8000 `FunctionMaker.create()` fails when given a function definition with a return type annotation. · Issue #138 · micheles/decorator · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
FunctionMaker.create() fails when given a function definition with a return type annotation. #138
Open
@amitaiirron

Description

@amitaiirron

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

name, rest = obj.strip().split('(', 1)

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

body = 'def %(name)s(%(signature)s):\n' + ibody
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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0