jedi icon indicating copy to clipboard operation
jedi copied to clipboard

renaming a variable inside a comprehension goes wrong

Open dimbleby opened this issue 3 years ago • 1 comments

eg start with

foo = [x for x in [1,2,3] if x < 3]

and try to rename x as y. Get

foo = [y for y in [1,2,3] if x < 3]

where you can see that the final x survives.

Here's the same example expressed as a testcase, which currently fails (eg if I put it in test_refactoring.py):

  def test_rename_in_comprehension(Script, dir_with_content):
      script = Script(
          'foo = [x for x in [1,2,3] if x < 3]\n',
          path=dir_with_content.joinpath('some_script.py'),
          project=jedi.Project(dir_with_content),
      )
      refactoring = script.rename(line=1, column=7, new_name='y')
      assert refactoring.get_diff() == dedent('''\
          --- some_script.py
          +++ some_script.py
          @@ -1,2 +1,2 @@
          -foo = [x for x in [1,2,3] if x < 3]
          +foo = [y for y in [1,2,3] if y < 3]
          ''')

dimbleby avatar Mar 30 '21 23:03 dimbleby

Thanks for the report. Since you asked how you could potentially fix that:

The issue is that goto doesn't work on the x in the if clause. Once that works, renaming should probably work. This is probably an issue with the context. The context gets created in jedi.inference.context.TreeContextMixin.create_context and there should probably be a special case for the comp_if node and we should also somehow end up with a CompForContext. The sync_comp_for is probably currently it's context, which means that the if part has no access to the variables defined in that context, I guess.

davidhalter avatar Mar 13 '23 23:03 davidhalter