Skip to content

Commit 2e19181

Browse files
elazarggvanrossum
authored andcommitted
Remove support for @builtinclass (#2294)
Following #599. (As a followup, we should remove it from typeshed too.)
1 parent 6fbe68c commit 2e19181

11 files changed

+9
-83
lines changed

mypy/checker.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
from mypy.visitor import NodeVisitor
5151
from mypy.join import join_types
5252
from mypy.treetransform import TransformVisitor
53-
from mypy.meet import meet_simple, nearest_builtin_ancestor, is_overlapping_types
53+
from mypy.meet import meet_simple, is_overlapping_types
5454
from mypy.binder import ConditionalTypeBinder
5555
from mypy.options import Options
5656

@@ -959,7 +959,6 @@ def visit_class_def(self, defn: ClassDef) -> Type:
959959

960960
def check_multiple_inheritance(self, typ: TypeInfo) -> None:
961961
"""Check for multiple inheritance related errors."""
962-
963962
if len(typ.bases) <= 1:
964963
# No multiple inheritance.
965964
return
@@ -973,13 +972,6 @@ def check_multiple_inheritance(self, typ: TypeInfo) -> None:
973972
# checks suffice (these are implemented elsewhere).
974973
if name in base2.names and base2 not in base.mro:
975974
self.check_compatibility(name, base, base2, typ)
976-
# Verify that base class layouts are compatible.
977-
builtin_bases = [nearest_builtin_ancestor(base.type)
978-
for base in typ.bases]
979-
for base1 in builtin_bases:
980-
for base2 in builtin_bases:
981-
if not (base1 in base2.mro or base2 in base1.mro):
982-
self.fail(messages.INSTANCE_LAYOUT_CONFLICT, typ)
983975

984976
def check_compatibility(self, name: str, base1: TypeInfo,
985977
base2: TypeInfo, ctx: Context) -> None:

mypy/meet.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import cast, List
1+
from typing import List
22

33
from mypy.join import is_similar_callables, combine_similar_callables
44
from mypy.types import (
@@ -7,7 +7,6 @@
77
DeletedType, UninhabitedType, TypeType
88
)
99
from mypy.subtypes import is_subtype
10-
from mypy.nodes import TypeInfo
1110

1211
from mypy import experiments
1312

@@ -114,14 +113,6 @@ class C(A, B): ...
114113
return True
115114

116115

117-
def nearest_builtin_ancestor(type: TypeInfo) -> TypeInfo:
118-
for base in type.mro:
119-
if base.defn.is_builtinclass:
120-
return base
121-
else:
122-
return None
123-
124-
125116
class TypeMeetVisitor(TypeVisitor[Type]):
126117
def __init__(self, s: Type) -> None:
127118
self.s = s

mypy/messages.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
'Overloaded method has both abstract and non-abstract variants'
7777
READ_ONLY_PROPERTY_OVERRIDES_READ_WRITE = \
7878
'Read-only property cannot override read-write property'
79-
INSTANCE_LAYOUT_CONFLICT = 'Instance layout conflict in multiple inheritance'
8079
FORMAT_REQUIRES_MAPPING = 'Format requires a mapping'
8180
GENERIC_TYPE_NOT_VALID_AS_EXPRESSION = \
8281
"Generic type is prohibited as a runtime expression (use a type alias or '# type:' comment)"

mypy/nodes.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,6 @@ class ClassDef(Statement):
694694
info = None # type: TypeInfo # Related TypeInfo
695695
metaclass = ''
696696
decorators = None # type: List[Expression]
697-
# Built-in/extension class? (single implementation inheritance only)
698-
is_builtinclass = False
699697
has_incompatible_baseclass = False
700698

701699
def __init__(self,
@@ -724,7 +722,6 @@ def serialize(self) -> JsonDict:
724722
'fullname': self.fullname,
725723
'type_vars': [v.serialize() for v in self.type_vars],
726724
'metaclass': self.metaclass,
727-
'is_builtinclass': self.is_builtinclass,
728725
}
729726

730727
@classmethod
@@ -736,7 +733,6 @@ def deserialize(self, data: JsonDict) -> 'ClassDef':
736733
metaclass=data['metaclass'],
737734
)
738735
res.fullname = data['fullname']
739-
res.is_builtinclass = data['is_builtinclass']
740736
return res
741737

742738

mypy/semanal.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,6 @@ def visit_class_def(self, defn: ClassDef) -> None:
559559

560560
self.enter_class(defn)
561561

562-
self.setup_is_builtinclass(defn)
563-
564562
# Analyze class body.
565563
defn.defs.accept(self)
566564

@@ -606,15 +604,6 @@ def unbind_class_type_vars(self) -> None:
606604
def analyze_class_decorator(self, defn: ClassDef, decorator: Expression) -> None:
607605
decorator.accept(self)
608606

