IronLanguages / ironpython2

Implementation of the Python programming language for .NET Framework; built on top of the Dynamic Language Runtime (DLR).
http://ironpython.net
Apache License 2.0
1.08k stars 229 forks source link

Nested generator expressions can't access parent scope in set and dict comprehensions (unlike cPython 2.7) #819

Open JamesParrott opened 2 years ago

JamesParrott commented 2 years ago

Hi there, I have searched, but apologies if this is a known bug. (I know I can and should just code this as "if key in chars" but this is just an MRE. I wanted to be able to use any with a more useful iterable of functions to check much more general conditions than equality):

keys = 'abc'
chars = 'bcd'
print( {key for key in keys if any(key==x for x in chars)})
>py27 filtered_set_comp.py
set(['c', 'b'])

>ipy filtered_set_comp.py
NameError: global name 'key' is not defined

List comprehensions don't have this issue, as in Python 2 they leak all their variables into their parent scope anyway. Set and dict comprehensions don't leak variables out into their local scope. A work around is coercing a generator expression to the desired type:

set(key for key in d if any(key==x for x in chars))

dict((key, v) for (key, v) in d.items() if any(key==x for x in chars))

dict_and_set_comprehensions_iron_python_2_sub_scope_bug.zip

slozier commented 2 years ago

Thanks for the report! May be related to https://github.com/IronLanguages/ironpython3/issues/817 (which was fixed in IronPython 3).