[Python-3000] optional argument annotations

Tony Lownds tony at pagedna.com
Fri Nov 24 19:00:48 CET 2006


>>>>> f.func_annotations
>> {'x': 1}
>
> Very cool! I agree that Phillip's idea for simplification is worth a
> try. We're generally not too concerned over the cost of function
> declarations since they typically execute only once per program. As
> long as it's really cheap when no annotations are present (which would
> suggest that func_annotations should be None in that case since an
> empty dict is kind of expensive, at least in memory).
>
>

func_annotations could create the empty dict just in time.

Building the annotations dict in bytecode actually takes slightly  
more C code
and quite a bit more bytecode. Maybe using dict(zip(<tuple from  
co_consts>, <values from stack>)) would
be more efficient. I'll probably keep both the MAKE_FUNCTION change  
and the bytecode version for a while.

The next step is changing the syntax for nested parameters, eg

def f((x:1, y:2))

 >>> dis.dis(compile("def f(x:1, y:2=3, z=4)->5:pass", "<str>", "exec"))
   1           0 LOAD_CONST               0 (3)
               3 LOAD_CONST               1 (4)
               6 LOAD_CONST               2 (<code object f at  
0xb7ec70b0, file "<str>", line 1>)
               9 MAKE_FUNCTION            2
              12 DUP_TOP
              13 BUILD_MAP                0
              16 DUP_TOP
              17 LOAD_CONST               3 (1)
              20 ROT_TWO
              21 LOAD_CONST               4 ('x')
              24 STORE_SUBSCR
              25 DUP_TOP
              26 LOAD_CONST               5 (2)
              29 ROT_TWO
              30 LOAD_CONST               6 ('y')
              33 STORE_SUBSCR
              34 ROT_TWO
              35 STORE_ATTR               0 (func_annotations)
              38 DUP_TOP
              39 LOAD_CONST               7 (5)
              42 ROT_TWO
              43 STORE_ATTR               1 (func_returns)
              46 STORE_NAME               2 (f)
              49 LOAD_CONST               8 (None)
              52 RETURN_VALUE

>>> dis.dis(compile("def f(x:1, y:2=3, z=4)->5:pass", "<str>", "exec"))
>>>
    1           0 LOAD_CONST               0 (3)         # default for y
                3 LOAD_CONST               1 (4)          # default  
for z
                6 LOAD_CONST               2 (1)          # annotation
for x
                9 LOAD_CONST               3 (2)          # annotation
for y
               12 LOAD_CONST               4 (6)         # bitmask for
annotations... 0b110
               15 LOAD_CONST               5 (5)         # func_returns
               18 LOAD_CONST               6 (<code object f at
0xb7f08848, file "<str>", line 1>)
               21 MAKE_FUNCTION        49154      # numdefaults(2) +
kwdefaults(0) << 8 + has_annotations(1) << 14 + has_returns(1) << 15
               24 STORE_NAME               0 (f)
               27 LOAD_CONST               7 (None)
               30 RETURN_VALUE





More information about the Python-3000 mailing list