[Python-ideas] If branch merging

Chris Angelico rosuav at gmail.com
Wed Jun 10 17:06:26 CEST 2015


On Wed, Jun 10, 2015 at 4:17 PM, Chris Angelico <rosuav at gmail.com> wrote:
>> But I think your quick&dirty hack may be worth playing with even if it bans this possibility and a few others, and may not be that hard to do if you make that decision, so if I were you I'd try that first.
>>
>
> Okay. I'll start poking around with CPython and see what I can do.

Here's a gross, disgusting, brutal hack. It applies only to try/except
(but can easily be expanded to other places; it's just a matter of
calling one function at top and bottom), and it currently assumes that
you're in a function scope (not at top level, not directly in a class;
methods are supported).

(Should I create a tracker issue? It's not even at proof-of-concept at
this point.)

Here's how it works: As an 'except' block is entered (at compilation
stage), a new subscope is defined. At the end of the except block,
after the "e = None; del e" opcodes get added in, the subscope is
popped off and disposed of. So long as there is a subscope attached to
the current compilation unit, any name lookups will be redirected
through it. Finally, when co_varnames is populated, names get
de-mangled, thus (possibly) making duplicates in the tuple, but more
importantly, getting tracebacks and such looking correct.

The subscope is a tiny thing that just says "this name now becomes
that mangled name", where the mangled name is the original name dot
something (eg mangle "e" and get back "e.0x12345678"); they're stored
in a linked list in the current compiler_unit.

Currently, locals() basically ignores the magic. If there is no
"regular" name to be shadowed, then it correctly picks up the interior
one; if there are both forms, I've no idea how it picks which one to
put into the dictionary, but it certainly can't logically retain both.
The fact that it manages to not crash and burn is, in my opinion, pure
luck :)

Can compiler_nameop() depend on all names being interned? I have a
full-on PyObject_RichCompareBool() to check for name equality; if
they're all interned, I could simply do a pointer comparison instead.

Next plan: Change compiler_comprehension_generator() to use subscopes
rather than a full nested function, and then do performance testing.
Currently, this can only have slowed things down. Removing the
function call overhead from list comps could give that speed back.

ChrisA
-------------- next part --------------
A non-text attachment was scrubbed...
Name: scope_hack.patch
Type: text/x-patch
Size: 5783 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150611/2a2dbd4a/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nesting_demo.py
Type: text/x-python
Size: 813 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150611/2a2dbd4a/attachment.py>


More information about the Python-ideas mailing list