@@ -1801,31 +1801,66 @@ def new_user(user_class: Type[U]) -> U:
1801
1801
"""
1802
1802
1803
1803
1804
- def NamedTuple (typename , fields ):
1805
- """Typed version of namedtuple.
1804
+ def _make_nmtuple (name , types ):
1805
+ nm_tpl = collections .namedtuple (name , [n for n , t in types ])
1806
+ nm_tpl ._field_types = dict (types )
1807
+ try :
1808
+ nm_tpl .__module__ = sys ._getframe (2 ).f_globals .get ('__name__' , '__main__' )
1809
+ except (AttributeError , ValueError ):
1810
+ pass
1811
+ return nm_tpl
1806
1812
1807
- Usage::
1808
1813
1809
- Employee = typing.NamedTuple('Employee', [('name', str), 'id', int)])
1814
+ if sys .version_info [:2 ] >= (3 , 6 ):
1815
+ class NamedTupleMeta (type ):
1810
1816
1811
- This is equivalent to::
1817
+ def __new__ (cls , typename , bases , ns , * , _root = False ):
1818
+ if _root :
1819
+ return super ().__new__ (cls , typename , bases , ns )
1820
+ types = ns .get ('__annotations__' , {})
1821
+ return _make_nmtuple (typename , types .items ())
1812
1822
1813
- Employee = collections.namedtuple('Employee', ['name', 'id'])
1823
+ class NamedTuple (metaclass = NamedTupleMeta , _root = True ):
1824
+ """Typed version of namedtuple.
1814
1825
1815
- The resulting class has one extra attribute: _field_types,
1816
- giving a dict mapping field names to types. (The field names
1817
- are in the _fields attribute, which is part of the namedtuple
1818
- API.)
1819
- """
1820
- fields = [(n , t ) for n , t in fields ]
1821
- cls = collections .namedtuple (typename , [n for n , t in fields ])
1822
- cls ._field_types = dict (fields )
1823
- # Set the module to the caller's module (otherwise it'd be 'typing').
1824
- try :
1825
- cls .__module__ = sys ._getframe (1 ).f_globals .get ('__name__' , '__main__' )
1826
- except (AttributeError , ValueError ):
1827
- pass
1828
- return cls
1826
+ Usage::
1827
+
1828
+ class Employee(NamedTuple):
1829
+ name: str
1830
+ id: int
1831
+
1832
+ This is equivalent to::
1833
+
1834
+ Employee = collections.namedtuple('Employee', ['name', 'id'])
1835
+
1836
+ The resulting class has one extra attribute: _field_types,
1837
+ giving a dict mapping field names to types. (The field names
1838
+ are in the _fields attribute, which is part of the namedtuple
1839
+ API.) Backward-compatible usage::
1840
+
1841
+ Employee = NamedTuple('Employee', [('name', str), ('id', int)])
1842
+ """
1843
+
1844
+ def __new__ (self , typename , fields ):
1845
+ return _make_nmtuple (typename , fields )
1846
+ else :
1847
+ def NamedTuple (typename , fields ):
1848
+ """Typed version of namedtuple.
1849
+
1850
+ Usage::
1851
+
1852
+ Employee = typing.NamedTuple('Employee', [('name', str), 'id', int)])
1853
+
1854
+ This is equivalent to::
1855
+
1856
+ Employee = collections.namedtuple('Employee', ['name', 'id'])
1857
+
1858
+ The resulting class has one extra attribute: _field_types,
1859
+ giving a dict mapping field names to types. (The field names
1860
+ are in the _fields attribute, which is part of the namedtuple
1861
+ API.)
1862
+ """
1863
+ return _make_nmtuple (typename , fields )
1829
1864
1830
1865
1831
1866
def NewType (name , tp ):
0 commit comments