python / python/typing

When making a dynamic member descriptor that can also behave as a Wrapper Why Does Self Not get deleted from ParamSpec?

Ouverte
#2,060 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

topic: other
Langage dominant
Python
Étoiles
1.8k
Forks
302
Merge moyen
23 h
PR mergées (30 j)
8

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)

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par l’exemple Python fourni et examinez les règles relatives à ParamSpec, Self, Concatenate et à la liaison des descripteurs. Comparez la façon dont mypy et pyright interprètent l’exemple, puis déterminez si le résultat attendu nécessite une clarification de la spécification ou une modification de la documentation ; le travail est terminé lorsque le comportement et les annotations attendues sont clairement définis.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
developer-experience
Type d'issue
Documentation
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.