8000 Remove unnecessary hasattr check from TypedDict (#533) · python/typing_extensions@3f47bf9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3f47bf9

Browse files
Remove unnecessary hasattr check from TypedDict (#533)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
1 parent caf24b4 commit 3f47bf9

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ aliases that have a `Concatenate` special form as their argument.
3838
Patch by [Daraan](https://github.com/Daraan).
3939
- Fix error on Python 3.10 when using `typing.Concatenate` and
4040
`typing_extensions.Concatenate` together. Patch by [Daraan](https://github.com/Daraan).
41+
- Backport of CPython PR [#109544](https://github.com/python/cpython/pull/109544)
42+
to reflect Python 3.13+ behavior: A value assigned to `__total__` in the class body of a
43+
`TypedDict` will be overwritten by the `total` argument of the `TypedDict` constructor.
44+
Patch by [Daraan](https://github.com/Daraan), backporting a CPython PR by Jelle Zijlstra.
4145

4246
# Release 4.12.2 (June 7, 2024)
4347

src/test_typing_extensions.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4237,6 +4237,37 @@ def test_total(self):
42374237
self.assertEqual(Options.__required_keys__, frozenset())
42384238
self.assertEqual(Options.__optional_keys__, {'log_level', 'log_path'})
42394239

4240+
def test_total_inherits_non_total(self):
4241+
class TD1(TypedDict, total=False):
4242+
a: int
4243+
4244+
self.assertIs(TD1.__total__, False)
4245+
4246+
class TD2(TD1):
4247+
b: str
4248+
4249+
self.assertIs(TD2.__total__, True)
4250+
4251+
def test_total_with_assigned_value(self):
4252+
class TD(TypedDict):
4253+
__total__ = "some_value"
4254+
4255+
self.assertIs(TD.__total__, True)
4256+
4257+
class TD2(TypedDict, total=True):
4258+
__total__ = "some_value"
4259+
4260+
self.assertIs(TD2.__total__, True)
4261+
4262+
class TD3(TypedDict, total=False):
4263+
__total__ = "some value"
4264+
4265+
self.assertIs(TD3.__total__, False)
4266+
4267+
TD4 = TypedDict('TD4', {'__total__': "some_value"}) # noqa: F821
4268+
self.assertIs(TD4.__total__, True)
4269+
4270+
42404271
def test_optional_keys(self):
42414272
class Point2Dor3D(Point2D, total=False):
42424273
z: int

src/typing_extensions.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,8 +1029,7 @@ def __new__(cls, name, bases, ns, *, total=True, closed=False):
10291029
tp_dict.__optional_keys__ = frozenset(optional_keys)
10301030
tp_dict.__readonly_keys__ = frozenset(readonly_keys)
10311031
tp_dict.__mutable_keys__ = frozenset(mutable_keys)
1032-
if not hasattr(tp_dict, '__total__'):
1033-
tp_dict.__total__ = total
1032+
tp_dict.__total__ = total
10341033
tp_dict.__closed__ = closed
10351034
tp_dict.__extra_items__ = extra_items_type
10361035
return tp_dict

0 commit comments

Comments
 (0)
0