Skip to content

UP028 false positive when a target variable is global or nonlocal #16445

@dscorbett

Description

@dscorbett

Summary

The fix for yield-in-for-loop (UP028) is incorrect when the for loop’s target list includes a global or nonlocal variable. Rewriting the loop with yield from means the variable isn’t updated. This is similar to #15725. The fix is already marked unsafe, but because in this context it is so likely to break the program, no fix should be provided.

$ cat >up028.py <<'# EOF'
CURRENT_ELEMENT = None
def f(iterable):
    global CURRENT_ELEMENT
    for CURRENT_ELEMENT in iterable:
        yield CURRENT_ELEMENT
list(f("xyz"))
print(CURRENT_ELEMENT)
# EOF

$ python up028.py
z

$ ruff --isolated check --select UP028 up028.py --unsafe-fixes --fix
Found 1 error (1 fixed, 0 remaining).

$ cat up028.py
CURRENT_ELEMENT = None
def f(iterable):
    global CURRENT_ELEMENT
    yield from iterable
list(f("xyz"))
print(CURRENT_ELEMENT)

$ python up028.py
None

Version

ruff 0.9.9 (091d0af 2025-02-28)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions