Georg Brandl wrote:
Nick Coghlan schrieb:

2. Method lookup MAY bypass __getattribute__, shadowing the attribute in the instance dictionary MAY have ill effects. (slots such as __enter__ and __exit__ that are looked up via normal attribute lookup in CPython will fit into this category)

I would argue that the __enter__ and __exit__ behavior should be changed too.
The reason for the current behavior is this:

  2           0 LOAD_GLOBAL              0 (a)
              3 DUP_TOP
              4 LOAD_ATTR                1 (__exit__)
              7 STORE_FAST               0 (_[1])
             10 LOAD_ATTR                2 (__enter__)
             13 CALL_FUNCTION            0
             16 STORE_FAST               1 (_[2])
             19 SETUP_FINALLY           18 (to 40)

IOW, when "with" is compiled, the attributes are retrieved using bytecode.
It wouldn't be hard to have a WITH_SETUP opcode (along with the already
existing WITH_CLEANUP) that would make the bytecode read like:

  2           0 LOAD_GLOBAL              0 (a)
              3 WITH_SETUP               0 (_[1])
              6 STORE_FAST               1 (_[2])
              9 SETUP_FINALLY           18 (to 40)

No argument here - the PEP 343 implementation is the way it is mainly because it involved the least messing around with the performance-sensitive ceval loop.

That said, the with statement implementation is already a bit different in 2.6/3.0 (it moves things around on the stack so it can avoid the STORE_FAST/LOAD_FAST/DELETE_FAST operations):

def f():
  with a:
    pass

Python 2.5 disassembly:
 2           0 LOAD_GLOBAL              0 (a)
              3 DUP_TOP
              4 LOAD_ATTR                1 (__exit__)
              7 STORE_FAST               0 (_[1])
             10 LOAD_ATTR                2 (__enter__)
             13 CALL_FUNCTION            0
             16 POP_TOP
             17 SETUP_FINALLY            4 (to 24)
             20 POP_BLOCK
             21 LOAD_CONST               0 (None)
        >>   24 LOAD_FAST                0 (_[1])
             27 DELETE_FAST              0 (_[1])
             30 WITH_CLEANUP
             31 END_FINALLY

Python 2.6 disassembly:
  2           0 LOAD_GLOBAL              0 (a)
              3 DUP_TOP
              4 LOAD_ATTR                1 (__exit__)
              7 ROT_TWO
              8 LOAD_ATTR                2 (__enter__)
             11 CALL_FUNCTION            0
             14 POP_TOP
             15 SETUP_FINALLY            4 (to 22)
             18 POP_BLOCK
             19 LOAD_CONST               0 (None)
        >>   22 WITH_CLEANUP
             23 END_FINALLY

Cheers,
Nick.

--
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---------------------------------------------------------------
            http://www.boredomandlaziness.org
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to