Message266966
The origin of the ".0" parameter name is the compiler's implicit symbol definition - we use the "." prefix for those to ensure we don't accidentally collide with actual identifiers used in the code.
We can see that via dis.dis:
>>> def make_set():
... return {z*z for z in range(5)}
...
>>> import dis
>>> dis.dis(make_set)
2 0 LOAD_CONST 1 (<code object <setcomp> at 0x7f54c5b2cd20, file "<stdin>", line 2>)
3 LOAD_CONST 2 ('make_set.<locals>.<setcomp>')
6 MAKE_FUNCTION 0
9 LOAD_GLOBAL 0 (range)
12 LOAD_CONST 3 (5)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
18 GET_ITER
19 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
22 RETURN_VALUE
>>> dis.dis(make_set.__code__.co_consts[1])
2 0 BUILD_SET 0
3 LOAD_FAST 0 (.0)
>> 6 FOR_ITER 16 (to 25)
9 STORE_FAST 1 (z)
12 LOAD_FAST 1 (z)
15 LOAD_FAST 1 (z)
18 BINARY_MULTIPLY
19 SET_ADD 2
22 JUMP_ABSOLUTE 6
>> 25 RETURN_VALUE
It isn't just set comprehensions that will do this - it's all the implicit nested functions that accept a positional argument (list/dict/set comprehensions, generator expressions)
I chatted to Brett Cannon about it, and we agree inspect should handle the implicit functions generated by the compiler, even if those signatures can't be expressed in normal Python code. The fact those may be emitted by the affected inspect functions can then be documented as a CPython implementation detail, rather than as a language level behaviour. |
|
Date |
User |
Action |
Args |
2016-06-02 21:55:49 | ncoghlan | set | recipients:
+ ncoghlan, nedbat, r.david.murray, serhiy.storchaka, yselivanov, JelleZijlstra |
2016-06-02 21:55:49 | ncoghlan | set | messageid: <1464904549.67.0.428811279778.issue19611@psf.upfronthosting.co.za> |
2016-06-02 21:55:49 | ncoghlan | link | issue19611 messages |
2016-06-02 21:55:49 | ncoghlan | create | |
|