Created
November 14, 2025 01:37
-
-
Save mypy-play/b8151b02fa9af8192dd11a0966c20c9a to your computer and use it in GitHub Desktop.
Shared via mypy Playground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from typing import Any, Generic, TypeVarTuple, TypeVar, Concatenate, Tuple, Unpack, ParamSpec, Optional, TypedDict, Required, NotRequired | |
| T = TypeVar('T') | |
| TT = TypeVarTuple('TT') | |
| TTF = TypeVarTuple('TTF') | |
| P = ParamSpec('P') | |
| class Base(): | |
| @classmethod | |
| def do(cls, *args, **kwargs): | |
| if kwargs['maybe_present'] is None: | |
| kwargs['maybe_present'] = 5 | |
| return cls._really_do(*args, **kwargs) | |
| @classmethod | |
| def _really_do(cls, *args, **kwargs): | |
| raise NotImplementedError | |
| class Derived(Base): | |
| @classmethod | |
| def _really_do(cls, i, s, **kwargs): | |
| return (i + kwargs['maybe_present']) * s | |
| Derived.do(2, 'seven') | |
| class KWMaybe(TypedDict): | |
| maybe_present: NotRequired[int] | |
| class KWReq(TypedDict): | |
| maybe_present: Required[int] | |
| class BaseTuple(Generic[*TT, T]): | |
| @classmethod | |
| def do(cls: type[BaseTuple], *args: *TT, **kwargs: Unpack[KWMaybe]) -> T: | |
| if kwargs['maybe_present'] is None: | |
| kwargs['maybe_present'] = 5 | |
| return cls._really_do(*args, **kwargs) | |
| @classmethod | |
| def _really_do(cls: type[BaseTuple], *args: *TT, **kwargs: Unpack[KWReq]) -> T: | |
| raise NotImplementedError | |
| class DerivedTuple(BaseTuple[int, str, str]): | |
| @classmethod | |
| def _really_do(cls: type[DerivedTuple], i: int, s: str, /, **kwargs: Unpack[KWReq]) -> str: | |
| return i * s | |
| DerivedTuple.do(5, 'bye') | |
| DerivedTuple.do(5, 'bye', maybe_present = 7) | |
| #DerivedTuple.do(5, 'bye', something = "else") | |
| #DerivedTuple.do("whatever", "i", "want") | |
| class DefaultedTuple(BaseTuple[int, str | None, str]): | |
| @classmethod | |
| def do(cls, i: int, s: str | None = None, /, **kwargs: Unpack[KWMaybe]) -> str: | |
| return super(DefaultedTuple, cls).do(i, s, **kwargs) | |
| @classmethod | |
| def _really_do(cls: type[DefaultedTuple], i: int, s: str | None, /, **kwargs: Unpack[KWReq]) -> str: | |
| if s is None: | |
| return i * 'hi' | |
| return i * s | |
| DefaultedTuple.do(5, 'a') | |
| DefaultedTuple.do(5) | |
| DefaultedTuple.do(5, maybe_present = 7) | |
| class KWAdditionalMaybe(KWMaybe): | |
| additional: NotRequired[str] | |
| class KWAdditional(KWReq): | |
| additional: NotRequired[str] | |
| class KeywordTuple(BaseTuple[int, str]): | |
| # @classmethod | |
| # def do(cls, i: int, /, **kwargs: Unpack[KWAdditionalMaybe]) -> str: | |
| # return super(KeywordTuple, cls).do(i, **kwargs) | |
| @classmethod | |
| def _really_do(cls: type[KeywordTuple], i: int, /, **kwargs: Unpack[KWAdditional]) -> str: | |
| return i * kwargs['additional'] | |
| KeywordTuple.do(5) | |
| #KeywordTuple.do(5, additional="hi") | |
| KW = TypeVar('KW', bound=KWMaybe) | |
| class BaseTupleK(Generic[*TT, T]): | |
| # @classmethod | |
| # def __init_subclass__(cls, /, KW=KWMaybe, **kwargs): | |
| # super().__init_subclass__(**kwargs) | |
| # cls.KW = KW | |
| @classmethod | |
| def do(cls: type[BaseTupleK], *args: *TT, **kwargs: Unpack[KWMaybe]) -> T: | |
| if kwargs['maybe_present'] is None: | |
| kwargs['maybe_present'] = 5 | |
| return cls._really_do(*args, **kwargs) | |
| @classmethod | |
| def _really_do(cls: type[BaseTupleK], *args: *TT, **kwargs: Unpack[KWReq]) -> T: | |
| raise NotImplementedError | |
| class BaseParams(Generic[P, T]): | |
| @classmethod | |
| def do(cls: type[BaseParams], *args: P.args, **kwargs: P.kwargs) -> T: | |
| if kwargs['maybe_present'] is None: | |
| kwargs['maybe_present'] = 5 | |
| return cls._really_do(*args, **kwargs) | |
| @classmethod | |
| def _really_do(cls: type, *args: P.args, **kwargs: P.kwargs) -> T: | |
| raise NotImplementedError | |
| class DerivedParams(BaseParams[[int, str], str]): | |
| @classmethod | |
| def _really_do(cls: type, i: int, s: str, **kwargs: Any) -> str: | |
| return i * s | |
| DerivedParams.do(5, "hi") | |
| # DerivedParams.do(5, "hi", maybe_present=3) | |
| class InferredParams(BaseParams[..., str]): | |
| @classmethod | |
| def _really_do(cls: type, i: int, s: str, **kwargs: Any) -> str: | |
| return i * s | |
| InferredParams.do(5, "hi", maybe_present=3) | |
| InferredParams.do("whatever", "i", "please") | |
| class DefaultedParams(BaseParams[[int, str | None], str]): | |
| @classmethod | |
| def _really_do(cls: type, i: int, s: str | None = None, **kwargs: Any) -> str: | |
| if s is None: | |
| return i * 'hi' | |
| return i * s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment