python / python/typing

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

Abierto
#2,060 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

topic: other
Lenguaje dominante
Python
Estrellas
1.8k
Forks
302
Merge medio
23 h
PR fusionados (30 d)
8

Descripción

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)

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con el ejemplo de Python proporcionado y revisa las reglas de ParamSpec, Self, Concatenate y la vinculación de descriptores. Compara cómo interpretan mypy y pyright el ejemplo y determina después si el resultado previsto requiere una aclaración de la especificación o un cambio en la documentación; se considera terminado cuando el comportamiento y las anotaciones esperadas están claramente decididos.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
developer-experience
Tipo de issue
Documentación
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.