Skip to content

Commit 79ab8b8

Browse files
committed
use note
1 parent 27e9da3 commit 79ab8b8

File tree

4 files changed

+35
-19
lines changed

4 files changed

+35
-19
lines changed

mypy/checker.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,15 +2955,15 @@ def check_metaclass_compatibility(self, typ: TypeInfo) -> None:
29552955
if typ.metaclass_type is None and any(
29562956
base.type.metaclass_type is not None for base in typ.bases
29572957
):
2958-
explanation = typ.explain_metaclass_conflict() or ""
2959-
if explanation:
2960-
explanation = f" - {explanation}"
29612958
self.fail(
29622959
"Metaclass conflict: the metaclass of a derived class must be "
2963-
f"a (non-strict) subclass of the metaclasses of all its bases{explanation}",
2960+
"a (non-strict) subclass of the metaclasses of all its bases",
29642961
typ,
29652962
code=codes.METACLASS,
29662963
)
2964+
explanation = typ.explain_metaclass_conflict()
2965+
if explanation:
2966+
self.note(explanation, typ, code=codes.METACLASS)
29672967

29682968
def visit_import_from(self, node: ImportFrom) -> None:
29692969
for name, _ in node.names:

mypy/nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3434,7 +3434,7 @@ def explain_metaclass_conflict(self) -> str | None:
34343434
continue
34353435
# metaclass conflict
34363436
conflict = f"{super_meta.type.fullname} (metaclass of {super_class.fullname})"
3437-
return f"{' > '.join(resolution_steps)} conflicting with {conflict}"
3437+
return f"{' > '.join(resolution_steps)} conflicts with {conflict}"
34383438

34393439
return None
34403440

test-data/unit/check-classes.test

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4757,7 +4757,9 @@ class C(B):
47574757
class X(type): pass
47584758
class Y(type): pass
47594759
class A(metaclass=X): pass
4760-
class B(A, metaclass=Y): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.Y (meta of __main__.B) conflicting with __main__.X (metaclass of __main__.A)
4760+
class B(A, metaclass=Y): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
4761+
# N: __main__.Y (meta of __main__.B) conflicts with __main__.X (metaclass of __main__.A)
4762+
47614763

47624764
[case testMetaclassNoTypeReveal]
47634765
class M:
@@ -5737,8 +5739,8 @@ def f() -> type: return M
57375739
class C1(six.with_metaclass(M), object): pass # E: Unsupported dynamic base class "six.with_metaclass"
57385740
class C2(C1, six.with_metaclass(M)): pass # E: Unsupported dynamic base class "six.with_metaclass"
57395741
class C3(six.with_metaclass(A)): pass # E: Metaclasses not inheriting from "type" are not supported
5740-
@six.add_metaclass(A) # E: Metaclasses not inheriting from "type" are not supported \
5741-
# E: Argument 1 to "add_metaclass" has incompatible type "type[A]"; expected "type[type]"
5742+
@six.add_metaclass(A) # E: Metaclasses not inheriting from "type" are not supported \
5743+
# E: Argument 1 to "add_metaclass" has incompatible type "type[A]"; expected "type[type]"
57425744

