Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dcdc53f

Browse filesBrowse files
authored
Restore compatibility with PyPy <3.9 (#262)
1 parent bc9bc06 commit dcdc53f
Copy full SHA for dcdc53f

File tree

Expand file treeCollapse file tree

3 files changed

+39
-13
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+39
-13
lines changed

‎.github/workflows/ci.yml

Copy file name to clipboardExpand all lines: .github/workflows/ci.yml
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ jobs:
5353
- "3.11"
5454
- "3.11.0"
5555
- "3.12"
56+
- "pypy3.7"
57+
- "pypy3.8"
5658
- "pypy3.9"
5759
- "pypy3.10"
5860

‎CHANGELOG.md

Copy file name to clipboardExpand all lines: CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Release 4.7.1 (???)
2+
3+
- Fix `TypedDict`, `NamedTuple` and `is_protocol` tests on PyPy-3.7 and
4+
PyPy-3.8. Patch by Alex Waygood.
5+
16
# Release 4.7.0 (June 28, 2023)
27

38
- This is expected to be the last feature release supporting Python 3.7,

‎src/typing_extensions.py

Copy file name to clipboardExpand all lines: src/typing_extensions.py
+32-13Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,21 @@ def __round__(self, ndigits: int = 0) -> T_co:
953953
pass
954954

955955

956+
def _ensure_subclassable(mro_entries):
957+
def inner(func):
958+
if sys.implementation.name == "pypy" and sys.version_info < (3, 9):
959+
cls_dict = {
960+
"__call__": staticmethod(func),
961+
"__mro_entries__": staticmethod(mro_entries)
962+
}
963+
t = type(func.__name__, (), cls_dict)
964+
return functools.update_wrapper(t(), func)
965+
else:
966+
func.__mro_entries__ = mro_entries
967+
return func
968+
return inner
969+
970+
956971
if sys.version_info >= (3, 13):
957972
# The standard library TypedDict in Python 3.8 does not store runtime information
958973
# about which (if any) keys are optional. See https://bugs.python.org/issue38834
@@ -1059,6 +1074,9 @@ def __subclasscheck__(cls, other):
10591074

10601075
__instancecheck__ = __subclasscheck__
10611076

1077+
_TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
1078+
1079+
@_ensure_subclassable(lambda bases: (_TypedDict,))
10621080
def TypedDict(__typename, __fields=_marker, *, total=True, **kwargs):
10631081
"""A simple typed namespace. At runtime it is equivalent to a plain dict.
10641082
@@ -1142,9 +1160,6 @@ class Point2D(TypedDict):
11421160
td.__orig_bases__ = (TypedDict,)
11431161
return td
11441162

1145-
_TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
1146-
TypedDict.__mro_entries__ = lambda bases: (_TypedDict,)
1147-
11481163
if hasattr(typing, "_TypedDictMeta"):
11491164
_TYPEDDICT_TYPES = (typing._TypedDictMeta, _TypedDictMeta)
11501165
else:
@@ -2633,6 +2648,13 @@ def __new__(cls, typename, bases, ns):
26332648
nm_tpl.__init_subclass__()
26342649
return nm_tpl
26352650

2651+
_NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {})
2652+
2653+
def _namedtuple_mro_entries(bases):
2654+
assert NamedTuple in bases
2655+
return (_NamedTuple,)
2656+
2657+
@_ensure_subclassable(_namedtuple_mro_entries)
26362658
def NamedTuple(__typename, __fields=_marker, **kwargs):
26372659
"""Typed version of namedtuple.
26382660
@@ -2698,19 +2720,15 @@ class Employee(NamedTuple):
26982720
nt.__orig_bases__ = (NamedTuple,)
26992721
return nt
27002722

2701-
_NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {})
2702-
27032723
# On 3.8+, alter the signature so that it matches typing.NamedTuple.
27042724
# The signature of typing.NamedTuple on >=3.8 is invalid syntax in Python 3.7,
27052725
# so just leave the signature as it is on 3.7.
27062726
if sys.version_info >= (3, 8):
2707-
NamedTuple.__text_signature__ = '(typename, fields=None, /, **kwargs)'
2708-
2709-
def _namedtuple_mro_entries(bases):
2710-
assert NamedTuple in bases
2711-
return (_NamedTuple,)
2712-
2713-
NamedTuple.__mro_entries__ = _namedtuple_mro_entries
2727+
_new_signature = '(typename, fields=None, /, **kwargs)'
2728+
if isinstance(NamedTuple, _types.FunctionType):
2729+
NamedTuple.__text_signature__ = _new_signature
2730+
else:
2731+
NamedTuple.__call__.__text_signature__ = _new_signature
27142732

27152733

27162734
if hasattr(collections.abc, "Buffer"):
@@ -2986,7 +3004,8 @@ def is_protocol(__tp: type) -> bool:
29863004
return (
29873005
isinstance(__tp, type)
29883006
and getattr(__tp, '_is_protocol', False)
2989-
and __tp != Protocol
3007+
and __tp is not Protocol
3008+
and __tp is not getattr(typing, "Protocol", object())
29903009
)
29913010

29923011
def get_protocol_members(__tp: type) -> typing.FrozenSet[str]:

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.