609-
def setup_is_builtinclass(self, defn: ClassDef) -> None:
610-
for decorator in defn.decorators:
611-
if refers_to_fullname(decorator, 'typing.builtinclass'):
612-
defn.is_builtinclass = True
613-
if defn.fullname == 'builtins.object':
614-
# Only 'object' is marked as a built-in class, as otherwise things elsewhere
615-
# would break. We need a better way of dealing with built-in classes.
616-
defn.is_builtinclass = True
617-
618607
def calculate_abstract_status(self, typ: TypeInfo) -> None:
619608
"""Calculate abstract status of a class.
620609

mypy/strconv.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ def visit_class_def(self, o: 'mypy.nodes.ClassDef') -> str:
141141
a.insert(1, 'Metaclass({})'.format(o.metaclass))
142142
if o.decorators:
143143
a.insert(1, ('Decorators', o.decorators))
144-
if o.is_builtinclass:
145-
a.insert(1, 'Builtinclass')
146144
if o.info and o.info._promote:
147145
a.insert(1, 'Promote({})'.format(o.info._promote))
148146
if o.info and o.info.tuple_type:

mypy/treetransform.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ def visit_class_def(self, node: ClassDef) -> ClassDef:
190190
new.info = node.info
191191
new.decorators = [self.expr(decorator)
192192
for decorator in node.decorators]
193-
new.is_builtinclass = node.is_builtinclass
194193
return new
195194

196195
def visit_global_decl(self, node: GlobalDecl) -> GlobalDecl:

test-data/unit/check-classes.test

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -894,26 +894,6 @@ a.f = a.f # E: Property "f" defined in "A" is read-only
894894
a.f.x # E: "int" has no attribute "x"
895895
[builtins fixtures/property.pyi]
896896

897-
898-
-- Multiple inheritance, non-object built-in class as base
899-
-- -------------------------------------------------------
900-
901-
902-
[case testInvalidMultipleInheritanceFromBuiltins-skip]
903-
import typing
904-
class A(int, str): pass # E: Instance layout conflict in multiple inheritance
905-
[out]
906-
main: note: In class "A":
907-
908-
[case testInvalidMultipleInheritanceFromBuiltins-skip]
909-
import typing
910-
class S(str): pass
911-
class A(S, str): pass
912-
class B(S, int): pass # E: Instance layout conflict in multiple inheritance
913-
[out]
914-
main: note: In class "B":
915-
916-
917897
-- _promote decorators
918898
-- -------------------
919899

test-data/unit/check-overloading.test

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,10 @@ A() + B()
411411
A() + '' # E: No overload variant of "__add__" of "A" matches argument types [builtins.str]
412412

413413
[case testOverrideOverloadedMethodWithMoreGeneralArgumentTypes]
414-
from typing import overload, builtinclass
415-
@builtinclass
414+
from typing import overload
415+
416416
class IntSub(int): pass
417-
@builtinclass
417+
418418
class StrSub(str): pass
419419
class A:
420420
@overload
@@ -429,10 +429,10 @@ class B(A):
429429
[out]
430430

431431
[case testOverrideOverloadedMethodWithMoreSpecificArgumentTypes]
432-
from typing import overload, builtinclass
433-
@builtinclass
432+
from typing import overload
433+
434434
class IntSub(int): pass
435-
@builtinclass
435+
436436
class StrSub(str): pass
437437
class A:
438438
@overload
@@ -461,12 +461,10 @@ main: note: In class "C":
461461
main:17: error: Signature of "f" incompatible with supertype "A"
462462

463463
[case testOverloadingAndDucktypeCompatibility]
464-
from typing import overload, _promote, builtinclass
464+
from typing import overload, _promote
465465

466-
@builtinclass
467466
class A: pass
468467

469-
@builtinclass
470468
@_promote(A)
471469
class B: pass
472470

test-data/unit/semanal-classes.test

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -518,20 +518,6 @@ MypyFile:1(
518518
NameExpr(object [builtins.object]))
519519
PassStmt:3()))
520520

521-
[case testBuiltinclassDecorator]
522-
from typing import builtinclass
523-
@builtinclass
524-
class A: pass
525-
[out]
526-
MypyFile:1(
527-
ImportFrom:1(typing, [builtinclass])
528-
ClassDef:2(
529-
A
530-
Builtinclass
531-
Decorators(
532-
NameExpr(builtinclass [typing.builtinclass]))
533-
PassStmt:3()))
534-
535521
[case testClassAttributeAsMethodDefaultArgumentValue]
536522
import typing
537523
class A:

test-data/unit/typexport-basic.test

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@ import typing
136136
8 > 3
137137
4 < 6 > 2
138138
[file builtins.py]
139-
from typing import builtinclass
140-
@builtinclass
141139
class object:
142140
def __init__(self) -> None: pass
143141
class int:

0 commit comments

Comments
 (0)