OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

How can I use ParamSpec with method decorators?

  • Thread starter Thread starter Ocab19
  • Start date Start date
O

Ocab19

Guest
I was following the example from PEP 0612 (last one in the Motivation section) to create a decorator that can add default parameters to a function. The problem is, the example provided only works for functions but not methods, because Concate doesn't allow inserting self anywhere in the definition.

Consider this example, as an adaptation of the one in the PEP:

Code:
def with_request(f: Callable[Concatenate[Request, P], R]) -> Callable[P, R]:
    def inner(*args: P.args, **kwargs: P.kwargs) -> R:
        return f(*args, request=Request(), **kwargs)

    return inner


class Thing:
    @with_request
    def takes_int_str(self, request: Request, x: int, y: str) -> int:
        print(request)
        return x + 7


thing = Thing()
thing.takes_int_str(1, "A")  # Invalid self argument "Thing" to attribute function "takes_int_str" with type "Callable[[str, int, str], int]"
thing.takes_int_str("B", 2)  # Argument 2 to "takes_int_str" of "Thing" has incompatible type "int"; expected "str"

Both attempts raise a mypy error because Request doesn't match self as the first argument of the method, like Concatenate said. The problem is that Concatenate doesn't allow you to append Request to the end, so something like Concatenate[P, Request] won't work either.

This would be the ideal way to do this in my view, but it doesn't work because "The last parameter to Concatenate needs to be a ParamSpec".

Code:
def with_request(f: Callable[Concatenate[P, Request], R]) -> Callable[P, R]:
    ...


class Thing:
    @with_request
    def takes_int_str(self, x: int, y: str, request: Request) -> int:
        ...

Any ideas?
<p>I was following the example <a href="https://peps.python.org/pep-0612/#motivation" rel="noreferrer">from PEP 0612</a> (last one in the Motivation section) to create a decorator that can add default parameters to a function. The problem is, the example provided only works for functions but not methods, because <code>Concate</code> doesn't allow inserting <code>self</code> anywhere in the definition.</p>
<p>Consider this example, as an adaptation of the one in the PEP:</p>
<pre><code>def with_request(f: Callable[Concatenate[Request, P], R]) -> Callable[P, R]:
def inner(*args: P.args, **kwargs: P.kwargs) -> R:
return f(*args, request=Request(), **kwargs)

return inner


class Thing:
@with_request
def takes_int_str(self, request: Request, x: int, y: str) -> int:
print(request)
return x + 7


thing = Thing()
thing.takes_int_str(1, "A") # Invalid self argument "Thing" to attribute function "takes_int_str" with type "Callable[[str, int, str], int]"
thing.takes_int_str("B", 2) # Argument 2 to "takes_int_str" of "Thing" has incompatible type "int"; expected "str"
</code></pre>
<p>Both attempts raise a mypy error because <code>Request</code> doesn't match <code>self</code> as the first argument of the method, like <code>Concatenate</code> said. The problem is that <code>Concatenate</code> doesn't allow you to append <code>Request</code> to the end, so something like <code>Concatenate[P, Request]</code> won't work either.</p>
<p>This would be the ideal way to do this in my view, but it doesn't work because "The last parameter to Concatenate needs to be a ParamSpec".</p>
<pre><code>def with_request(f: Callable[Concatenate[P, Request], R]) -> Callable[P, R]:
...


class Thing:
@with_request
def takes_int_str(self, x: int, y: str, request: Request) -> int:
...
</code></pre>
<p>Any ideas?</p>
 

Latest posts

A
Replies
0
Views
1
Adrian-Mihai Enache
A
Top