[Python-Dev] Anonymous + varargs: possible serious breakage -- please confirm!

Ka-Ping Yee ping@lfw.org
Wed, 24 Jan 2001 12:33:43 -0800 (PST)


Hi -- after updating my CVS tree today with Python 2.1a1, i ran
the tests and test_inspect failed.  This revealed that the format
of code.co_varnames has changed.  At first i tried to update the
inspect.py module to check the Python version number and track the
change, but now i believe this is actually symptomatic of a real
interpreter problem.

Consider the function:

    def f(a, (b, c), *d):
        x = 1
        print a, b, c, d, x

Whereas in Python 1.5.2:

    f.func_code.co_argcount = 2
    f.func_code.co_nlocals = 6
    f.func_code.co_names = ('x', 'a', 'b', 'c', 'd')
    f.func_code.co_varnames = ('a', '.2', 'd', 'b', 'c', 'x')

In Python 2.1a1:

    f.func_code.co_argcount = 2
    f.func_code.co_nlocals = 6
    f.func_code.co_names = ('b', 'c', 'x', 'a', 'd')
    f.func_code.co_varnames = ('a', '.2', 'b', 'c', 'd', 'x')

Notice how the ordering of the variable names has changed.
I went and looked at the CO_VARARGS clause in eval_code2 to
see if it put the varargs and kwdict arguments in different
slots, but it appears unchanged!  It still puts varargs at
locals[co_argcount] and kwdict at locals[co_argcount + 1].

Please try:

    >>> def f(a, (b, c), *d):
    ...     x = 1
    ...     print a, b, c, d, x
    ...
    >>> f(1, (2, 3), 4)
    1 2 3
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 3, in f
    UnboundLocalError: local variable 'd' referenced before assignment
    >>> 

In Python 1.5.2, this prints "1 2 3 (4,)" as expected.

I only have 1.5.2 and 2.1a1 to test.  I hope this problem
isn't present in 2.0...


Note that test_inspect was the only test to fail!  It might be the
only test that checks anonymous and *varargs at the same time.
(Yet another reason to put inspect in the core...)

I did recently check in additions to test_extcall that made the
test much beefier -- but that only tested combinations of regular,
keyword, varargs, and kwdict arguments; it neglected to test
anonymous (tuple) arguments as well.


-- ?!ng