codetransformer
codetransformer copied to clipboard
New TypeError in Python 3.8
The example code from the README works correctly under Python 3.7 but gives a TypeError under Python 3.8.0. Any pointers for how to fix this?
from codetransformer import CodeTransformer, instructions, pattern
class FoldNames(CodeTransformer):
@pattern(
instructions.LOAD_GLOBAL,
instructions.LOAD_GLOBAL,
instructions.BINARY_ADD,
)
def _load_fast(self, a, b, add):
yield instructions.LOAD_FAST(a.arg + b.arg).steal(a)
@FoldNames()
def f():
ab = 3
return a + b
f()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-319624ac894a> in <module>
11
12 @FoldNames()
---> 13 def f():
14 ab = 3
15 return a + b
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/codetransformer/core.py in __call__(self, f, globals_, name, defaults, closure)
213
214 return FunctionType(
--> 215 self.transform(Code.from_pycode(f.__code__)).to_pycode(),
216 _a_if_not_none(globals_, f.__globals__),
217 _a_if_not_none(name, f.__name__),
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/codetransformer/code.py in to_pycode(self)
582 bc.append(0)
583
--> 584 return CodeType(
585 self.argcount,
586 self.kwonlyargcount,
TypeError: an integer is required (got type bytes)
The issue is that in Python 3.8 the constructor for CodeType changed to support the positional only argument count and you cannot pass arguments by keyword. This broke any code that directly called CodeType constructor, including codetransformer's use. The way to fix this is to conditionally define the args tuple based on the version of Python being used. Codetransformer had a small wrapper around CodeType to allow keyword arguments to be passed, so that is the only place that should need to be updated. I haven't had time to play with Python 3.8, but would you like to try to contribute a fix for this?