]> granicus.if.org Git - python/commitdiff
Issue #17941: Add a *module* parameter to collections.namedtuple()
authorRaymond Hettinger <python@rcn.com>
Mon, 12 Sep 2016 07:18:31 +0000 (00:18 -0700)
committerRaymond Hettinger <python@rcn.com>
Mon, 12 Sep 2016 07:18:31 +0000 (00:18 -0700)
Doc/library/collections.rst
Lib/collections/__init__.py
Lib/test/test_collections.py
Misc/NEWS

index 6daee6f2fd46e91d65c76c0cde5652dde7cfb083..51c235deea09c595b8ebf3588c49d85a3094c4f4 100644 (file)
@@ -763,7 +763,7 @@ Named tuples assign meaning to each position in a tuple and allow for more reada
 self-documenting code.  They can be used wherever regular tuples are used, and
 they add the ability to access fields by name instead of position index.
 
-.. function:: namedtuple(typename, field_names, *, verbose=False, rename=False)
+.. function:: namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)
 
     Returns a new tuple subclass named *typename*.  The new subclass is used to
     create tuple-like objects that have fields accessible by attribute lookup as
@@ -790,6 +790,9 @@ they add the ability to access fields by name instead of position index.
     built.  This option is outdated; instead, it is simpler to print the
     :attr:`_source` attribute.
 
+    If *module* is defined, the ``__module__`` attribute of the named tuple is
+    set to that value.
+
     Named tuple instances do not have per-instance dictionaries, so they are
     lightweight and require no more memory than regular tuples.
 
@@ -800,6 +803,8 @@ they add the ability to access fields by name instead of position index.
        The *verbose* and *rename* parameters became
        :ref:`keyword-only arguments <keyword-only_parameter>`.
 
+    .. versionchanged:: 3.6
+       Added the *module* parameter.
 
 .. doctest::
     :options: +NORMALIZE_WHITESPACE
index 03ecea27cc1c47d3289fa99bfb71ef6487d50d60..bcc429195d0349627b83a6f91c650779946c911a 100644 (file)
@@ -353,7 +353,7 @@ _field_template = '''\
     {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
 '''
 
-def namedtuple(typename, field_names, *, verbose=False, rename=False):
+def namedtuple(typename, field_names, *, verbose=False, rename=False, module=None):
     """Returns a new subclass of tuple with named fields.
 
     >>> Point = namedtuple('Point', ['x', 'y'])
@@ -434,11 +434,15 @@ def namedtuple(typename, field_names, *, verbose=False, rename=False):
     # For pickling to work, the __module__ variable needs to be set to the frame
     # where the named tuple is created.  Bypass this step in environments where
     # sys._getframe is not defined (Jython for example) or sys._getframe is not
-    # defined for arguments greater than 0 (IronPython).
-    try:
-        result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
-    except (AttributeError, ValueError):
-        pass
+    # defined for arguments greater than 0 (IronPython), or where the user has
+    # specified a particular module.
+    if module is None:
+        try:
+            module = _sys._getframe(1).f_globals.get('__name__', '__main__')
+        except (AttributeError, ValueError):
+            pass
+    if module is not None:
+        result.__module__ = module
 
     return result
 
index f1fb0112667b9541d938820bc13bcc53bec2106f..52ff256eb9438b526447282bd8b364e314ab39a5 100644 (file)
@@ -242,6 +242,10 @@ class TestNamedTuple(unittest.TestCase):
         ]:
             self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
 
+    def test_module_parameter(self):
+        NT = namedtuple('NT', ['x', 'y'], module=collections)
+        self.assertEqual(NT.__module__, collections)
+
     def test_instance(self):
         Point = namedtuple('Point', 'x y')
         p = Point(11, 22)
index b58822e24a8c97f2537895f0fe3457751a7b81dc..33c919ba3e420b86bd82ad123da575174501cc36 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -159,6 +159,8 @@ Library
 - Issue #10740: sqlite3 no longer implicitly commit an open transaction
   before DDL statements.
 
+- Issue #17941: Add a *module* parameter to collections.namedtuple().
+
 - Issue #22493: Inline flags now should be used only at the start of the
   regular expression.  Deprecation warning is emitted if uses them in the
   middle of the regular expression.