Kaydet (Commit) f6d3e8ea authored tarafından Raymond Hettinger's avatar Raymond Hettinger

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).
üst 5d43cff6
...@@ -234,8 +234,6 @@ class OrderedDict(dict): ...@@ -234,8 +234,6 @@ class OrderedDict(dict):
################################################################################ ################################################################################
_class_template = '''\ _class_template = '''\
__name__ = 'namedtuple_{typename}'
from builtins import property as _property, tuple as _tuple from builtins import property as _property, tuple as _tuple
from operator import itemgetter as _itemgetter from operator import itemgetter as _itemgetter
from collections import OrderedDict from collections import OrderedDict
...@@ -353,8 +351,9 @@ def namedtuple(typename, field_names, verbose=False, rename=False): ...@@ -353,8 +351,9 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
for index, name in enumerate(field_names)) for index, name in enumerate(field_names))
) )
# Execute the class definition string in a temporary namespace # Execute the template string in a temporary namespace and
namespace = {} # support tracing utilities by setting a value for frame.f_globals['__name__']
namespace = dict(__name__='namedtuple_%s' % typename)
try: try:
exec(class_definition, namespace) exec(class_definition, namespace)
except SyntaxError as e: except SyntaxError as e:
......
"""Unit tests for collections.py.""" """Unit tests for collections.py."""
import unittest, doctest, operator import unittest, doctest, operator
from test.support import TESTFN, forget, unlink
import inspect import inspect
from test import support from test import support
from collections import namedtuple, Counter, OrderedDict, _count_elements from collections import namedtuple, Counter, OrderedDict, _count_elements
...@@ -327,6 +328,39 @@ class TestNamedTuple(unittest.TestCase): ...@@ -327,6 +328,39 @@ class TestNamedTuple(unittest.TestCase):
pass pass
self.assertEqual(repr(B(1)), 'B(x=1)') 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 ### Abstract Base Classes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment