Skip to content

Commit

Permalink
Fix crash if a callable returning a context manager was assigned to a…
Browse files Browse the repository at this point in the history
… list or dict item (#4733)

* Fix crash if left hand side of assignment is neither ``astroid.AssignName`` nor ``astroid.AssignAttr``
* Add ChangeLog and whatsnew entry
  • Loading branch information
DudeNr33 committed Jul 21, 2021
1 parent 970c5d2 commit a2c166c
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 1 deletion.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Release date: TBA
..
Put bug fixes that should not wait for a new minor version here

* Fix crash if a callable returning a context manager was assigned to a list or dict item

Closes #4732


What's New in Pylint 2.9.4?
===========================
Expand Down
2 changes: 2 additions & 0 deletions doc/whatsnew/2.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,5 @@ Other Changes

* No longer emit ``consider-using-with`` for ``ThreadPoolExecutor`` and ``ProcessPoolExecutor``
as they have legitimate use cases without a ``with`` block.

* Fix crash if a callable returning a context manager was assigned to a list or dict item
6 changes: 5 additions & 1 deletion pylint/checkers/refactoring/refactoring_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,11 @@ def _append_context_managers_to_stack(self, node: astroid.Assign) -> None:
if not isinstance(value, astroid.Call):
continue
inferred = utils.safe_infer(value.func)
if not inferred or inferred.qname() not in CALLS_RETURNING_CONTEXT_MANAGERS:
if (
not inferred
or inferred.qname() not in CALLS_RETURNING_CONTEXT_MANAGERS
or not isinstance(assignee, (astroid.AssignName, astroid.AssignAttr))
):
continue
stack = self._consider_using_with_stack.get_stack_for_frame(node.frame())
varname = (
Expand Down
14 changes: 14 additions & 0 deletions tests/functional/c/consider/consider_using_with.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,17 @@ def my_nested_function():
)
with used_pool:
pass


def test_subscript_assignment():
"""
Regression test for issue https://github.com/PyCQA/pylint/issues/4732.
If a context manager is assigned to a list or dict, we are not able to
tell if / how the context manager is used later on, as it is not assigned
to a variable or attribute directly.
In this case we can only emit the message directly.
"""
job_list = [None, None]
job_list[0] = subprocess.Popen("ls") # [consider-using-with]
job_dict = {}
job_dict["myjob"] = subprocess.Popen("ls") # [consider-using-with]
2 changes: 2 additions & 0 deletions tests/functional/c/consider/consider_using_with.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ consider-using-with:201:4::Consider using 'with' for resource-allocating operati
consider-using-with:202:4::Consider using 'with' for resource-allocating operations:HIGH
consider-using-with:207:4::Consider using 'with' for resource-allocating operations:HIGH
consider-using-with:213:4::Consider using 'with' for resource-allocating operations:HIGH
consider-using-with:229:18:test_subscript_assignment:Consider using 'with' for resource-allocating operations:HIGH
consider-using-with:231:24:test_subscript_assignment:Consider using 'with' for resource-allocating operations:HIGH

0 comments on commit a2c166c

Please sign in to comment.