[Python-3000] PEP 3107 - Function Annotations
Tony Lownds
tony at pagedna.com
Sat Jan 6 20:05:51 CET 2007
On Jan 5, 2007, at 12:01 AM, Neal Norwitz wrote:
> On 12/28/06, Tony Lownds <tony at pagedna.com> wrote:
>>
>> > * With the modification of MAKE_FUNCTION to be a 32-bit value,
>> this
>> > means that EXTENDED_ARG is now used. This means that the peephole
>> > optimizer won't work for the outer function. I think we should
>> > correct this.
>>
>> Ok. Something like this should fix it in peephople.c. I can post a
>> patch.
>>
>> @@ -535,8 +535,13 @@
>> break;
>> case EXTENDED_ARG:
>> - goto exitUnchanged;
>> + if (codestr[i+3] != MAKE_FUNCTION)
>> + goto exitUnchanged;
>> + /* don't visit MAKE_FUNCTION as
>> GETARG will be wrong */
>> + i += 3;
>> + break;
>> +
>
> I'm not sure if it's not that simple or not. The problem is the jump
> fix up code. There are some assumptions that the code sizes are only
> 1 or 2. It's possible that this is a very limited circumstance that
> doesn't screw up any of the assumptions. IIRC there would be problems
> if a jump changed from 2 to 4 bytes (or vica versa). Since the size
> can't change for MAKE_FUNCTION, it may be ok in this limited case, but
> I'm not sure without reviewing the code in detail. (It probably is
> ok, but I'm not sure.)
>
The peephole code bails on code larger than 32767 . All of the peephole
optimizations make the code smaller. In practice that means EXTENDED_ARG
will not be encountered before jump opcodes. I believe the logic is
fine even if
EXTENDED_ARG did pop up on any other opcode.
> Hmm, what would happen if the nested function contained more than 256
> args? Might that mess up the annotation handling?
There is a limit for non-nested arguments, but apparently not for
nested arguments, and the handling does mess up:
>>> s = "def f((%s)): pass"
>>> s %= ', '.join('a%d' % i for i in xrange(70000))
>>> d = {}
>>> exec(s, d)
>>> s = "def f((%s)): pass"
>>> s %= ', '.join('a%d:%d' % (i,i) for i in xrange(70000))
>>> exec(s, d)
python: Python/ceval.c:2307: PyEval_EvalFrameEx: Assertion
`num_annotations == name_ix+1' failed.
Abort (core dumped)
compile.c happily compiled 70000 annotations; I think it should
complain (SyntaxError) at 2^16-1.
I'll post a patch.
Thanks
-Tony
More information about the Python-3000
mailing list