FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Support default type parameters in Generic by GruffElixir · Pull Request #795 · python/typing_extensions · GitHub

Repository navigation

Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .py  (2) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
8 changes: 8 additions & 0 deletions src/test_typing_extensions.py
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
Original file line number Diff line number Diff line change
Expand Up @@ -7815,6 +7815,14 @@ def test_typevar(self):
class A(Generic[T]): ...
self.assertEqual(Optional[T].__args__, (T, type(None)))

def test_generic_typevar_default(self):
R = TypeVar("R")
T = TypeVar("T", default=int)

class A(Generic[R, T]): ...

self.assertEqual(get_args(A[str]), (str, int))

def test_typevar_none(self):
U = typing_extensions.TypeVar('U')
U_None = typing_extensions.TypeVar('U_None', default=None)
Expand Down
66 changes: 66 additions & 0 deletions src/typing_extensions.py
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
Original file line number Diff line number Diff line change
Expand Up @@ -4418,5 +4418,71 @@ def type_repr(value):
# These are defined unconditionally because they are used in
# typing-extensions itself.
Generic = typing.Generic

# Python 3.9-3.12 do not ask type parameters to fill in their defaults when
# specializing a generic alias. TypeVarLike implementations above expose the
# same substitution hook used by newer versions of typing, so apply it before
# delegating to the standard library alias implementation.
if not _PEP_696_IMPLEMENTED:
_generic_alias_getitem = typing._GenericAlias.__getitem__

@typing._tp_cache
def _generic_alias_getitem_with_defaults(self, params):
if not isinstance(params, tuple):
params = (params,)
params = tuple(typing._type_convert(param) for param in params)

for param in self.__parameters__:
prepare = getattr(param, "__typing_prepare_subst__", None)
if prepare is None:
continue
if type(param).__name__ == "TypeVar":
if not getattr(param, "has_default", lambda: False)():
continue
elif not (
sys.version_info < (3, 11)
and type(param).__name__ == "TypeVarTuple"
):
continue
params = prepare(self, params)

return _generic_alias_getitem(self, params)

typing._GenericAlias.__getitem__ = _generic_alias_getitem_with_defaults

_generic_class_getitem_descriptor = typing.Generic.__dict__["__class_getitem__"]
if hasattr(_generic_class_getitem_descriptor, "__func__"):
_generic_class_getitem = _generic_class_getitem_descriptor.__func__
else:
# Python 3.12 stores this as a classmethod descriptor rather than a
# classmethod object. Bind it through the subclass so the original
# implementation receives the class being specialized.
def _generic_class_getitem(cls, params):
return _generic_class_getitem_descriptor.__get__(None, cls)(params)

@typing._tp_cache
def _generic_class_getitem_with_defaults(cls, params):
if not isinstance(params, tuple):
params = (params,)
params = tuple(typing._type_convert(param) for param in params)

for param in getattr(cls, "__parameters__", ()):
prepare = getattr(param, "__typing_prepare_subst__", None)
if prepare is None:
continue
if type(param).__name__ == "TypeVar":
if not getattr(param, "has_default", lambda: False)():
continue
elif not (
sys.version_info < (3, 11)
and type(param).__name__ == "TypeVarTuple"
):
continue
params = prepare(cls, params)

return _generic_class_getitem(cls, params)

typing.Generic.__class_getitem__ = classmethod(_generic_class_getitem_with_defaults)

ForwardRef = typing.ForwardRef
Annotated = typing.Annotated
Loading

Back | FazBrowse Home | New Git URL