summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2012-05-11 18:48:41 (GMT)
committerBrett Cannon <brett@python.org>2012-05-11 18:48:41 (GMT)
commitc049952de76cbcd00e490e48445ed7a50d3dc83a (patch)
tree91d1ff6bffbb8d6c5b04a8bae6b53944eb078335 /Lib
parent0c59b039b86afa9f51c30f7d9f340d9c75984488 (diff)
downloadcpython-c049952de76cbcd00e490e48445ed7a50d3dc83a.zip
cpython-c049952de76cbcd00e490e48445ed7a50d3dc83a.tar.gz
cpython-c049952de76cbcd00e490e48445ed7a50d3dc83a.tar.bz2
Issue #13959: Have
importlib.abc.FileLoader.load_module()/get_filename() and importlib.machinery.ExtensionFileLoader.load_module() have their single argument be optional as the loader's constructor has all the ncessary information. This allows for the deprecation of imp.load_source()/load_compile()/load_package().
Diffstat (limited to 'Lib')
-rw-r--r--Lib/imp.py60
-rw-r--r--Lib/importlib/_bootstrap.py14
-rw-r--r--Lib/importlib/test/extension/test_loader.py20
-rw-r--r--Lib/importlib/test/source/test_file_loader.py35
-rw-r--r--Lib/test/test_imp.py19
-rw-r--r--Lib/test/test_tools.py8
6 files changed, 113 insertions, 43 deletions
diff --git a/Lib/imp.py b/Lib/imp.py
index f60f050..edef0be 100644
--- a/Lib/imp.py
+++ b/Lib/imp.py
@@ -24,8 +24,7 @@ import tokenize
import warnings
-# XXX "deprecate" once find_module(), load_module(), and get_suffixes() are
-# deprecated.
+# DEPRECATED
SEARCH_ERROR = 0
PY_SOURCE = 1
PY_COMPILED = 2
@@ -112,8 +111,11 @@ class _LoadSourceCompatibility(_HackedGetData, _bootstrap.SourceFileLoader):
"""Compatibility support for implementing load_source()."""
-# XXX deprecate after better API exposed in importlib
def load_source(name, pathname, file=None):
+ msg = ('imp.load_source() is deprecated; use '
+ 'importlib.machinery.SourceFileLoader(name, pathname).load_module()'
+ ' instead')
+ warnings.warn(msg, DeprecationWarning, 2)
return _LoadSourceCompatibility(name, pathname, file).load_module(name)
@@ -123,15 +125,22 @@ class _LoadCompiledCompatibility(_HackedGetData,
"""Compatibility support for implementing load_compiled()."""
-# XXX deprecate
def load_compiled(name, pathname, file=None):
+ msg = ('imp.load_compiled() is deprecated; use '
+ 'importlib.machinery.SourcelessFileLoader(name, pathname).'
+ 'load_module() instead ')
+ warnings.warn(msg, DeprecationWarning, 2)
return _LoadCompiledCompatibility(name, pathname, file).load_module(name)
-# XXX deprecate
def load_package(name, path):
+ msg = ('imp.load_package() is deprecated; use either '
+ 'importlib.machinery.SourceFileLoader() or '
+ 'importlib.machinery.SourcelessFileLoader() instead')
+ warnings.warn(msg, DeprecationWarning, 2)
if os.path.isdir(path):
- extensions = machinery.SOURCE_SUFFIXES[:] + [machinery.BYTECODE_SUFFIXES]
+ extensions = (machinery.SOURCE_SUFFIXES[:] +
+ machinery.BYTECODE_SUFFIXES[:])
for extension in extensions:
path = os.path.join(path, '__init__'+extension)
if os.path.exists(path):
@@ -149,26 +158,29 @@ def load_module(name, file, filename, details):
"""
suffix, mode, type_ = details
- if mode and (not mode.startswith(('r', 'U')) or '+' in mode):
- raise ValueError('invalid file open mode {!r}'.format(mode))
- elif file is None and type_ in {PY_SOURCE, PY_COMPILED}:
- msg = 'file object required for import (type code {})'.format(type_)
- raise ValueError(msg)
- elif type_ == PY_SOURCE:
- return load_source(name, filename, file)
- elif type_ == PY_COMPILED:
- return load_compiled(name, filename, file)
- elif type_ == PKG_DIRECTORY:
- return load_package(name, filename)
- elif type_ == C_BUILTIN:
- return init_builtin(name)
- elif type_ == PY_FROZEN:
- return init_frozen(name)
- else:
- msg = "Don't know how to import {} (type code {}".format(name, type_)
- raise ImportError(msg, name=name)
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore')
+ if mode and (not mode.startswith(('r', 'U')) or '+' in mode):
+ raise ValueError('invalid file open mode {!r}'.format(mode))
+ elif file is None and type_ in {PY_SOURCE, PY_COMPILED}:
+ msg = 'file object required for import (type code {})'.format(type_)
+ raise ValueError(msg)
+ elif type_ == PY_SOURCE:
+ return load_source(name, filename, file)
+ elif type_ == PY_COMPILED:
+ return load_compiled(name, filename, file)
+ elif type_ == PKG_DIRECTORY:
+ return load_package(name, filename)
+ elif type_ == C_BUILTIN:
+ return init_builtin(name)
+ elif type_ == PY_FROZEN:
+ return init_frozen(name)
+ else:
+ msg = "Don't know how to import {} (type code {}".format(name, type_)
+ raise ImportError(msg, name=name)
+# XXX deprecate
def find_module(name, path=None):
"""Search for a module.
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index ce23043..41b96a9 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -282,8 +282,10 @@ def _check_name(method):
compared against. If the comparison fails then ImportError is raised.
"""
- def _check_name_wrapper(self, name, *args, **kwargs):
- if self.name != name:
+ def _check_name_wrapper(self, name=None, *args, **kwargs):
+ if name is None:
+ name = self.name
+ elif self.name != name:
raise ImportError("loader cannot handle %s" % name, name=name)
return method(self, name, *args, **kwargs)
_wrap(_check_name_wrapper, method)
@@ -614,6 +616,11 @@ class FileLoader:
self.path = path
@_check_name
+ def load_module(self, fullname):
+ """Load a module from a file."""
+ return super().load_module(fullname)
+
+ @_check_name
def get_filename(self, fullname):
"""Return the path to the source file as found by the finder."""
return self.path
@@ -713,17 +720,14 @@ class ExtensionFileLoader:
del sys.modules[fullname]
raise
- @_check_name
def is_package(self, fullname):
"""Return False as an extension module can never be a package."""
return False
- @_check_name
def get_code(self, fullname):
"""Return None as an extension module cannot create a code object."""
return None
- @_check_name
def get_source(self, fullname):
"""Return None as extension modules have no source code."""
return None
diff --git a/Lib/importlib/test/extension/test_loader.py b/Lib/importlib/test/extension/test_loader.py
index ab2b686..4f486ce 100644
--- a/Lib/importlib/test/extension/test_loader.py
+++ b/Lib/importlib/test/extension/test_loader.py
@@ -1,4 +1,4 @@
-from importlib import _bootstrap
+from importlib import machinery
from . import util as ext_util
from .. import abc
from .. import util
@@ -11,10 +11,20 @@ class LoaderTests(abc.LoaderTests):
"""Test load_module() for extension modules."""
+ def setUp(self):
+ self.loader = machinery.ExtensionFileLoader(ext_util.NAME,
+ ext_util.FILEPATH)
+
def load_module(self, fullname):
- loader = _bootstrap.ExtensionFileLoader(ext_util.NAME,
- ext_util.FILEPATH)
- return loader.load_module(fullname)
+ return self.loader.load_module(fullname)
+
+ def test_load_module_API(self):
+ # Test the default argument for load_module().
+ self.loader.load_module()
+ self.loader.load_module(None)
+ with self.assertRaises(ImportError):
+ self.load_module('XXX')
+
def test_module(self):
with util.uncache(ext_util.NAME):
@@ -25,7 +35,7 @@ class LoaderTests(abc.LoaderTests):
self.assertEqual(getattr(module, attr), value)
self.assertTrue(ext_util.NAME in sys.modules)
self.assertTrue(isinstance(module.__loader__,
- _bootstrap.ExtensionFileLoader))
+ machinery.ExtensionFileLoader))
def test_package(self):
# Extensions are not found in packages.
diff --git a/Lib/importlib/test/source/test_file_loader.py b/Lib/importlib/test/source/test_file_loader.py
index c4c7545..ffa0c24 100644
--- a/Lib/importlib/test/source/test_file_loader.py
+++ b/Lib/importlib/test/source/test_file_loader.py
@@ -1,5 +1,6 @@
from ... import _bootstrap
import importlib
+import importlib.abc
from .. import abc
from .. import util
from . import util as source_util
@@ -24,6 +25,40 @@ class SimpleTest(unittest.TestCase):
"""
+ def test_load_module_API(self):
+ # If fullname is not specified that assume self.name is desired.
+ class TesterMixin(importlib.abc.Loader):
+ def load_module(self, fullname): return fullname
+
+ class Tester(importlib.abc.FileLoader, TesterMixin):
+ def get_code(self, _): pass
+ def get_source(self, _): pass
+ def is_package(self, _): pass
+
+ name = 'mod_name'
+ loader = Tester(name, 'some_path')
+ self.assertEqual(name, loader.load_module())
+ self.assertEqual(name, loader.load_module(None))
+ self.assertEqual(name, loader.load_module(name))
+ with self.assertRaises(ImportError):
+ loader.load_module(loader.name + 'XXX')
+
+ def test_get_filename_API(self):
+ # If fullname is not set then assume self.path is desired.
+ class Tester(importlib.abc.FileLoader):
+ def get_code(self, _): pass
+ def get_source(self, _): pass
+ def is_package(self, _): pass
+
+ path = 'some_path'
+ name = 'some_name'
+ loader = Tester(name, path)
+ self.assertEqual(path, loader.get_filename(name))
+ self.assertEqual(path, loader.get_filename())
+ self.assertEqual(path, loader.get_filename(None))
+ with self.assertRaises(ImportError):
+ loader.get_filename(name + 'XXX')
+
# [basic]
def test_module(self):
with source_util.create_modules('_temp') as mapping:
diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py
index 5b285fc..3f419b7 100644
--- a/Lib/test/test_imp.py
+++ b/Lib/test/test_imp.py
@@ -1,11 +1,12 @@
import imp
+import importlib
import os
import os.path
import shutil
import sys
-import unittest
from test import support
-import importlib
+import unittest
+import warnings
class LockTests(unittest.TestCase):
@@ -154,18 +155,24 @@ class ImportTests(unittest.TestCase):
mod = imp.load_module(temp_mod_name, file, filename, info)
self.assertEqual(mod.a, 1)
- mod = imp.load_source(temp_mod_name, temp_mod_name + '.py')
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore')
+ mod = imp.load_source(temp_mod_name, temp_mod_name + '.py')
self.assertEqual(mod.a, 1)
- mod = imp.load_compiled(
- temp_mod_name, imp.cache_from_source(temp_mod_name + '.py'))
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore')
+ mod = imp.load_compiled(
+ temp_mod_name, imp.cache_from_source(temp_mod_name + '.py'))
self.assertEqual(mod.a, 1)
if not os.path.exists(test_package_name):
os.mkdir(test_package_name)
with open(init_file_name, 'w') as file:
file.write('b = 2\n')
- package = imp.load_package(test_package_name, test_package_name)
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore')
+ package = imp.load_package(test_package_name, test_package_name)
self.assertEqual(package.b, 2)
finally:
del sys.path[0]
diff --git a/Lib/test/test_tools.py b/Lib/test/test_tools.py
index bc2672d..cbe6d80 100644
--- a/Lib/test/test_tools.py
+++ b/Lib/test/test_tools.py
@@ -6,7 +6,7 @@ Tools directory of a Python checkout or tarball, such as reindent.py.
import os
import sys
-import imp
+import importlib.machinery
import unittest
from unittest import mock
import sysconfig
@@ -80,7 +80,8 @@ class PdepsTests(unittest.TestCase):
@classmethod
def setUpClass(self):
path = os.path.join(scriptsdir, 'pdeps.py')
- self.pdeps = imp.load_source('pdeps', path)
+ loader = importlib.machinery.SourceFileLoader('pdeps', path)
+ self.pdeps = loader.load_module()
@classmethod
def tearDownClass(self):
@@ -104,7 +105,8 @@ class Gprof2htmlTests(unittest.TestCase):
def setUp(self):
path = os.path.join(scriptsdir, 'gprof2html.py')
- self.gprof = imp.load_source('gprof2html', path)
+ loader = importlib.machinery.SourceFileLoader('gprof2html', path)
+ self.gprof = loader.load_module()
oldargv = sys.argv
def fixup():
sys.argv = oldargv