57435745
class D3(A): pass
57445746
class C4(six.with_metaclass(M), metaclass=M): pass # E: Multiple metaclass definitions
@@ -5754,8 +5756,11 @@ class CD(six.with_metaclass(M)): pass # E: Multiple metaclass definitions
57545756
class M1(type): pass
57555757
class Q1(metaclass=M1): pass
57565758
@six.add_metaclass(M)
5757-
class CQA(Q1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.M (meta of __main__.CQA) conflicting with __main__.M1 (metaclass of __main__.Q1)
5758-
class CQW(six.with_metaclass(M, Q1)): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.M (meta of __main__.CQW) conflicting with __main__.M1 (metaclass of __main__.Q1)
5759+
class CQA(Q1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
5760+
# N: __main__.M (meta of __main__.CQA) conflicts with __main__.M1 (metaclass of __main__.Q1)
5761+
class CQW(six.with_metaclass(M, Q1)): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
5762+
# N: __main__.M (meta of __main__.CQW) conflicts with __main__.M1 (metaclass of __main__.Q1)
5763+
57595764
[builtins fixtures/tuple.pyi]
57605765

57615766
[case testSixMetaclassAny]
@@ -5873,7 +5878,9 @@ class C5(future.utils.with_metaclass(f())): pass # E: Dynamic metaclass not sup
58735878

58745879
class M1(type): pass
58755880
class Q1(metaclass=M1): pass
5876-
class CQW(future.utils.with_metaclass(M, Q1)): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.M (meta of __main__.CQW) conflicting with __main__.M1 (metaclass of __main__.Q1)
5881+
class CQW(future.utils.with_metaclass(M, Q1)): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
5882+
# N: __main__.M (meta of __main__.CQW) conflicts with __main__.M1 (metaclass of __main__.Q1)
5883+
58775884
[builtins fixtures/tuple.pyi]
58785885

58795886
[case testFutureMetaclassAny]
@@ -7342,17 +7349,22 @@ class ChildOfCorrectSubclass1(CorrectSubclass1): ...
73427349
class CorrectWithType1(C, A1): ...
73437350
class CorrectWithType2(B, C): ...
73447351

7345-
class Conflict1(A1, B, E): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.MyMeta1 (metaclass of __main__.A) conflicting with __main__.MyMeta2 (metaclass of __main__.B)
7346-
class Conflict2(A, B): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.MyMeta1 (metaclass of __main__.A) conflicting with __main__.MyMeta2 (metaclass of __main__.B)
7347-
class Conflict3(B, A): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.MyMeta2 (metaclass of __main__.B) conflicting with __main__.MyMeta1 (metaclass of __main__.A)
7352+
class Conflict1(A1, B, E): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
7353+
# N: __main__.MyMeta1 (metaclass of __main__.A) conflicts with __main__.MyMeta2 (metaclass of __main__.B)
7354+
class Conflict2(A, B): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
7355+
# N: __main__.MyMeta1 (metaclass of __main__.A) conflicts with __main__.MyMeta2 (metaclass of __main__.B)
7356+
class Conflict3(B, A): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
7357+
# N: __main__.MyMeta2 (metaclass of __main__.B) conflicts with __main__.MyMeta1 (metaclass of __main__.A)
73487358

73497359
class ChildOfConflict1(Conflict3): ...
73507360
class ChildOfConflict2(Conflict3, metaclass=CorrectMeta): ...
73517361

73527362
class ConflictingMeta(MyMeta1, MyMeta3): ...
7353-
class Conflict4(A1, B, E, metaclass=ConflictingMeta): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.ConflictingMeta (meta of __main__.Conflict4) conflicting with __main__.MyMeta2 (metaclass of __main__.B)
7363+
class Conflict4(A1, B, E, metaclass=ConflictingMeta): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
7364+
# N: __main__.ConflictingMeta (meta of __main__.Conflict4) conflicts with __main__.MyMeta2 (metaclass of __main__.B)
73547365

7355-
class ChildOfCorrectButWrongMeta(CorrectSubclass1, metaclass=ConflictingMeta): # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.ConflictingMeta (meta of __main__.ChildOfCorrectButWrongMeta) conflicting with __main__.CorrectMeta (metaclass of __main__.CorrectSubclass1)
7366+
class ChildOfCorrectButWrongMeta(CorrectSubclass1, metaclass=ConflictingMeta): # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
7367+
# N: __main__.ConflictingMeta (meta of __main__.ChildOfCorrectButWrongMeta) conflicts with __main__.CorrectMeta (metaclass of __main__.CorrectSubclass1)
73567368
...
73577369

73587370
[case testMetaClassConflictIssue14033]
@@ -7367,8 +7379,10 @@ class B1(metaclass=M2): pass
73677379

73687380
class C1(metaclass=Mx): pass
73697381

7370-
class TestABC(A2, B1, C1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.M1 (metaclass of __main__.A1) conflicting with __main__.M2 (metaclass of __main__.B1)
7371-
class TestBAC(B1, A2, C1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.M2 (metaclass of __main__.B1) conflicting with __main__.M1 (metaclass of __main__.A1)
7382+
class TestABC(A2, B1, C1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
7383+
# N: __main__.M1 (metaclass of __main__.A1) conflicts with __main__.M2 (metaclass of __main__.B1)
7384+
class TestBAC(B1, A2, C1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \
7385+
# N: __main__.M2 (metaclass of __main__.B1) conflicts with __main__.M1 (metaclass of __main__.A1)
73727386

73737387
# should not warn again for children
73747388
class ChildOfTestABC(TestABC): pass

test-data/unit/check-errorcodes.test

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,9 @@ class A3(six.with_metaclass(M1)): pass # E: Multiple metaclass definitions [me
12751275
class X(type): pass
12761276
class Y(type): pass
12771277
class A(metaclass=X): pass
1278-
class B(A, metaclass=Y): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases - __main__.Y (meta of __main__.B) conflicting with __main__.X (metaclass of __main__.A) [metaclass]
1278+
class B(A, metaclass=Y): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases [metaclass] \
1279+
# N: __main__.Y (meta of __main__.B) conflicts with __main__.X (metaclass of __main__.A)
1280+
12791281

12801282
[case testOverloadedFunctionSignature]
12811283
from typing import overload, Union

0 commit comments

Comments
 (0)