Skip to content

Commit

Permalink
Reverse the order of decorators for infer_subscript
Browse files Browse the repository at this point in the history
`path_wrapper` needs to come first, followed by `raise_if_nothing_inferred`,
otherwise we won't handle `StopIteration` correctly.

Close #762
  • Loading branch information
PCManticore committed Mar 5, 2020
1 parent 01b5b57 commit 0a8a75d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ Release Date: TBA

Close PyCQA/pylint#3209

* Reverse the order of decorators for `infer_subscript`

`path_wrapper` needs to come first, followed by `raise_if_nothing_inferred`,
otherwise we won't handle `StopIteration` correctly.

Close #762

* Numpy `datetime64.astype` return value is inferred as a `ndarray`.

Close PyCQA/pylint#3332
Expand Down
7 changes: 4 additions & 3 deletions astroid/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,6 @@ def infer_global(self, context=None):
_SUBSCRIPT_SENTINEL = object()


@decorators.raise_if_nothing_inferred
def infer_subscript(self, context=None):
"""Inference for subscripts
Expand Down Expand Up @@ -407,8 +406,10 @@ def infer_subscript(self, context=None):
return None


nodes.Subscript._infer = decorators.path_wrapper(infer_subscript)
nodes.Subscript.infer_lhs = infer_subscript
nodes.Subscript._infer = decorators.raise_if_nothing_inferred(
decorators.path_wrapper(infer_subscript)
)
nodes.Subscript.infer_lhs = decorators.raise_if_nothing_inferred(infer_subscript)


@decorators.raise_if_nothing_inferred
Expand Down
21 changes: 21 additions & 0 deletions tests/unittest_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -5646,5 +5646,26 @@ def test_custom_decorators_for_classmethod_and_staticmethods(code, obj, obj_type
assert inferred.type == obj_type


@pytest.mark.skipif(sys.version_info < (3, 8), reason="Needs dataclasses available")
def test_dataclasses_subscript_inference_recursion_error():
code = """
from dataclasses import dataclass, replace
@dataclass
class ProxyConfig:
auth: str = "/auth"
a = ProxyConfig("")
test_dict = {"proxy" : {"auth" : "", "bla" : "f"}}
foo = test_dict['proxy']
replace(a, **test_dict['proxy']) # This fails
"""
node = extract_node(code)
# Reproduces only with safe_infer()
assert helpers.safe_infer(node) is None


if __name__ == "__main__":
unittest.main()

0 comments on commit 0a8a75d

Please sign in to comment.