Skip to content

Commit

Permalink
Make igetattr() idempotent
Browse files Browse the repository at this point in the history
This addresses some reports of varying results when running pylint with ``--jobs. The original inconsistency
was due to a performance optimization in 2d7a87b, but
we have no source for the original bug report it targeted.
  • Loading branch information
jacobtylerwalls committed Jun 9, 2023
1 parent 4493399 commit df30870
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Release date: TBA

* Reduce file system access in ``ast_from_file()``.

* Make ``igetattr()`` idempotent. This addresses some reports of varying results
when running pylint with ``--jobs``.

Closes pylint-dev/pylint#4356
Refs #7

* Fix incorrect cache keys for inference results, thereby correctly inferring types
for calls instantiating types dynamically.

Expand Down
8 changes: 0 additions & 8 deletions astroid/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,14 +277,6 @@ def igetattr(
context = InferenceContext()
try:
context.lookupname = name
# avoid recursively inferring the same attr on the same class
if context.push(self._proxied):
raise InferenceError(
message="Cannot infer the same attribute again",
node=self,
context=context,
)

# XXX frame should be self._proxied, or not ?
get_attr = self.getattr(name, context, lookupclass=False)
yield from _infer_stmts(
Expand Down
16 changes: 15 additions & 1 deletion tests/test_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -4024,7 +4024,7 @@ def __getitem__(self, name):
flow['app']['config']['doffing'] = AttributeDict() #@
"""
)
self.assertIsNone(helpers.safe_infer(ast_node.targets[0]))
self.assertIsInstance(helpers.safe_infer(ast_node.targets[0]), Instance)

def test_classmethod_inferred_by_context(self) -> None:
ast_node = extract_node(
Expand Down Expand Up @@ -6120,6 +6120,20 @@ def __exit__(self, ex_type, ex_value, ex_tb):
next(node.infer())


def test_igetattr_idempotent() -> None:
code = """
class InferMeTwice:
item = 10
InferMeTwice()
"""
call = extract_node(code)
instance = call.inferred()[0]
context_to_be_used_twice = InferenceContext()
assert util.Uninferable not in instance.igetattr("item", context_to_be_used_twice)
assert util.Uninferable not in instance.igetattr("item", context_to_be_used_twice)


def test_infer_context_manager_with_unknown_args() -> None:
code = """
class client_log(object):
Expand Down

0 comments on commit df30870

Please sign in to comment.