Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f7b57df

Browse files
rhettingermiss-islington
authored andcommitted
bpo-36320: Switch typing.NamedTuple from OrderedDict to regular dict (GH-12396)
Also, deprecate the *_field_types* attributes which duplicated the information in *\__annotations__*. https://bugs.python.org/issue36320
1 parent 1be0d11 commit f7b57df

4 files changed

Lines changed: 28 additions & 13 deletions

File tree

Doc/library/typing.rst

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -838,10 +838,11 @@ The module defines the following classes, functions and decorators:
838838

839839
Fields with a default value must come after any fields without a default.
840840

841-
The resulting class has two extra attributes: ``_field_types``,
842-
giving a dict mapping field names to types, and ``_field_defaults``, a dict
843-
mapping field names to default values. (The field names are in the
844-
``_fields`` attribute, which is part of the namedtuple API.)
841+
The resulting class has an extra attribute ``__annotations__`` giving a
842+
dict that maps the field names to the field types. (The field names are in
843+
the ``_fields`` attribute and the default values are in the
844+
``_field_defaults`` attribute both of which are part of the namedtuple
845+
API.)
845846

846847
``NamedTuple`` subclasses can also have docstrings and methods::
847848

@@ -863,6 +864,15 @@ The module defines the following classes, functions and decorators:
863864
.. versionchanged:: 3.6.1
864865
Added support for default values, methods, and docstrings.
865866

867+
.. versionchanged:: 3.8
868+
Deprecated the ``_field_types`` attribute in favor of the more
869+
standard ``__annotations__`` attribute which has the same information.
870+
871+
.. versionchanged:: 3.8
872+
The ``_field_types`` and ``__annotations__`` attributes are
873+
now regular dictionaries instead of instances of ``OrderedDict``.
874+
875+
866876
.. function:: NewType(typ)
867877

868878
A helper function to indicate a distinct types to a typechecker,

Doc/whatsnew/3.8.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,10 @@ Deprecated
510510

511511
(Contributed by Berker Peksag in :issue:`9372`.)
512512

513+
* The :class:`typing.NamedTuple` class has deprecated the ``_field_types``
514+
attribute in favor of the ``__annotations__`` attribute which has the same
515+
information. (Contributed by Raymond Hettinger in :issue:`36320`.)
516+
513517
* :mod:`ast` classes ``Num``, ``Str``, ``Bytes``, ``NameConstant`` and
514518
``Ellipsis`` are considered deprecated and will be removed in future Python
515519
versions. :class:`~ast.Constant` should be used instead.

Lib/typing.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,8 +1325,8 @@ def _make_nmtuple(name, types):
13251325
types = [(n, _type_check(t, msg)) for n, t in types]
13261326
nm_tpl = collections.namedtuple(name, [n for n, t in types])
13271327
# Prior to PEP 526, only _field_types attribute was assigned.
1328-
# Now, both __annotations__ and _field_types are used to maintain compatibility.
1329-
nm_tpl.__annotations__ = nm_tpl._field_types = collections.OrderedDict(types)
1328+
# Now __annotations__ are used and _field_types is deprecated (remove in 3.9)
1329+
nm_tpl.__annotations__ = nm_tpl._field_types = dict(types)
13301330
try:
13311331
nm_tpl.__module__ = sys._getframe(2).f_globals.get('__name__', '__main__')
13321332
except (AttributeError, ValueError):
@@ -1361,7 +1361,7 @@ def __new__(cls, typename, bases, ns):
13611361
"follow default field(s) {default_names}"
13621362
.format(field_name=field_name,
13631363
default_names=', '.join(defaults_dict.keys())))
1364-
nm_tpl.__new__.__annotations__ = collections.OrderedDict(types)
1364+
nm_tpl.__new__.__annotations__ = dict(types)
13651365
nm_tpl.__new__.__defaults__ = tuple(defaults)
13661366
nm_tpl._field_defaults = defaults_dict
13671367
# update from user namespace without overriding special namedtuple attributes
@@ -1386,12 +1386,10 @@ class Employee(NamedTuple):
13861386
13871387
Employee = collections.namedtuple('Employee', ['name', 'id'])
13881388
1389-
The resulting class has extra __annotations__ and _field_types
1390-
attributes, giving an ordered dict mapping field names to types.
1391-
__annotations__ should be preferred, while _field_types
1392-
is kept to maintain pre PEP 526 compatibility. (The field names
1393-
are in the _fields attribute, which is part of the namedtuple
1394-
API.) Alternative equivalent keyword syntax is also accepted::
1389+
The resulting class has an extra __annotations__ attribute, giving a
1390+
dict that maps field names to types. (The field names are also in
1391+
the _fields attribute, which is part of the namedtuple API.)
1392+
Alternative equivalent keyword syntax is also accepted::
13951393
13961394
Employee = NamedTuple('Employee', name=str, id=int)
13971395
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The typing.NamedTuple() class has deprecated the _field_types attribute in
2+
favor of the __annotations__ attribute which carried the same information.
3+
Also, both attributes were converted from OrderedDict to a regular dict.

0 commit comments

Comments
 (0)