This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author nedbat
Recipients nedbat
Date 2013-11-15.12:03:02
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1384516983.26.0.0584971052865.issue19611@psf.upfronthosting.co.za>
In-reply-to
Content
In 2.7, set comprehensions are compiled to code objects expecting an argument named ".0".  This convention is also used for the unnamed arguments needed by tuple arguments.  inspect.getcallargs understands the tuple argument case, but not the set comprehension case, and throws errors for correct arguments.

This is also true for generator expressions and dictionary comprehensions.

Demonstration:

#-----
import inspect
import sys
import types

def make_set():
    return {z*z for z in range(5)}

print(make_set())

# The set comprehension is turned into a code object expecting a single
# argument called ".0" with should be an iterator over range(5).
if sys.version_info < (3,):
    setcomp_code = make_set.func_code.co_consts[1]
else:
    setcomp_code = make_set.__code__.co_consts[1]
setcomp_func = types.FunctionType(setcomp_code, {})

# We can successfully call the function with the argument it expects.
print(setcomp_func(iter(range(5))))

# But inspect can't figure that out, because the ".0" argument also means
# tuple arguments, which this code object doesn't expect.
print(inspect.getcallargs(setcomp_func, iter(range(5))))

#-----



When run on Python 3.3, this produces:

    {0, 1, 4, 16, 9} 
    {0, 1, 4, 16, 9}
    {'.0': <range_iterator object at 0x10834be70>}

When run on Python 2.7, it produces:

    set([0, 1, 4, 16, 9])
    set([0, 1, 4, 16, 9])
    Traceback (most recent call last):
      File "foo.py", line 17, in <module>
        print(inspect.getcallargs(setcomp_func, iter(range(5))))
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 935, in getcallargs
        assign(arg, value)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 922, in assign
        raise ValueError('too many values to unpack')
    ValueError: too many values to unpack
History
Date User Action Args
2013-11-15 12:03:03nedbatsetrecipients: + nedbat
2013-11-15 12:03:03nedbatsetmessageid: <1384516983.26.0.0584971052865.issue19611@psf.upfronthosting.co.za>
2013-11-15 12:03:03nedbatlinkissue19611 messages
2013-11-15 12:03:02nedbatcreate