summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2013-05-26 20:45:10 (GMT)
committerBrett Cannon <brett@python.org>2013-05-26 20:45:10 (GMT)
commit9ffe85e1e86bc6718f105f2ab9833ef80f691367 (patch)
tree236b5acf6fa3186bc46d74b64d8f68fc6c5dd097 /Lib
parent1256f1f438503530d9dcf2790f7ff5b4a08d85f3 (diff)
downloadcpython-9ffe85e1e86bc6718f105f2ab9833ef80f691367.zip
cpython-9ffe85e1e86bc6718f105f2ab9833ef80f691367.tar.gz
cpython-9ffe85e1e86bc6718f105f2ab9833ef80f691367.tar.bz2
Move importlib.abc.SourceLoader.source_to_code() to InspectLoader.
While the previous location was fine, it makes more sense to have the method higher up in the inheritance chain, especially at a point where get_source() is defined which is the earliest source_to_code() could programmatically be used in the inheritance tree in importlib.abc.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/importlib/abc.py7
-rw-r--r--Lib/test/test_importlib/test_abc.py50
2 files changed, 54 insertions, 3 deletions
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index 7752ac4..cdcf244 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -165,6 +165,13 @@ class InspectLoader(Loader):
"""
raise ImportError
+ def source_to_code(self, data, path='<string>'):
+ """Compile 'data' into a code object.
+
+ The 'data' argument can be anything that compile() can handle. The'path'
+ argument should be where the data was retrieved (when applicable)."""
+ return compile(data, path, 'exec', dont_inherit=True)
+
_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter,
machinery.ExtensionFileLoader)
diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py
index 8d3d51e..5d1661c 100644
--- a/Lib/test/test_importlib/test_abc.py
+++ b/Lib/test/test_importlib/test_abc.py
@@ -12,7 +12,7 @@ import unittest
from . import util
-##### Inheritance
+##### Inheritance ##############################################################
class InheritanceTests:
"""Test that the specified class is a subclass/superclass of the expected
@@ -81,7 +81,7 @@ class SourceLoader(InheritanceTests, unittest.TestCase):
subclasses = [machinery.SourceFileLoader]
-##### Default semantics
+##### Default return values ####################################################
class MetaPathFinderSubclass(abc.MetaPathFinder):
def find_module(self, fullname, path):
@@ -205,7 +205,50 @@ class ExecutionLoaderDefaultsTests(unittest.TestCase):
self.ins.get_filename('blah')
-##### SourceLoader
+##### InspectLoader concrete methods ###########################################
+class InspectLoaderConcreteMethodTests(unittest.TestCase):
+
+ def source_to_module(self, data, path=None):
+ """Help with source_to_code() tests."""
+ module = imp.new_module('blah')
+ loader = InspectLoaderSubclass()
+ if path is None:
+ code = loader.source_to_code(data)
+ else:
+ code = loader.source_to_code(data, path)
+ exec(code, module.__dict__)
+ return module
+
+ def test_source_to_code_source(self):
+ # Since compile() can handle strings, so should source_to_code().
+ source = 'attr = 42'
+ module = self.source_to_module(source)
+ self.assertTrue(hasattr(module, 'attr'))
+ self.assertEqual(module.attr, 42)
+
+ def test_source_to_code_bytes(self):
+ # Since compile() can handle bytes, so should source_to_code().
+ source = b'attr = 42'
+ module = self.source_to_module(source)
+ self.assertTrue(hasattr(module, 'attr'))
+ self.assertEqual(module.attr, 42)
+
+ def test_source_to_code_path(self):
+ # Specifying a path should set it for the code object.
+ path = 'path/to/somewhere'
+ loader = InspectLoaderSubclass()
+ code = loader.source_to_code('', path)
+ self.assertEqual(code.co_filename, path)
+
+ def test_source_to_code_no_path(self):
+ # Not setting a path should still work and be set to <string> since that
+ # is a pre-existing practice as a default to compile().
+ loader = InspectLoaderSubclass()
+ code = loader.source_to_code('')
+ self.assertEqual(code.co_filename, '<string>')
+
+
+##### SourceLoader concrete methods ############################################
class SourceOnlyLoaderMock(abc.SourceLoader):
# Globals that should be defined for all modules.
@@ -498,5 +541,6 @@ class SourceLoaderGetSourceTests(unittest.TestCase):
self.assertEqual(mock.get_source(name), expect)
+
if __name__ == '__main__':
unittest.main()