summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTushar Sadhwani <86737547+tushar-deepsource@users.noreply.github.com>2021-12-29 20:53:33 +0530
committerGitHub <noreply@github.com>2021-12-29 16:23:33 +0100
commitaa4f5bed58dc6521a6c2c0927ca0e0da48fd5ea5 (patch)
treed9dbc2d0834d6209346ea2ee0736fbfab1336c83
parent7afd696520f70a46334adea6d39f7150379198f3 (diff)
downloadastroid-git-aa4f5bed58dc6521a6c2c0927ca0e0da48fd5ea5.tar.gz
Add future=True to frame calls (#1305)
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com> Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
-rw-r--r--astroid/arguments.py2
-rw-r--r--astroid/bases.py4
-rw-r--r--astroid/builder.py4
-rw-r--r--astroid/helpers.py2
-rw-r--r--astroid/nodes/node_classes.py6
-rw-r--r--astroid/nodes/scoped_nodes/scoped_nodes.py26
-rw-r--r--astroid/protocols.py2
-rw-r--r--tests/unittest_builder.py5
-rw-r--r--tests/unittest_inference.py2
-rw-r--r--tests/unittest_manager.py4
-rw-r--r--tests/unittest_nodes.py10
-rw-r--r--tests/unittest_scoped_nodes.py9
12 files changed, 54 insertions, 22 deletions
diff --git a/astroid/arguments.py b/astroid/arguments.py
index fadb5a8b..9ae8bab2 100644
--- a/astroid/arguments.py
+++ b/astroid/arguments.py
@@ -226,7 +226,7 @@ class CallSite:
return positional[0].infer(context=context)
if boundnode is None:
# XXX can do better ?
- boundnode = funcnode.parent.frame()
+ boundnode = funcnode.parent.frame(future=True)
if isinstance(boundnode, nodes.ClassDef):
# Verify that we're accessing a method
diff --git a/astroid/bases.py b/astroid/bases.py
index c39e887a..9fbdc3a3 100644
--- a/astroid/bases.py
+++ b/astroid/bases.py
@@ -368,7 +368,7 @@ class UnboundMethod(Proxy):
special_attributes = lazy_descriptor(lambda: objectmodel.UnboundMethodModel())
def __repr__(self):
- frame = self._proxied.parent.frame()
+ frame = self._proxied.parent.frame(future=True)
return "<{} {} of {} at 0x{}".format(
self.__class__.__name__, self._proxied.name, frame.qname(), id(self)
)
@@ -404,7 +404,7 @@ class UnboundMethod(Proxy):
# instance of the class given as first argument.
if (
self._proxied.name == "__new__"
- and self._proxied.parent.frame().qname() == "builtins.object"
+ and self._proxied.parent.frame(future=True).qname() == "builtins.object"
):
if caller.args:
node_context = context.extra_context.get(caller.args[0])
diff --git a/astroid/builder.py b/astroid/builder.py
index ea9d7dc8..150eeed8 100644
--- a/astroid/builder.py
+++ b/astroid/builder.py
@@ -234,7 +234,7 @@ class AstroidBuilder(raw_building.InspectBuilder):
This adds name to locals and handle members definition.
"""
try:
- frame = node.frame()
+ frame = node.frame(future=True)
for inferred in node.expr.infer():
if inferred is util.Uninferable:
continue
@@ -263,7 +263,7 @@ class AstroidBuilder(raw_building.InspectBuilder):
if (
frame.name == "__init__"
and values
- and values[0].frame().name != "__init__"
+ and values[0].frame(future=True).name != "__init__"
):
values.insert(0, node)
else:
diff --git a/astroid/helpers.py b/astroid/helpers.py
index eadd8cb6..6e74558b 100644
--- a/astroid/helpers.py
+++ b/astroid/helpers.py
@@ -255,7 +255,7 @@ def object_len(node, context=None):
# prevent self referential length calls from causing a recursion error
# see https://github.com/PyCQA/astroid/issues/777
- node_frame = node.frame()
+ node_frame = node.frame(future=True)
if (
isinstance(node_frame, scoped_nodes.FunctionDef)
and node_frame.name == "__len__"
diff --git a/astroid/nodes/node_classes.py b/astroid/nodes/node_classes.py
index 4e33bb5d..0f196812 100644
--- a/astroid/nodes/node_classes.py
+++ b/astroid/nodes/node_classes.py
@@ -4815,9 +4815,9 @@ class NamedExpr(mixins.AssignTypeMixin, NodeNG):
raise ParentMissingError(target=self.parent)
if not self.parent.parent.parent:
raise ParentMissingError(target=self.parent.parent)
- return self.parent.parent.parent.frame()
+ return self.parent.parent.parent.frame(future=True)
- return self.parent.frame()
+ return self.parent.frame(future=True)
def scope(self) -> "LocalsDictNodeNG":
"""The first parent node defining a new scope.
@@ -4849,7 +4849,7 @@ class NamedExpr(mixins.AssignTypeMixin, NodeNG):
:param stmt: The statement that defines the given name.
"""
- self.frame().set_local(name, stmt)
+ self.frame(future=True).set_local(name, stmt)
class Unknown(mixins.AssignTypeMixin, NodeNG):
diff --git a/astroid/nodes/scoped_nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes/scoped_nodes.py
index f2720c4c..15e9c1c9 100644
--- a/astroid/nodes/scoped_nodes/scoped_nodes.py
+++ b/astroid/nodes/scoped_nodes/scoped_nodes.py
@@ -244,7 +244,7 @@ class LocalsDictNodeNG(node_classes.LookupMixIn, node_classes.NodeNG):
# pylint: disable=no-member; github.com/pycqa/astroid/issues/278
if self.parent is None:
return self.name
- return f"{self.parent.frame().qname()}.{self.name}"
+ return f"{self.parent.frame(future=True).qname()}.{self.name}"
def scope(self: T) -> T:
"""The first parent node defining a new scope.
@@ -1452,7 +1452,7 @@ class Lambda(mixins.FilterStmtsMixin, LocalsDictNodeNG):
:rtype: tuple(str, list(NodeNG))
"""
if node in self.args.defaults or node in self.args.kw_defaults:
- frame = self.parent.frame()
+ frame = self.parent.frame(future=True)
# line offset to avoid that def func(f=func) resolve the default
# value to the defined function
offset = -1
@@ -1595,7 +1595,7 @@ class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda):
parent=parent,
)
if parent:
- frame = parent.frame()
+ frame = parent.frame(future=True)
frame.set_local(name, self)
# pylint: disable=arguments-differ; different than Lambdas
@@ -1641,7 +1641,7 @@ class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda):
:type: list(NodeNG)
"""
- frame = self.parent.frame()
+ frame = self.parent.frame(future=True)
if not isinstance(frame, ClassDef):
return []
@@ -1668,7 +1668,7 @@ class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda):
# original method.
if (
isinstance(meth, FunctionDef)
- and assign_node.frame() == frame
+ and assign_node.frame(future=True) == frame
):
decorators.append(assign.value)
return decorators
@@ -1687,7 +1687,7 @@ class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda):
if decorator.func.name in BUILTIN_DESCRIPTORS:
return decorator.func.name
- frame = self.parent.frame()
+ frame = self.parent.frame(future=True)
type_name = "function"
if isinstance(frame, ClassDef):
if self.name == "__new__":
@@ -1815,7 +1815,9 @@ class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda):
"""
# check we are defined in a ClassDef, because this is usually expected
# (e.g. pylint...) when is_method() return True
- return self.type != "function" and isinstance(self.parent.frame(), ClassDef)
+ return self.type != "function" and isinstance(
+ self.parent.frame(future=True), ClassDef
+ )
@decorators_mod.cached
def decoratornames(self, context=None):
@@ -1999,7 +2001,7 @@ class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda):
# if any methods in a class body refer to either __class__ or super.
# In our case, we want to be able to look it up in the current scope
# when `__class__` is being used.
- frame = self.parent.frame()
+ frame = self.parent.frame(future=True)
if isinstance(frame, ClassDef):
return self, [frame]
return super().scope_lookup(node, name, offset)
@@ -2124,12 +2126,12 @@ def get_wrapping_class(node):
:rtype: ClassDef or None
"""
- klass = node.frame()
+ klass = node.frame(future=True)
while klass is not None and not isinstance(klass, ClassDef):
if klass.parent is None:
klass = None
else:
- klass = klass.parent.frame()
+ klass = klass.parent.frame(future=True)
return klass
@@ -2260,7 +2262,7 @@ class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, node_classes.Statement
parent=parent,
)
if parent is not None:
- parent.frame().set_local(name, self)
+ parent.frame(future=True).set_local(name, self)
for local_name, node in self.implicit_locals():
self.add_local_node(node, local_name)
@@ -2517,7 +2519,7 @@ class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, node_classes.Statement
# class A(name.Name):
# def name(self): ...
- frame = self.parent.frame()
+ frame = self.parent.frame(future=True)
# line offset to avoid that class A(A) resolve the ancestor to
# the defined class
offset = -1
diff --git a/astroid/protocols.py b/astroid/protocols.py
index 58b60834..ef7f5c96 100644
--- a/astroid/protocols.py
+++ b/astroid/protocols.py
@@ -411,7 +411,7 @@ def arguments_assigned_stmts(
if (
context.callcontext
and node
- and getattr(callee, "name", None) == node.frame().name
+ and getattr(callee, "name", None) == node.frame(future=True).name
):
# reset call context/name
callcontext = context.callcontext
diff --git a/tests/unittest_builder.py b/tests/unittest_builder.py
index 7dffbb72..c1aa3bd4 100644
--- a/tests/unittest_builder.py
+++ b/tests/unittest_builder.py
@@ -609,6 +609,7 @@ class FileBuildTest(unittest.TestCase):
self.assertEqual(module.fromlineno, 0)
self.assertIsNone(module.parent)
self.assertEqual(module.frame(), module)
+ self.assertEqual(module.frame(future=True), module)
self.assertEqual(module.root(), module)
self.assertEqual(module.file, os.path.abspath(resources.find("data/module.py")))
self.assertEqual(module.pure_python, 1)
@@ -651,6 +652,8 @@ class FileBuildTest(unittest.TestCase):
self.assertTrue(function.parent)
self.assertEqual(function.frame(), function)
self.assertEqual(function.parent.frame(), module)
+ self.assertEqual(function.frame(future=True), function)
+ self.assertEqual(function.parent.frame(future=True), module)
self.assertEqual(function.root(), module)
self.assertEqual([n.name for n in function.args.args], ["key", "val"])
self.assertEqual(function.type, "function")
@@ -672,6 +675,8 @@ class FileBuildTest(unittest.TestCase):
self.assertTrue(klass.parent)
self.assertEqual(klass.frame(), klass)
self.assertEqual(klass.parent.frame(), module)
+ self.assertEqual(klass.frame(future=True), klass)
+ self.assertEqual(klass.parent.frame(future=True), module)
self.assertEqual(klass.root(), module)
self.assertEqual(klass.basenames, [])
self.assertTrue(klass.newstyle)
diff --git a/tests/unittest_inference.py b/tests/unittest_inference.py
index 89e9d59d..8a53899b 100644
--- a/tests/unittest_inference.py
+++ b/tests/unittest_inference.py
@@ -337,6 +337,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase):
self.assertIsInstance(meth1, UnboundMethod)
self.assertEqual(meth1.name, "meth1")
self.assertEqual(meth1.parent.frame().name, "C")
+ self.assertEqual(meth1.parent.frame(future=True).name, "C")
self.assertRaises(StopIteration, partial(next, inferred))
def test_bound_method_inference(self) -> None:
@@ -345,6 +346,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase):
self.assertIsInstance(meth1, BoundMethod)
self.assertEqual(meth1.name, "meth1")
self.assertEqual(meth1.parent.frame().name, "C")
+ self.assertEqual(meth1.parent.frame(future=True).name, "C")
self.assertRaises(StopIteration, partial(next, inferred))
def test_args_default_inference1(self) -> None:
diff --git a/tests/unittest_manager.py b/tests/unittest_manager.py
index f2feea17..69a91d87 100644
--- a/tests/unittest_manager.py
+++ b/tests/unittest_manager.py
@@ -280,10 +280,12 @@ class AstroidManagerTest(
ast = self.manager.ast_from_class(int)
self.assertEqual(ast.name, "int")
self.assertEqual(ast.parent.frame().name, "builtins")
+ self.assertEqual(ast.parent.frame(future=True).name, "builtins")
ast = self.manager.ast_from_class(object)
self.assertEqual(ast.name, "object")
self.assertEqual(ast.parent.frame().name, "builtins")
+ self.assertEqual(ast.parent.frame(future=True).name, "builtins")
self.assertIn("__setattr__", ast)
def test_ast_from_class_with_module(self) -> None:
@@ -291,10 +293,12 @@ class AstroidManagerTest(
ast = self.manager.ast_from_class(int, int.__module__)
self.assertEqual(ast.name, "int")
self.assertEqual(ast.parent.frame().name, "builtins")
+ self.assertEqual(ast.parent.frame(future=True).name, "builtins")
ast = self.manager.ast_from_class(object, object.__module__)
self.assertEqual(ast.name, "object")
self.assertEqual(ast.parent.frame().name, "builtins")
+ self.assertEqual(ast.parent.frame(future=True).name, "builtins")
self.assertIn("__setattr__", ast)
def test_ast_from_class_attr_error(self) -> None:
diff --git a/tests/unittest_nodes.py b/tests/unittest_nodes.py
index aab8c5a1..48f767c7 100644
--- a/tests/unittest_nodes.py
+++ b/tests/unittest_nodes.py
@@ -741,25 +741,35 @@ class TestNamedExprNode:
)
function = module.body[0]
assert function.args.frame() == function
+ assert function.args.frame(future=True) == function
function_two = module.body[1]
assert function_two.args.args[0].frame() == function_two
+ assert function_two.args.args[0].frame(future=True) == function_two
assert function_two.args.args[1].frame() == function_two
+ assert function_two.args.args[1].frame(future=True) == function_two
assert function_two.args.defaults[0].frame() == module
+ assert function_two.args.defaults[0].frame(future=True) == module
inherited_class = module.body[3]
assert inherited_class.keywords[0].frame() == inherited_class
+ assert inherited_class.keywords[0].frame(future=True) == inherited_class
assert inherited_class.keywords[0].value.frame() == module
+ assert inherited_class.keywords[0].value.frame(future=True) == module
lambda_assignment = module.body[4].value
assert lambda_assignment.args.args[0].frame() == lambda_assignment
+ assert lambda_assignment.args.args[0].frame(future=True) == lambda_assignment
assert lambda_assignment.args.defaults[0].frame() == module
+ assert lambda_assignment.args.defaults[0].frame(future=True) == module
lambda_named_expr = module.body[5].args.defaults[0]
assert lambda_named_expr.value.args.defaults[0].frame() == module
+ assert lambda_named_expr.value.args.defaults[0].frame(future=True) == module
comprehension = module.body[6].value
assert comprehension.generators[0].ifs[0].frame() == module
+ assert comprehension.generators[0].ifs[0].frame(future=True) == module
@staticmethod
def test_scope() -> None:
diff --git a/tests/unittest_scoped_nodes.py b/tests/unittest_scoped_nodes.py
index 0aa3e5d7..33e1002d 100644
--- a/tests/unittest_scoped_nodes.py
+++ b/tests/unittest_scoped_nodes.py
@@ -2315,17 +2315,24 @@ class TestFrameNodes:
)
function = module.body[0]
assert function.frame() == function
+ assert function.frame(future=True) == function
assert function.body[0].frame() == function
+ assert function.body[0].frame(future=True) == function
class_node = module.body[1]
assert class_node.frame() == class_node
+ assert class_node.frame(future=True) == class_node
assert class_node.body[0].frame() == class_node
+ assert class_node.body[0].frame(future=True) == class_node
assert class_node.body[1].frame() == class_node.body[1]
+ assert class_node.body[1].frame(future=True) == class_node.body[1]
lambda_assignment = module.body[2].value
assert lambda_assignment.args.args[0].frame() == lambda_assignment
+ assert lambda_assignment.args.args[0].frame(future=True) == lambda_assignment
assert module.frame() == module
+ assert module.frame(future=True) == module
@staticmethod
def test_non_frame_node():
@@ -2338,8 +2345,10 @@ class TestFrameNodes:
"""
)
assert module.body[0].frame() == module
+ assert module.body[0].frame(future=True) == module
assert module.body[1].value.locals["x"][0].frame() == module
+ assert module.body[1].value.locals["x"][0].frame(future=True) == module
if __name__ == "__main__":