Type hinting class-decorator factories. #1752
Replies: 1 comment
-
Ok, my best bet is probably to just make these non-generic (which will cause false-negatives, if the decorator has bounds on the class-type): Code sample in pyright playground # fmt: off
from functools import partial, partialmethod, wraps
from typing import Any, Protocol, TypeVar, assert_type, overload
T = TypeVar("T")
class ClassDecorator(Protocol):
def __call__(self, cls: type[T], /) -> type[T]: ...
class ParametrizedClassDecorator(Protocol):
@overload
def __call__(self, cls: type[T], /, **kwargs: Any) -> type[T]: ...
@overload
def __call__(self, /, **kwargs: Any) -> ClassDecorator: ...
def decorator(deco: ClassDecorator, /) -> ParametrizedClassDecorator:
@wraps(deco)
def __parametrized_decorator(obj=None, /, **kwargs):
if obj is None:
return partial(deco, **kwargs)
return deco(obj, **kwargs)
return __parametrized_decorator # pyright: ignore[reportReturnType]
def format_obj(obj: object, **options: Any) -> str:
return f"Custom formatting of {object.__repr__(obj)}" # dummy implementation
@decorator
def pprint(cls: type[T], /, **options: Any) -> type[T]:
cls.__repr__ = partialmethod(format_obj, **options) # pyright: ignore[reportAttributeAccessIssue]
return cls
# Test cases
@pprint
class A: ...
@pprint(indent=4)
class B: ...
class C: ...
class D: ...
assert_type(A, type[A]) # ✅
assert_type(B, type[B]) # ✅
assert_type(pprint(C), type[C]) # ✅
assert_type(pprint(D, indent=4), type[D]) # ✅
print(A()) |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I want to type-hint a decorator factory that allows to use a decorator as-is
@my_decorator
, or with arguments@my_decorator(**options)
. The following example type-checks inmypy
, apparently due to some special-casing of callback-protocols onmypy
's side, but not inpyright
(microsoft/pyright#8014).What can I do to alleviate the situation? I am fine with using type-ignores inside the definition of
decorator
andpprint
, but I'd like to avoid having to add type-ignore at the call sites.Code sample in pyright playground
Beta Was this translation helpful? Give feedback.
All reactions