diff --git a/mypy/test/testdeps.py b/mypy/test/testdeps.py index 84c5ec2f66c93..99464469524fe 100644 --- a/mypy/test/testdeps.py +++ b/mypy/test/testdeps.py @@ -50,13 +50,18 @@ def run_case(self, testcase: DataDrivenTestCase) -> None: else: deps = defaultdict(set) # type: DefaultDict[str, Set[str]] for module in files: - if module in dumped_modules or dump_all and module not in ('abc', 'typing', - 'mypy_extensions'): + if module in dumped_modules or dump_all and module not in ('abc', + 'typing', + 'mypy_extensions', + 'enum'): new_deps = get_dependencies(files[module], type_map, python_version) for source in new_deps: deps[source].update(new_deps[source]) for source, targets in sorted(deps.items()): + if source.startswith(' List[str]: return a def dump_typeinfo(self, info: TypeInfo) -> List[str]: + if info.fullname() == 'enum.Enum': + # Avoid noise + return [] s = info.dump(str_conv=self.str_conv, type_str_conv=self.type_str_conv) return s.splitlines() diff --git a/test-data/unit/deps-classes.test b/test-data/unit/deps-classes.test index 9e3aaaff6aebc..64c31ae36c0e3 100644 --- a/test-data/unit/deps-classes.test +++ b/test-data/unit/deps-classes.test @@ -147,3 +147,25 @@ def foo() -> None: -> m, m.C, m.D -> m.foo -> m.D, m.foo + +[case testClassBasedEnum] +from enum import Enum +from m import B + +class A(Enum): + X = B() + +def f(a: A) -> None: + pass +def g() -> None: + A.X +[file m.py] +class B: pass +[out] + -> m.g +-- The __init__ is superfluous but benign + -> m.g + -> , m.A, m.f, m.g + -> m +-- The dependecy target is superfluous but benign + -> , m diff --git a/test-data/unit/diff.test b/test-data/unit/diff.test index b97310f8097bb..7b9b542fde75e 100644 --- a/test-data/unit/diff.test +++ b/test-data/unit/diff.test @@ -563,6 +563,48 @@ B = Enum('B', 'y') __main__.B.x __main__.B.y +[case testClassBasedEnum] +from enum import Enum +class A(Enum): + X = 0 + Y = 1 +class B(Enum): + X = 0 + Y = 1 +class C(Enum): + X = 0 + Y = 1 +class D(Enum): + X = 0 + Y = 1 +class E(Enum): + X = 0 +[file next.py] +from enum import Enum +class A(Enum): + X = 0 + Y = 1 +class B(Enum): + X = 0 + Z = 1 +class C(Enum): + X = 0 + Y = 1 + Z = 2 +class D(Enum): + X = 'a' + Y = 'b' +class F(Enum): + X = 0 +[out] +__main__.B.Y +__main__.B.Z +__main__.C.Z +__main__.D.X +__main__.D.Y +__main__.E +__main__.F + [case testTypedDict] from mypy_extensions import TypedDict Point = TypedDict('Point', {'x': int, 'y': int}) diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index d75b6083a319e..a4ee06efa38d5 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -2716,3 +2716,101 @@ class User: [builtins fixtures/ops.pyi] [out] == + +[case testRefreshClassBasedEnum] +import aa +[file aa.py] +import a +[file a.py] +from enum import Enum +import b +b.x +class C(Enum): + X = 0 +[file b.py] +x = 0 +[file b.py.2] +x = '' +[file aa.py.3] +from a import C +c: C +c = C.X +c = 1 +[out] +== +== +aa.py:4: error: Incompatible types in assignment (expression has type "int", variable has type "C") + +[case testRefreshClassBasedIntEnum] +import aa +[file aa.py] +import a +[file a.py] +from enum import IntEnum +import b +b.x +class C(IntEnum): + X = 0 +x: int +x = C.X +[file b.py] +x = 0 +[file b.py.2] +x = '' +[file aa.py.3] +from a import C +c: C +c = C.X +c = 1 +n: int +n = C.X +n = c +[out] +== +== +aa.py:4: error: Incompatible types in assignment (expression has type "int", variable has type "C") + +[case testClassBasedEnumPropagation1] +import a +[file a.py] +from b import C + +def f(x: C) -> None: pass +f(C.X) +f(C.Y) +[file b.py] +from enum import Enum + +class C(Enum): + X = 0 + Y = 1 +[file b.py.2] +from enum import Enum + +class C(Enum): + X = 0 +[out] +== +a.py:5: error: "Type[C]" has no attribute "Y" + +[case testClassBasedEnumPropagation2] +import a +[file a.py] +from b import C + +def f(x: int) -> None: pass +f(C.X) +f(C.Y) +[file b.py] +class C: + X = 0 + Y = 1 +[file b.py.2] +from enum import Enum +class C(Enum): + X = 0 + Y = 1 +[out] +== +a.py:4: error: Argument 1 to "f" has incompatible type "C"; expected "int" +a.py:5: error: Argument 1 to "f" has incompatible type "C"; expected "int" diff --git a/test-data/unit/merge.test b/test-data/unit/merge.test index 492f86d6b99ef..de9869e76a1d7 100644 --- a/test-data/unit/merge.test +++ b/test-data/unit/merge.test @@ -1422,3 +1422,30 @@ target: Thing: TypeInfo<1> cast: Var<2> thing: Var<3>(target.Thing<1>) + +[case testClassBasedEnum_typeinfo] +import target +[file target.py] +from enum import Enum +class A(Enum): + X = 0 +[file target.py.next] +from enum import Enum +class A(Enum): + X = 0 + Y = 1 +[out] +TypeInfo<0>( + Name(target.A) + Bases(enum.Enum<1>) + Mro(target.A<0>, enum.Enum<1>, builtins.object<2>) + Names( + X<3> (builtins.int<4>))) +==> +TypeInfo<0>( + Name(target.A) + Bases(enum.Enum<1>) + Mro(target.A<0>, enum.Enum<1>, builtins.object<2>) + Names( + X<3> (builtins.int<4>) + Y<5> (builtins.int<4>)))