Skip to content

Extracting a function from walrus assignment with an internal walrus assignment produces invalid code #871

Description

@lieryan

Describe the bug

Walrus assignment can only assign to 1 assignment target, but the current implementation of extract function refactoring may potentially produce invalid code as the extracted code were attempting to assign the return value to multiple assignment target. There is a test case that was actually asserting for the invalid code, which will also need to be fixed:

@testutils.only_for_versions_higher("3.8")
def test_extract_function_expression_with_inline_assignment_complex(self):
code = dedent("""\
def foo(a):
if i := a == (c := 5):
i += 1
c += 1
print(i)
""")
extract_target = "i := a == (c := 5)"
start, end = code.index(extract_target), code.index(extract_target) + len(
extract_target
)
refactored = self.do_extract_method(code, start, end, "new_func")
expected = dedent("""\
def foo(a):
if i, c := new_func(a):
i += 1
c += 1
print(i)
def new_func(a):
return (i := a == (c := 5))
""")
self.assertEqual(expected, refactored)

To Reproduce
Steps to reproduce the behavior:

  1. Code before refactoring:
def foo(a): 
    if i := a == (c := 5): 
        i += 1 
        c += 1 
    print(i) 
  1. Describe the refactoring you want to do: Extract "i := a == (c := 5)"

  2. Expected code after refactoring, either produce something like:

def foo(a):
    if (i := new_func(a, c := 5)):
        i += 1
        c += 1
    print(i)

def new_func(a, c):
    return (i := a == c)

or maybe should just refuse the extraction.

  1. Describe the error or unexpected result that you are getting:
def foo(a): 
    if i, c := new_func(a): 
        i += 1 
        c += 1 
    print(i) 

def new_func(a): 
    return (i := a == (c := 5)) 

i, c := is not actually a valid assignment target for the walrus operator.

Editor information:

  • Rope version: 1.14.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugUnexpected or incorrect user-visible behaviorextract-refactor

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions