Created
July 23, 2024 01:55
-
-
Save clintval/737d51492d5a3803b1dd6765ec51db8d to your computer and use it in GitHub Desktop.
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
class MethodType: | |
"""A Python-equivalent method type that binds type arguments to the calling class.""" | |
def __init__(self, func: Callable, obj: object) -> None: | |
"""Initialize this method with the calling class and function.""" | |
self.__func__ = func | |
self.__self__ = obj | |
self._generic_classmethod = False | |
def __call__(self, *args: object, **kwargs: object) -> object: | |
"""Call this method with the given arguments and keyword arguments.""" | |
return self.__func__(self.__self__, *args, **kwargs) | |
def __getitem__(self, *values: type) -> None: | |
"""Bind the type arguments this method was given to the calling class.""" | |
print(self.__self__) | |
if hasattr(self.__self__, "__args__"): | |
print(self.__self__.__args__) | |
assert all(isinstance(value, type) for value in values), "Type arguments must be types!" | |
# https://github.com/python/cpython/blob/0aa0fc3d3ca144f979c684552a56a18ed8f558e4/Lib/typing.py#L1346 | |
self.__self__.__args__ = values | |
return self | |
class classmethod_generic: | |
"""A generic classmethod decorator that will allow the method to know its type parameters.""" | |
def __init__(self, func: Callable) -> None: | |
"""Initialize the decorator with the supplied classmethod.""" | |
self.func = func | |
def __get__(self, obj: object, cls: object | None = None) -> Callable: | |
"""Wrap the generic classmethod with a custom method type that knows its type parameters.""" | |
if cls is None: | |
cls = type(obj) | |
method = MethodType(self.func, cls) | |
method._generic_classmethod = True | |
return method |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment