Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support decorated providers #127

Closed
jl-wynen opened this issue Feb 15, 2024 · 1 comment · Fixed by #128
Closed

Support decorated providers #127

jl-wynen opened this issue Feb 15, 2024 · 1 comment · Fixed by #128
Assignees
Labels
bug Something isn't working

Comments

@jl-wynen
Copy link
Member

Currently, providers with decorators are broken:

import sciline as sl
import functools

def deco(f):
    @functools.wraps(f)
    def impl(*args, **kwargs):
        return f(*args, **kwargs)
    return impl

@deco
def foo(x: int) -> str:
    return str(x)

pl = sl.Pipeline([foo], params={int: 3})
pl.compute(str)

raises

TypeError: foo() missing 1 required positional argument: 'x'

I think this was introduced in #116 because

import functools
import inspect
from typing import get_type_hints

def deco(f):
    @functools.wraps(f)
    def impl(*args, **kwargs):
        return f(*args, **kwargs)
    return impl

@deco
def foo(x: int) -> str:
    return str(x)

print(get_type_hints(foo))
# -> {'x': <class 'int'>, 'return': <class 'str'>}
print(inspect.getfullargspec(foo))
# -> FullArgSpec(args=[], varargs='args', varkw='kwargs', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={'return': <class 'str'>})

So using getfullargspec is not enough, we also need to use get_type_hints.

Unfortunately, this breaks keyword-only args:

@deco
def foo(x: int, *k: float) -> str:
    return str(x)

print(get_type_hints(foo))
# -> {'x': <class 'int'>, 'k': <class 'float'>, 'return': <class 'str'>}
print(inspect.getfullargspec(foo))
# -> FullArgSpec(args=[], varargs='args', varkw='kwargs', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={'return': <class 'str'>})
@jl-wynen jl-wynen added the bug Something isn't working label Feb 15, 2024
@jl-wynen jl-wynen moved this from Triage to Selected in Development Board Feb 15, 2024
@jl-wynen
Copy link
Member Author

To deal with decorators that use functools.wraps, we can detect a __wrapped__ arg and inspect that instead.
But this would not work for other decorators. But that may not matter.

@jl-wynen jl-wynen self-assigned this Feb 15, 2024
@jl-wynen jl-wynen moved this from Selected to In progress in Development Board Feb 15, 2024
@github-project-automation github-project-automation bot moved this from In progress to Done in Development Board Feb 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

1 participant