When making a dynamic member descriptor that can also behave as a Wrapper Why Does Self Not get deleted from ParamSpec?
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Documentation
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- python
- Domain
- developer-experience
Research direction
Start with the supplied Python example and review the rules for ParamSpec, Self, Concatenate, and descriptor binding. Compare how mypy and pyright interpret the example, then determine whether the intended outcome requires a specification clarification or documentation change; done means the behavior and expected annotations are clearly decided.
Written by the indexing model from the issue text.
Description
I've bumped into one of the largest and most frustrating puzzles I've ever encountered but I wanted to understand what the thought process behind ParamSpec was for class functions because I think if Self was ignored from ParamSpec dynamically based on weather or not a class function was in use it would not only fix lru_cache but it would also allow async_lru library to be type-hinted as well. No matter what I do, nothing works. I've tried multiple search engines to no avail so I go here now as my final resort since it's not a mypy problem because pyright is also plagued by the same rules.
from typing import ParamSpec, TypeVar, Callable, Protocol
P = ParamSpec("P")
T = TypeVar("T")
I = TypeVar("I")
# I made a class of my own for callable to illistrate the problem at hand.
class CallableProto(Protocol[P, T]):
def __call__(self, *args:P.args, **kwds:P.kwargs) -> T:...
class RespectingCallable(CallableProto[P, T]):
def __init__(self, func:Callable[P, T]):
self.func = func
# My question is Why does Self inside of a class function still get preserved in
# ParamSpec when it's just a class function? Shouldn't it get removed?
# Also Concatenate doesn't work I've tried that one already with no success...
def __get__(self, instance:I, obj:type[I]) -> CallableProto[P, T]:...
class A:
def __init__(self) -> None:
pass
@RespectingCallable
def coro(self, val:int) -> str:
return f"{val}"
g = A()
# It appears as (self: A, val: int) -> str instead of (val: int) -> str
# (mypy and pyright are also both are plagued by these rules)
g.coro(1)
@RespectingCallable
def func(i:int) -> str:
return f"{i}"
# Somehow this is fine?
func(1)
- Dominant language
- Python
- Stars
- 1.8k
- Forks
- 302
- Avg merge
- 23h
- Merged PRs (30d)
- 8
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from python/typing
-
topic: typing spec
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
topic: typing spec
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
topic: documentation
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
topic: documentation
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
topic: conformance tests topic: typing spec
Difficulty 3/5 1-2 days Newbie friendliness 72/100
Similar issues
-
Add: hunch Open
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
AbdelStark/awesome-typesafe#104 ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
DiamondLightSource/dodal#2211 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
openml/openml-python#1749 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
sipyourdrink-ltd/bernstein#6191 ·