Skip to content

Commit

Permalink
Remove newstyle variable given old-style class support should be remo…
Browse files Browse the repository at this point in the history
…ved (#2561)
  • Loading branch information
akamat10 committed Sep 11, 2024
1 parent 523eeb4 commit b4ac0e2
Show file tree
Hide file tree
Showing 7 changed files with 13 additions and 113 deletions.
11 changes: 4 additions & 7 deletions astroid/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,10 @@ def _object_type(

for inferred in node.infer(context=context):
if isinstance(inferred, scoped_nodes.ClassDef):
if inferred.newstyle:
metaclass = inferred.metaclass(context=context)
if metaclass:
yield metaclass
continue
metaclass = inferred.metaclass(context=context)
if metaclass:
yield metaclass
continue
yield builtins.getattr("type")[0]
elif isinstance(
inferred,
Expand Down Expand Up @@ -194,8 +193,6 @@ def _type_check(type1, type2) -> bool:
if not all(map(has_known_bases, (type1, type2))):
raise _NonDeducibleTypeHierarchy

if not all([type1.newstyle, type2.newstyle]):
return False
try:
return type1 in type2.mro()[:-1]
except MroError as e:
Expand Down
10 changes: 0 additions & 10 deletions astroid/interpreter/objectmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,19 +514,13 @@ def attr___doc__(self):

@property
def attr___mro__(self):
if not self._instance.newstyle:
raise AttributeInferenceError(target=self._instance, attribute="__mro__")

mro = self._instance.mro()
obj = node_classes.Tuple(parent=self._instance)
obj.postinit(mro)
return obj

@property
def attr_mro(self):
if not self._instance.newstyle:
raise AttributeInferenceError(target=self._instance, attribute="mro")

other_self = self

# Cls.mro is a method and we need to return one in order to have a proper inference.
Expand Down Expand Up @@ -565,10 +559,6 @@ def attr___subclasses__(self):
This looks only in the current module for retrieving the subclasses,
thus it might miss a couple of them.
"""
if not self._instance.newstyle:
raise AttributeInferenceError(
target=self._instance, attribute="__subclasses__"
)

qname = self._instance.qname()
root = self._instance.root()
Expand Down
67 changes: 8 additions & 59 deletions astroid/nodes/scoped_nodes/scoped_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1882,8 +1882,7 @@ def my_meth(self, arg):
),
)
_other_fields = ("name", "is_dataclass", "position")
_other_other_fields = ("locals", "_newstyle")
_newstyle: bool | None = None
_other_other_fields = "locals"

def __init__(
self,
Expand Down Expand Up @@ -1983,36 +1982,11 @@ def postinit(
self.bases = bases
self.body = body
self.decorators = decorators
self._newstyle = newstyle
self._metaclass = metaclass
self.position = position
self.doc_node = doc_node
self.type_params = type_params or []

def _newstyle_impl(self, context: InferenceContext | None = None):
if context is None:
context = InferenceContext()
if self._newstyle is not None:
return self._newstyle
for base in self.ancestors(recurs=False, context=context):
if base._newstyle_impl(context):
self._newstyle = True
break
klass = self.declared_metaclass()
# could be any callable, we'd need to infer the result of klass(name,
# bases, dict). punt if it's not a class node.
if klass is not None and isinstance(klass, ClassDef):
self._newstyle = klass._newstyle_impl(context)
if self._newstyle is None:
self._newstyle = False
return self._newstyle

_newstyle = None
newstyle = property(
_newstyle_impl,
doc=("Whether this is a new style class or not\n\n" ":type: bool or None"),
)

@cached_property
def blockstart_tolineno(self):
"""The line on which the beginning of this block ends.
Expand All @@ -2033,14 +2007,12 @@ def block_range(self, lineno: int) -> tuple[int, int]:
"""
return self.fromlineno, self.tolineno

def pytype(self) -> Literal["builtins.type", "builtins.classobj"]:
def pytype(self) -> Literal["builtins.type"]:
"""Get the name of the type that this node represents.
:returns: The name of the type.
"""
if self.newstyle:
return "builtins.type"
return "builtins.classobj"
return "builtins.type"

def display_type(self) -> str:
"""A human readable type of this node.
Expand Down Expand Up @@ -2580,7 +2552,6 @@ def _valid_getattr(node):
try:
return _valid_getattr(self.getattr("__getattr__", context)[0])
except AttributeInferenceError:
# if self.newstyle: XXX cause an infinite recursion error
try:
getattribute = self.getattr("__getattribute__", context)[0]
return _valid_getattr(getattribute)
Expand Down Expand Up @@ -2667,16 +2638,12 @@ def mymethods(self):
def implicit_metaclass(self):
"""Get the implicit metaclass of the current class.
For newstyle classes, this will return an instance of builtins.type.
For oldstyle classes, it will simply return None, since there's
no implicit metaclass there.
This will return an instance of builtins.type.
:returns: The metaclass.
:rtype: builtins.type or None
:rtype: builtins.type
"""
if self.newstyle:
return builtin_lookup("type")[1][0]
return None
return builtin_lookup("type")[1][0]

def declared_metaclass(
self, context: InferenceContext | None = None
Expand Down Expand Up @@ -2799,10 +2766,6 @@ def _islots(self):
return None

def _slots(self):
if not self.newstyle:
raise NotImplementedError(
"The concept of slots is undefined for old-style classes."
)

slots = self._islots()
try:
Expand Down Expand Up @@ -2842,11 +2805,6 @@ def grouped_slots(
else:
yield None

if not self.newstyle:
raise NotImplementedError(
"The concept of slots is undefined for old-style classes."
)

try:
mro = self.mro()
except MroError as e:
Expand Down Expand Up @@ -2912,17 +2870,8 @@ def _compute_mro(self, context: InferenceContext | None = None):
if base is self:
continue

try:
mro = base._compute_mro(context=context)
bases_mro.append(mro)
except NotImplementedError:
# Some classes have in their ancestors both newstyle and
# old style classes. For these we can't retrieve the .mro,
# although in Python it's possible, since the class we are
# currently working is in fact new style.
# So, we fallback to ancestors here.
ancestors = list(base.ancestors(context=context))
bases_mro.append(ancestors)
mro = base._compute_mro(context=context)
bases_mro.append(mro)

unmerged_mro: list[list[ClassDef]] = [[self], *bases_mro, inferred_bases]
unmerged_mro = clean_duplicates_mro(unmerged_mro, self, context)
Expand Down
3 changes: 0 additions & 3 deletions astroid/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,6 @@ def super_mro(self):
super_=self,
)

if not mro_type.newstyle:
raise SuperError("Unable to call super on old-style classes.", super_=self)

mro = mro_type.mro()
if self.mro_pointer not in mro:
raise SuperError(
Expand Down
31 changes: 0 additions & 31 deletions tests/test_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,36 +519,6 @@ def test_object(self) -> None:
obj_ast = self.builder.inspect_build(object)
self.assertIn("__setattr__", obj_ast)

def test_newstyle_detection(self) -> None:
data = """
class A:
"old style"
class B(A):
"old style"
class C(object):
"new style"
class D(C):
"new style"
__metaclass__ = type
class E(A):
"old style"
class F:
"new style"
"""
mod_ast = builder.parse(data, __name__)
self.assertTrue(mod_ast["A"].newstyle)
self.assertTrue(mod_ast["B"].newstyle)
self.assertTrue(mod_ast["E"].newstyle)
self.assertTrue(mod_ast["C"].newstyle)
self.assertTrue(mod_ast["D"].newstyle)
self.assertTrue(mod_ast["F"].newstyle)

def test_globals(self) -> None:
data = """
CSTE = 1
Expand Down Expand Up @@ -833,7 +803,6 @@ def test_class_base_props(self) -> None:
self.assertEqual(klass.parent.frame(), module)
self.assertEqual(klass.root(), module)
self.assertEqual(klass.basenames, [])
self.assertTrue(klass.newstyle)

def test_class_locals(self) -> None:
"""Test the 'locals' dictionary of an astroid class."""
Expand Down
1 change: 0 additions & 1 deletion tests/test_python3.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ class SubTest(Test): pass
)
)
klass = astroid["SubTest"]
self.assertTrue(klass.newstyle)
metaclass = klass.metaclass()
self.assertIsInstance(metaclass, nodes.ClassDef)
self.assertEqual(metaclass.name, "ABCMeta")
Expand Down
3 changes: 1 addition & 2 deletions tests/test_scoped_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1002,8 +1002,7 @@ def test_cls_special_attributes_1(self) -> None:
self.assertIsInstance(cls.getattr("__module__")[0], nodes.Const)
self.assertEqual(cls.getattr("__module__")[0].value, "data.module")
self.assertEqual(len(cls.getattr("__dict__")), 1)
if not cls.newstyle:
self.assertRaises(AttributeInferenceError, cls.getattr, "__mro__")

for cls in (nodes.List._proxied, nodes.Const(1)._proxied):
self.assertEqual(len(cls.getattr("__bases__")), 1)
self.assertEqual(len(cls.getattr("__name__")), 1)
Expand Down

0 comments on commit b4ac0e2

Please sign in to comment.