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

ic does not show funtion name, *args or **kwargs inside a wrapper #153

Open
Soif2Sang opened this issue Sep 15, 2023 · 3 comments
Open

ic does not show funtion name, *args or **kwargs inside a wrapper #153

Soif2Sang opened this issue Sep 15, 2023 · 3 comments

Comments

@Soif2Sang
Copy link

@decohints
def get_name(func):
    @wraps(func)
    def wrapper(self: object, *args: object, **kwargs: object):
        func_output = ic(func(self, *args, **kwargs))
        return func_output
    return wrapper

returns 'ic| func(self, *args, **kwargs): None'

instead of the actual functio name, args, and kwargs

@graipher
Copy link

graipher commented Oct 9, 2023

I guess this is actually a consequence of it showing the local variable names. They just happen to be not very helpful here. You get the same when doing:

from icecream import ic

def f(*args, **kwargs):
    return args, kwargs

args = 1, 2
kwargs = {"a": 3}
ic(f(*args, **kwargs))
# ic| f(*args, **kwargs): ((1, 2), {'a': 3})

Not sure how one could distinguish this case from the wrapped function case.

@Emasoft
Copy link

Emasoft commented Dec 23, 2023

@graipher

Not sure how one could distinguish this case from the wrapped function case.

I think Microsoft stumbled on a similar issue with Pylance, and they solved it like this (not sure if applicable to ic):

microsoft/pylance-release#4140
(related: microsoft/pylance-release#442 )

@graipher
Copy link

graipher commented Dec 28, 2023

I just checked, adding type hints (as alluded to in that first pylance link, to leverage the better type hints introduced by functools.wraps in recent Python versions), does not help:

from icecream import ic
from typing import Callable, TypeVar, ParamSpec

R = TypeVar("R")
P = ParamSpec("P")


def get_name(func: Callable[P, R]) -> Callable[P, R]:
    @wraps(func)
    def wrapper(self: object, *args: P.args, **kwargs: P.kwargs) -> R:
        func_output = ic(func(self, *args, **kwargs))
        return func_output
    return wrapper


class A:
    def a(self, x: str) -> str:
        return x


a = A()
get_name(a.a)("foo")
# ic| func(self, *args, **kwargs): 'foo'

Not unsurprising, since I guess ic only inspects the scope surrounding the call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants