@@ -4899,6 +4899,116 @@ class F(six.with_metaclass(t.M)): pass
4899
4899
@six.add_metaclass(t.M)
4900
4900
class G: pass
4901
4901
4902
+ -- Special support for future.utils
4903
+ -- --------------------------------
4904
+
4905
+ [case testFutureMetaclass]
4906
+ import future.utils
4907
+ class M(type):
4908
+ x = 5
4909
+ class A(future.utils.with_metaclass(M)): pass
4910
+ reveal_type(type(A).x) # N: Revealed type is 'builtins.int'
4911
+
4912
+ [case testFutureMetaclass_python2]
4913
+ import future.utils
4914
+ class M(type):
4915
+ x = 5
4916
+ class A(future.utils.with_metaclass(M)): pass
4917
+ reveal_type(type(A).x) # N: Revealed type is 'builtins.int'
4918
+
4919
+ [case testFromFutureMetaclass]
4920
+ from future.utils import with_metaclass
4921
+ class M(type):
4922
+ x = 5
4923
+ class A(with_metaclass(M)): pass
4924
+ reveal_type(type(A).x) # N: Revealed type is 'builtins.int'
4925
+
4926
+ [case testFutureMetaclassImportFrom]
4927
+ import future.utils
4928
+ from metadefs import M
4929
+ class A(future.utils.with_metaclass(M)): pass
4930
+ reveal_type(type(A).x) # N: Revealed type is 'builtins.int'
4931
+ [file metadefs.py]
4932
+ class M(type):
4933
+ x = 5
4934
+
4935
+ [case testFutureMetaclassImport]
4936
+ import future.utils
4937
+ import metadefs
4938
+ class A(future.utils.with_metaclass(metadefs.M)): pass
4939
+ reveal_type(type(A).x) # N: Revealed type is 'builtins.int'
4940
+ [file metadefs.py]
4941
+ class M(type):
4942
+ x = 5
4943
+
4944
+ [case testFutureMetaclassAndBase]
4945
+ from typing import Iterable, Iterator
4946
+ import future.utils
4947
+ class M(type, Iterable[int]):
4948
+ x = 5
4949
+ def __iter__(self) -> Iterator[int]: ...
4950
+ class A:
4951
+ def foo(self): pass
4952
+ class B:
4953
+ def bar(self): pass
4954
+ class C1(future.utils.with_metaclass(M, A)): pass
4955
+ class C2(future.utils.with_metaclass(M, A, B)): pass
4956
+ reveal_type(type(C1).x) # N: Revealed type is 'builtins.int'
4957
+ reveal_type(type(C2).x) # N: Revealed type is 'builtins.int'
4958
+ C1().foo()
4959
+ C1().bar() # E: "C1" has no attribute "bar"
4960
+ for x in C1: reveal_type(x) # N: Revealed type is 'builtins.int*'
4961
+ for x in C2: reveal_type(x) # N: Revealed type is 'builtins.int*'
4962
+ C2().foo()
4963
+ C2().bar()
4964
+ C2().baz() # E: "C2" has no attribute "baz"
4965
+
4966
+ [case testFutureMetaclassGenerics]
4967
+ from typing import Generic, GenericMeta, TypeVar
4968
+ import future.utils
4969
+ class DestroyableMeta(type):
4970
+ pass
4971
+ class Destroyable(future.utils.with_metaclass(DestroyableMeta)):
4972
+ pass
4973
+ T_co = TypeVar('T_co', bound='Destroyable', covariant=True)
4974
+ class ArcMeta(GenericMeta, DestroyableMeta):
4975
+ pass
4976
+ class Arc(future.utils.with_metaclass(ArcMeta, Generic[T_co], Destroyable)):
4977
+ pass
4978
+ class MyDestr(Destroyable):
4979
+ pass
4980
+ reveal_type(Arc[MyDestr]()) # N: Revealed type is '__main__.Arc[__main__.MyDestr*]'
4981
+ [builtins fixtures/bool.pyi]
4982
+ [typing fixtures/typing-full.pyi]
4983
+
4984
+ [case testFutureMetaclassErrors]
4985
+ import future.utils
4986
+ class M(type): pass
4987
+ class A(object): pass
4988
+ def f() -> type: return M
4989
+ class C1(future.utils.with_metaclass(M), object): pass # E: Unsupported dynamic base class "future.utils.with_metaclass"
4990
+ class C2(C1, future.utils.with_metaclass(M)): pass # E: Unsupported dynamic base class "future.utils.with_metaclass"
4991
+ class C3(future.utils.with_metaclass(A)): pass # E: Metaclasses not inheriting from 'type' are not supported
4992
+ class C4(future.utils.with_metaclass(M), metaclass=M): pass # E: Multiple metaclass definitions
4993
+ class C5(future.utils.with_metaclass(f())): pass # E: Dynamic metaclass not supported for 'C5'
4994
+
4995
+ class M1(type): pass
4996
+ class Q1(metaclass=M1): pass
4997
+ class CQW(future.utils.with_metaclass(M, Q1)): pass # E: Inconsistent metaclass structure for 'CQW'
4998
+
4999
+ [case testFutureMetaclassErrors_python2]
5000
+ # flags: --python-version 2.7
5001
+ import future.utils
5002
+ class M(type): pass
5003
+ class C4(future.utils.with_metaclass(M)): # E: Multiple metaclass definitions
5004
+ __metaclass__ = M
5005
+
5006
+ [case testFutureMetaclassAny]
5007
+ import t # type: ignore
5008
+ import future.utils
5009
+ class E(metaclass=t.M): pass
5010
+ class F(future.utils.with_metaclass(t.M)): pass
5011
+
4902
5012
-- Misc
4903
5013
-- ----
4904
5014
0 commit comments