[Python-checkins] cpython: Add tests for _source to importable and exec'able.

raymond.hettinger python-checkins at python.org
Thu Mar 24 04:34:01 CET 2011


http://hg.python.org/cpython/rev/f09f7ab40ce6
changeset:   68889:f09f7ab40ce6
user:        Raymond Hettinger <python at rcn.com>
date:        Wed Mar 23 20:33:30 2011 -0700
summary:
  Add tests for _source to importable and exec'able.
Move __name__ back out of the template; the responsibility
for setting __name__ lies with the caller (which knows
something about the new namespace), not with the class
definition (which doesn't know about the namespace it is
being built in).

files:
  Lib/collections/__init__.py  |   7 ++--
  Lib/test/test_collections.py |  34 ++++++++++++++++++++++++
  2 files changed, 37 insertions(+), 4 deletions(-)


diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py
--- a/Lib/collections/__init__.py
+++ b/Lib/collections/__init__.py
@@ -234,8 +234,6 @@
 ################################################################################
 
 _class_template = '''\
-__name__ = 'namedtuple_{typename}'
-
 from builtins import property as _property, tuple as _tuple
 from operator import itemgetter as _itemgetter
 from collections import OrderedDict
@@ -353,8 +351,9 @@
                                for index, name in enumerate(field_names))
     )
 
-    # Execute the class definition string in a temporary namespace
-    namespace = {}
+    # Execute the template string in a temporary namespace and
+    # support tracing utilities by setting a value for frame.f_globals['__name__']
+    namespace = dict(__name__='namedtuple_%s' % typename)
     try:
         exec(class_definition, namespace)
     except SyntaxError as e:
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -1,6 +1,7 @@
 """Unit tests for collections.py."""
 
 import unittest, doctest, operator
+from test.support import TESTFN, forget, unlink
 import inspect
 from test import support
 from collections import namedtuple, Counter, OrderedDict, _count_elements
@@ -327,6 +328,39 @@
             pass
         self.assertEqual(repr(B(1)), 'B(x=1)')
 
+    def test_source(self):
+        # verify that _source can be run through exec()
+        tmp = namedtuple('Color', 'red green blue')
+        self.assertNotIn('Color', globals())
+        exec(tmp._source, globals())
+        self.assertIn('Color', globals())
+        c = Color(10, 20, 30)
+        self.assertEqual((c.red, c.green, c.blue), (10, 20, 30))
+        self.assertEqual(Color._fields, ('red', 'green', 'blue'))
+
+    def test_source_importable(self):
+        tmp = namedtuple('Color', 'hue sat val')
+
+        compiled = None
+        source = TESTFN + '.py'
+        with open(source, 'w') as f:
+            print(tmp._source, file=f)
+
+        if TESTFN in sys.modules:
+            del sys.modules[TESTFN]
+        try:
+            mod = __import__(TESTFN)
+            compiled = mod.__file__
+            Color = mod.Color
+            c = Color(10, 20, 30)
+            self.assertEqual((c.hue, c.sat, c.val), (10, 20, 30))
+            self.assertEqual(Color._fields, ('hue', 'sat', 'val'))
+        finally:
+            forget(TESTFN)
+            if compiled:
+                unlink(compiled)
+            unlink(source)
+
 
 ################################################################################
 ### Abstract Base Classes

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list