The recipe in question is here
http://code.activestate.com/recipes/578353-code-to-source-and-back.
I've called it c2sab in the test code below.
The problem is that the class name gets dropped during the round trip,
but only if a list, dict or set comprehension or a generator expression
is involved, and only from the code.co_consts tuple. Hopefully the code
and output that follows makes sense.
<code>
import c2sab
import inspect
class Comps():
def listcomp(self):
self.lc = [x for x in range(10)]
def genexpr(self):
self.ge = (x for x in range(10))
def dictcomp(self):
self.dc = {x: x**2 for x in range(10)}
def setcomp(self):
self.sc = {x for x in range(10)}
methods = inspect.getmembers(Comps, inspect.isfunction)
for _, method in methods:
print('Processing', method.__name__)
code = method.__code__
recode = c2sab.recompile(*c2sab.uncompile(code))
for offset, co_consts in enumerate(zip(code.co_consts,
recode.co_consts)):
old = co_consts[0]
new = co_consts[1]
if old != new:
print('offset {} code |{}| not equal to recode
|{}|'.format(offset, old, new))
print()
</code>
<output>
Processing dictcomp
offset 2 code |Comps.dictcomp.<locals>.<dictcomp>| not equal to recode
|dictcomp.<locals>.<dictcomp>|
Processing genexpr
offset 2 code |Comps.genexpr.<locals>.<genexpr>| not equal to recode
|genexpr.<locals>.<genexpr>|
Processing listcomp
offset 2 code |Comps.listcomp.<locals>.<listcomp>| not equal to recode
|listcomp.<locals>.<listcomp>|
Processing setcomp
offset 2 code |Comps.setcomp.<locals>.<setcomp>| not equal to recode
|setcomp.<locals>.<setcomp>|
</output>
I can reproduce the above on 3.3 to 3.6 inclusive on Windows 10. This
has no impact on 3.2 or lower as the field in question is new in
co_consts for 3.3.
So is my analysis correct? If yes I'll be reporting a bug although I've
no idea what against, if no what have I overlooked?
--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.
Mark Lawrence
--
https://mail.python.org/mailman/listinfo/python-list