decorator icon indicating copy to clipboard operation
decorator copied to clipboard

`FunctionMaker.create()` fails when given a function definition with a return type annotation.

Open amitaiirron opened this issue 3 years ago • 1 comments

I think I may have found an issue with FunctionMaker.create(). When you try to pass a string containing a return type annotation, it breaks this function. Consider this example:

from decorator import FunctionMaker

def add(a: int, b: int) -> int:
    return a + b

add2 = FunctionMaker.create("add2(a: int, b: int)", "return add(a, b)", evaldict={"add": add}) # No problem
assert add2(6, 8) == add(6, 8) # add2 does the same as add

add3 = FunctionMaker.create("add3(a: int, b: int) -> int", "return add(a, b)", evaldict={"add": add}) # ERROR

I get a message like this:

  File "/nfs/iil/proj/dt/prv08/airon/git/socb_client/venv/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3457, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)

  File "<ipython-input-9-5d5ad6515055>", line 9, in <module>
    add3 = FunctionMaker.create("add3(a: int, b: int) -> int", "return add(a, b)", evaldict={"add": add})

  File "/nfs/iil/proj/dt/prv08/airon/git/socb_client/venv/lib/python3.9/site-packages/decorator.py", line 222, in create
    return self.make(body, evaldict, addsource, **attrs)

  File "/nfs/iil/proj/dt/prv08/airon/git/socb_client/venv/lib/python3.9/site-packages/decorator.py", line 184, in make
    code = compile(src, filename, 'single')

  File "<decorator-gen-123>", line 1
    def add3(a: int, b: int) -> in):
                                ^
SyntaxError: invalid syntax

It seems like the code that decomposes the signature at https://github.com/micheles/decorator/blob/9cf8151de8fd26551cb43288b2010965ad346839/src/decorator.py#L181

assumes the end of the signature is always a right parenthesis, which is not the case when we specify a return type annotation.

Then, the code at https://github.com/micheles/decorator/blob/9cf8151de8fd26551cb43288b2010965ad346839/src/decorator.py#L195 unconditionally adds the right parenthesis that was (actually or supposedly) removed previously.

I could fix this issue in my own environment, but the fix is kind of dirty, and has not gone through all your testing, obviously.

amitaiirron avatar Dec 26 '21 16:12 amitaiirron

This is a known issue: https://github.com/micheles/decorator/issues/114 It is tricky and not particularly high priority for the moment.

micheles avatar Dec 27 '21 04:12 micheles