[Python] How to correctly type-annotate a classmethod-like descriptor in python?

Discussão em 'Python' iniciado por Stack, Julho 6, 2025.

  1. Stack

    Stack Membro Participativo

    classonlymethod decorator/descriptor defined below is like the built-in classmethod, but you're not allowed to call the method on instances, only on the class itself.

    from typing import Concatenate, Self
    from collections.abc import Callable
    from functools import partial


    class classonlymethod[C, **P, R]:
    __slots__ = (
    '_func',
    )

    def __init__(self, func: Callable[Concatenate[type[C], P], R], /):
    self._func = func

    def __get__(self, instance: None, owner: type[C], /) -> Callable[P, R]:
    if instance is not None:
    raise AttributeError('class-only method')

    return partial(self._func, owner)


    class Foo:
    @classonlymethod
    def bar(cls: type[Self]) -> None:
    raise NotImplementedError()


    However, pyright complains on the definition of Foo.bar:


    Type of parameter "cls" must be a supertype of its class "Foo" (reportGeneralTypeIssues)
    ​

    Which is odd, since it matches annotations of classmethodin typeshed.

    I don't understand this error. Surely a Foo (denoted by Self) is a (non-strict) supertype of itself? I tried other ways to refer to Foo in the cls annotation, but they didn't work either.

    What's going on here and how do I fix it? Is it a pyright bug?

    Continue reading...

Compartilhe esta Página