Search code examples
pythonpycharmdecorator

Hide injected parameter by a decorator from function parameter hinting in PyCharm


I have a function that has a parameter injected by a decorator like so:

def decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        return func('hello', *args, **kwargs)
    return wrapper

@decorator
def func(hello_string: str, a: int, b: int):
    <some code>

and you call the function like this:

func(1,2)

I want Pycharm to not show me the existence of hello_string as a parameter, I want to show the user just the parameters that they need to put in the function when calling it (a and b).

enter image description here

is there a way to do it, or are decorators not a good solution for this type of injection? I tried using context managers inside the function as well, but they cause the whole function to indent, and using multiple context managers makes the method look messy, while using multiple decorators is clean.

Thanks


Solution

  • I don't know exactly what PyCharm would do with this, but the way to indicate that decorator returns a function with a different signature based the original is to use a ParamSpec.

    from typing import Callable, Concatenate, ParamSpec, TypeVar
    P = ParamSpec('P')
    RV = TypeVar('RV')
    
    def decorator(func: Callable[Concatenate[str, P], RV]) -> Callable[P, RV]:
        @wraps(func)
        def wrapper(*args: P.args, **kwargs: P.kwargs) -> RV:
            return func('hello', *args, **kwargs)
        return wrapper
    
    @decorator
    def func(hello_string: str, a: int, b: int):
        <some code>
    

    The type hints for decorator says that func is a function that has a str-valued parameter and zero or more arbitrary parameters, returning some arbitrary value, and that decorator returns a callable with the same arbitrary parameters and return value as the argument, minus the initial str-valued parameter.