[Python-checkins] r53330 - sandbox/trunk/import_in_py/importer.py sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/mock_importer.py sandbox/trunk/import_in_py/mock_importlib.py sandbox/trunk/import_in_py/test_importer.py sandbox/trunk/import_in_py/test_importlib.py
brett.cannon
python-checkins at python.org
Tue Jan 9 23:45:07 CET 2007
Author: brett.cannon
Date: Tue Jan 9 23:45:05 2007
New Revision: 53330
Added:
sandbox/trunk/import_in_py/importlib.py
- copied unchanged from r53322, sandbox/trunk/import_in_py/importer.py
sandbox/trunk/import_in_py/mock_importlib.py
- copied, changed from r53280, sandbox/trunk/import_in_py/mock_importer.py
sandbox/trunk/import_in_py/test_importlib.py
- copied, changed from r53280, sandbox/trunk/import_in_py/test_importer.py
Removed:
sandbox/trunk/import_in_py/importer.py
sandbox/trunk/import_in_py/mock_importer.py
sandbox/trunk/import_in_py/test_importer.py
Log:
Rename the module importlib.
Deleted: /sandbox/trunk/import_in_py/importer.py
==============================================================================
--- /sandbox/trunk/import_in_py/importer.py Tue Jan 9 23:45:05 2007
+++ (empty file)
@@ -1,902 +0,0 @@
-"""Implementation of Python's import machinery in Python source code.
-
-The Import class implements the semantics of import. This means that an
-instance of this class can be called to properly check sys.modules,
-sys.meta_path, sys.path, etc. to import the requested module.
-
-The importing of built-in, frozen, extension, .py, and .pyc files are all
-handled by implementing importers and loaders as specified by PEP 302. This
-leads to the ability to easily control imports based on the type of module.
-There is also a clear distinction between how the module is stored and how it
-is formatted (e.g., a Python source file does not require it be stored as a
-file on a filesystem).
-
-To help with the distinction between how a module is stored compared to its
-format the idea of handlers is introduced. A handler implements a specific
-interface while specifying the type of module it handles (usually by the what
-one would expect as a file extension if the module was on a filesystem). This
-allows a PEP 302 importer/loader to represent how a module is stored while the
-handler deals with how the module is formatted.
-
-A handler is expected to implement the handle_code method only. The handler
-for Python source and bytecode modules goes farther and defines an extensive
-interface that is designed so that alternatives on module formatting can be
-supported easily without needing to write a new importer/loader. The Python
-source and bytecode handler also expects loaders to define a more extensive
-interface to allow for different backend stores (e.g., databases) to use the
-handler without modification. All of this helps with code reuse and possible
-errors from the complicated relationship between Python source and bytecode
-modules.
-
-
-====================
-References on import
-====================
-* Language reference
- http://docs.python.org/ref/import.html
-* __import__ function
- http://docs.python.org/lib/built-in-funcs.html
-* Packages
- http://www.python.org/doc/essays/packages.html
-* PEP 235: Import on Case-Insensitive Platforms
- http://www.python.org/dev/peps/pep-0235
-* PEP 275: Import Modules from Zip Archives
- http://www.python.org/dev/peps/pep-0273
-* PEP 302: New Import Hooks
- http://www.python.org/dev/peps/pep-0302/
-* PEP 328: Imports: Multi-line and Absolute/Relative
- http://www.python.org/dev/peps/pep-0328
-
-============
-Known Issues
-============
-* runpy ('-m' command-line option for Python) does not work.
- + Requires get_code to be implemented for loaders.
- + Uses pkgutil.get_loader which fakes a loader if __loader__ is not defined.
- + New loaders do define __loader__ but not get_code, and thus dies on an
- AttributeError.
- + Possible fix
- - Implement optional interface for loaders.
- - Do not have new loaders set __loader__.
- * Might happen because of security issues.
-* warnings and stack level.
- + Affected tests
- - test___all__
- - test_imageop
- + 'warnings' assumes that the import code does not show up in the call
- stack.
- + Because import now implemented in Python, import does show up in the
- call stack.
- + Trick of specifying going back in the call stack two levels so warning
- shows up in the caller will cause the warning no longer holds true.
- + Possible fixes
- - Special module deprecation function.
- - Code in warnings.warn to handle special import case.
- - Flag on warnings.warn that warning is for an import and ignore stack
- level argument.
- * Could also infer from type of warning.
-* test_pkg
- + Old-style test that compares output.
- + Setting of __loader__ leads to different output.
-
-"""
-from __future__ import with_statement
-
-# Built-in modules.
-import imp
-import sys
-import marshal
-# Not built-in.
-import errno
-import os
-import contextlib
-import warnings
-
-
-def _set__import__():
- """Set __import__ to an instance of Import."""
- global original__import__
- original__import__ = __import__
- __builtins__['__import__'] = Import()
-
-def _reset__import__():
- """Set __import__ back to the original implementation (assumes
- _set__import__ was called previously)."""
- __builtins__['__import__'] = original__import__
-
-def _w_long(x):
- """Convert a 32-bit integer to little-endian.
-
- XXX Temporary until marshal's long functions are exposed.
-
- """
- bytes = []
- bytes.append(x & 0xFF)
- bytes.append((x >> 8) & 0xFF)
- bytes.append((x >> 16) & 0xFF)
- bytes.append((x >> 24) & 0xFF)
- return ''.join(chr(x) for x in bytes)
-
-def _r_long(bytes):
- """Convert 4 bytes in little-endian to an integer.
-
- XXX Temporary until marshal's long function are exposed.
-
- """
- x = ord(bytes[0])
- x |= ord(bytes[1]) << 8
- x |= ord(bytes[2]) << 16
- x |= ord(bytes[3]) << 24
- return x
-
-def _case_ok(directory, file_name):
- """Verify that file_name (as found in 'directory') has the proper case.
-
- The path is assumed to already exist.
-
- XXX Temporary until imp's case_ok function can be exposed.
-
- XXX Better to roll this into a single function some how so that existence
- check can be part of case check and thus cut down on stat calls?
-
- """
- # If platform is not case-sensitive *or* the environment variable
- # PYTHONCASEOK is defined, then os.path.exists already handled the case by
- # either doing a case-sensitive check or from the user saying he does not
- # want case-sensitivity, respectively.
- if sys.platform not in ('win32', 'mac', 'riscos', 'darwin', 'cygwin',
- 'os2emx') or os.environ.get('PYTHONCASEOK'):
- return True
- directory_contents = os.listdir(directory)
- if file_name in directory_contents:
- return True
- else:
- return False
-
-
-class _BuiltinFrozenBaseImporter(object):
-
- """Base class for meta_path importers for built-in and frozen modules.
-
- Subclasses must provide the _find and _load methods. The methods are
- expected to be defined on the subclass itself and not on an instance.
-
- """
-
- @classmethod
- def find_module(cls, fullname, path=None):
- """See if a built-in or frozen module can be imported based on the
- specified name."""
- if cls._find(fullname):
- return cls
- else:
- return None
-
- @classmethod
- def load_module(cls, fullname):
- """Load a built-in or frozen module.
-
- 'imp' code for loading a built-in or frozen module handles the setting
- of a module in sys.modules before initializing the module. This means
- that we do not need to perform that step as outlined by PEP 302.
-
- """
- try:
- return sys.modules[fullname]
- except KeyError:
- mod = cls._load(fullname)
- if not mod:
- raise ImportError("expected built-in module not loaded")
- return mod
-
-
-class BuiltinImporter(_BuiltinFrozenBaseImporter):
-
- """sys.meta_path class for importing built-in modules.
-
- XXX Possible optimization is to bail out in find_module() if 'path' is set
- to a value.
-
- """
-
- _find = imp.is_builtin
- _load = imp.init_builtin
-
-
-class FrozenImporter(_BuiltinFrozenBaseImporter):
-
- """sys.meta_path class for importing frozen modules."""
-
- _find = imp.is_frozen
- _load = imp.init_frozen
-
-
-class FileSystemFactory(object):
-
- """Factory function for sys.path_hooks for directory entries on sys.path.
-
- The path to be handled, if it is a filesystem directory, is used to
- initialize a new FileSystemImporter for that path entry. An instantiated
- object stores various handlers that are to be used to decide if the path
- entry contains the module to be imported.
-
- XXX Possible optimization would be to get the directory's contents and make
- sure that only handlers for the files in the directory are given to the
- returned importer. This would kill the ability to add a new module into
- the directory during run-time that is a new type of file, though.
-
- """
-
- def __init__(self, *handlers):
- """Store handlers to be used in attempting to import.
-
- The order that the handlers are specified are the order in which
- the handlers will be passed on to any instantiated importers.
-
- """
- self.handlers = handlers
-
- def __call__(self, path_entry):
- """If path_entry is a directory, return an importer object for it, else
- raise ImportError.
-
- Both relative and absolute paths are accepted (the former because of
- interactive interpreter usage).
-
- """
- absolute_path = os.path.abspath(path_entry)
- if os.path.isdir(absolute_path):
- return FileSystemImporter(absolute_path, *self.handlers)
- else:
- raise ImportError("can only handle directories")
-
-
-class FileSystemImporter(object):
-
- """Importer for the filesystem using the passed-in handlers."""
-
- def __init__(self, path_entry, *handlers):
- """Store the path this importer handles and the handlers to use.
-
- The order of the handlers determines precedence of file types.
-
- """
- self.path_entry = path_entry
- self.handlers = handlers
- self.loader = FileSystemLoader
-
- def find_module(self, fullname, path=None):
- """Determine if this path entry can handle this import, and if so,
- return a loader for the module on this path entry based on the handlers
- registered.
-
- If the module's name is dotted then only search for the trailing
- module's name on the path entry. An importer is already created
- for each directory in the __path__ attribute for a package.
-
- """
- tail_module = fullname.rsplit('.', 1)[-1]
- package_directory = os.path.join(self.path_entry, tail_module)
- for handler in self.handlers:
- for file_ext in handler.handles:
- # XXX Backwards-incompatible to use anything but .py/.pyc
- # files for __init__?
- init_filename = '__init__' + file_ext
- package_init = os.path.join(package_directory, init_filename)
- # Check if it is a package with an __init__ file.
- if (os.path.isfile(package_init) and
- _case_ok(self.path_entry, tail_module) and
- _case_ok(package_directory, init_filename)):
- return self.loader(package_init, handler, package_directory)
- # See if it is a module.
- file_name = tail_module + file_ext
- file_path = os.path.join(self.path_entry, file_name)
- if (os.path.isfile(file_path) and
- _case_ok(self.path_entry, file_name)):
- return self.loader(file_path, handler)
- else:
- # Raise a warning if it matches a directory w/o an __init__ file.
- if (os.path.isdir(package_directory) and
- _case_ok(self.path_entry, tail_module)):
- warnings.warn("Not importing directory %s: missing __init__.py"
- % package_directory,
- ImportWarning)
- return None
-
-
-class FileSystemLoader(object):
-
- """Loader for the filesystem.
-
- It implements the needed API for the PyPycHandler.
-
- """
-
- def __init__(self, file_path, handler, package=None):
- """Store the path to the file to use for the import and the handler to
- use along with whether this is a package (this does not include modules
- within a package)."""
- self.file_path = file_path
- self.handler = handler
- self.package = package
-
- def load_module(self, fullname):
- """Load the module from self.path using self.handler.
-
- The handler is expected to implement a handle_code method that will
- deal with initializing the module passed to it.
-
- """
- try:
- module = self.handler.handle_code(self, fullname,
- self.file_path, self.package)
- # Don't leave any partially initialised modules behind.
- except:
- if fullname in sys.modules:
- del sys.modules[fullname]
- raise
- else:
- return module
-
- def mod_time(self, path):
- """Return the modification time for the specified path as an integer.
-
- This method is required as part of the interface needed for
- PyPycHandler.
-
- """
- return int(os.stat(path).st_mtime)
-
- def split_path(self, path):
- """Split the specified path into a base path and the type of the
- path.
-
- This method is required for PyPycHandler.
-
- """
- return os.path.splitext(path)
-
- def create_path(self, base_path, type_, must_exist=False):
- """Create a new path based on a base path and requested path type.
-
- If must_exist is True, the path must already exist in order to return a
- path instead of None.
-
- This method is required for PyPycHandler.
-
- """
- path = base_path + type_
- if must_exist:
- path = path if os.path.exists(path) else None
- return path
-
- def read_data(self, path, binary=False):
- """Open the path and return the data read from it in the specified
- format.
-
- This method is required for PyPycHandler.
-
- """
- with open(path, 'rb' if binary else 'U') as data_file:
- data = data_file.read()
- return data
-
- def write_data(self, data, path, binary=False):
- """Write data to a specified path as either binary or textual data.
-
- If the path cannot be accessed, then exit silently.
-
- This method is required for PyPycHandler.
-
- """
- try:
- with open(path, 'wb' if binary else 'w') as data_file:
- data_file.write(data)
- except IOError, exc:
- if exc.errno == errno.EACCES:
- pass
- else:
- raise
-
-
-class PyPycHandler(object):
-
- """Handle reading Python bytecode/source with writing out of bytecode as
- needed.
-
- The handle_code method is the key entry point for this class.
-
- """
-
- def __init__(self, source_handles=None, bytecode_handles=None):
- """Specify the file types for source and bytecode to be handled by this
- handler and set 'handles' appropriately as tuples (empty tuples are
- acceptable).
-
- Not specifying handles will lead to reasonable defaults being used.
-
- """
- if source_handles is None:
- self.source_handles = ('.py',)
- else:
- self.source_handles = source_handles
- if bytecode_handles is None:
- self.bytecode_handles = ('.pyc',) if __debug__ else ('.pyo',)
- else:
- self.bytecode_handles = bytecode_handles
- self.handles = self.bytecode_handles + self.source_handles
-
- def new_module(self, name):
- """Retun a new module to be initialized (with __name__ set)."""
- return imp.new_module(name)
-
- def parse_pyc(self, data):
- """Split data into magic number, timestamp, and bytecode."""
- return data[:4], _r_long(data[4:8]), data[8:]
-
- def check_magic(self, magic):
- """Check whether the magic number is correct or not for the current
- running interpreter."""
- return imp.get_magic() == magic
-
- def code_from_bytecode(self, bytecode):
- """Create a code object from bytecode.
-
- ValueError is expected to be raised if a code object can not be created
- from the bytecode.
-
- """
- return marshal.loads(bytecode)
-
- def code_from_source(self, source, path):
- """Create a code object from source."""
- return compile(source, str(path), 'exec')
-
- def create_pyc(self, bytecode, timestamp):
- """Create data to be written out for a .pyc file."""
- data = imp.get_magic()
- data += _w_long(timestamp)
- data += marshal.dumps(bytecode)
- return data
-
- def handle_code(self, loader, mod_name, path, package=None):
- """Handle creating a new module object for the module mod_name that is
- to be initialized with data from 'path' and, if a package, has a
- package location of 'package'.
-
- The loader needs to implement several methods in order to this handler
- to be able to load needed data. A key point with some of these methods
- is the idea of opaque code objects which are not directly touched by
- the handler but are passed back to the loader so as to allow for a way
- to keep state:
-
- * split_path(path)
- Take in an opaque path object and split it into a base path and a
- string representing the type of the path (which should be in the
- 'handles' attribute of the handler).
- * create_path(base_path, type_, must_exist)
- Create an opaque path object from a base path and the type of path
- that is desired. If must_exist is True the path must already
- exist.
- * mod_time(path)
- Return the last modification time for a path as an integer.
- * read_data(path, binary)
- Read the data from the specified path. 'binary' is a boolean that
- flags whether the data should be read as binary data or text data.
- * write_data(data, path, binary)
- Write data to a path. 'binary' flags whether the data should be
- written as binary or textual data.
-
- """
- source_path = None
- source_timestamp = None
- bytecode_path = None
- module = sys.modules.get(mod_name)
- if module is None:
- module = self.new_module(mod_name)
- sys.modules[mod_name] = module
- # __file__, __path__, and __loader__ *must* be set on the module before
- # any code is executed by the import. __name__ is set by new_module.
- module.__loader__ = loader
- module.__file__ = path
- if package is not None:
- module.__path__ = [package]
- base_path, type_ = loader.split_path(path)
- if type_ in self.bytecode_handles:
- # Attempt to use bytecode.
- bytecode_path = path
- source_path = None
- pyc_data = loader.read_data(path, True)
- magic, pyc_timestamp, bytecode = self.parse_pyc(pyc_data)
- # Try to find corresponding source code.
- for source_handle in self.source_handles:
- source_path = loader.create_path(base_path, source_handle, True)
- if source_path:
- break
- try:
- # Verify that the magic number is valid.
- if not self.check_magic(magic):
- raise ImportError("bad magic number")
- # Verify that the bytecode is not stale.
- if source_path:
- source_timestamp = loader.mod_time(source_path)
- if pyc_timestamp < source_timestamp:
- raise ImportError("bytcode is stale")
- # Bytecode is valid.
- module.__file__ = path
- try:
- code_object = self.code_from_bytecode(bytecode)
- except ValueError:
- # Since bad bytecode halts the import entirely having the
- # source code is useless. Use this fact to signal that
- # the ImportError being raised should propagate.
- source_path = None
- raise ImportError('Non-code object in %s' %
- str(bytecode_path))
- exec code_object in module.__dict__
- return module
- except ImportError:
- # No source code to use to recover from bad bytecode.
- if not source_path:
- raise
- if type_ in self.source_handles:
- # Asked directly to handle source code.
- source_path = path
- # Get the source code.
- source = loader.read_data(source_path, False)
- module.__file__ = source_path
- code = self.code_from_source(source, source_path)
- # See if there is a corresponding path to bytecode.
- if not bytecode_path:
- if self.bytecode_handles:
- bytecode_handle = self.bytecode_handles[0]
- bytecode_path = loader.create_path(base_path,
- bytecode_handle)
- source_timestamp = loader.mod_time(source_path)
- # If there is a possible path to bytecode, generate .pyc file.
- if bytecode_path:
- if not source_timestamp:
- source_timestamp = loader.mod_time(source_path)
- pyc = self.create_pyc(code, source_timestamp)
- loader.write_data(pyc, bytecode_path, True)
- exec code in module.__dict__
- return module
-
-
-class ExtensionFileHandler(object):
-
- """A handler for loading extension modules."""
-
- def __init__(self):
- """Set 'handles'."""
- self.handles = tuple(suffix[0] for suffix in imp.get_suffixes()
- if suffix[2] == imp.C_EXTENSION)
-
- def handle_code(self, loader, mod_name, extension_path, package=None):
- """Import an extension module."""
- module = imp.load_dynamic(mod_name, extension_path)
- if package is not None:
- module.__path__ = [package]
- return module
-
-
-class ImportLockContext(object):
-
- """Context manager for the import lock."""
-
- def __enter__(self):
- """Acquire the import lock."""
- imp.acquire_lock()
-
- def __exit__(self, exc_type, exc_value, exc_traceback):
- """Release the import lock regardless of any raised exceptions."""
- imp.release_lock()
-
-
-class Import(object):
-
- """Class that implements the __import__ interface.
-
- Backwards compatibility is maintained by extending sys.meta_path
- interally (for handling built-in and frozen modules) and providing a
- default path hooks entry (for extension modules, .py, and .pyc
- files). Both are controlled during instance initialization.
-
- """
-
- def __init__(self, default_path_hook=None,
- extended_meta_path=(BuiltinImporter, FrozenImporter)):
- """Store a default path hook entry and a sequence to internally extend
- sys.meta_path by."""
- self.extended_meta_path = extended_meta_path
- self.default_path_hook = default_path_hook
- if not self.default_path_hook:
- # Create a handler to deal with extension modules, .py, and .pyc
- # files. Built-in and frozen modules are handled by sys.meta_path
- # entries.
- handlers = ExtensionFileHandler(), PyPycHandler()
- self.default_path_hook = FileSystemFactory(*handlers)
-
- def _search_meta_path(self, name, path=None):
- """Check the importers on sys.meta_path for a loader along with the
- extended meta path sequence stored within this instance.
-
- The extended sys.meta_path entries are searched after the entries on
- sys.meta_path.
-
- """
- for entry in (tuple(sys.meta_path) + self.extended_meta_path):
- loader = entry.find_module(name, path)
- if loader:
- return loader
- else:
- raise ImportError("No module named %s" % name)
-
- def _sys_path_importer(self, path_entry):
- """Return the importer for the specified path, from
- sys.path_importer_cache if possible.
-
- If None is stored in sys.path_importer_cache then use the default path
- hook.
-
- """
- try:
- # See if an importer is cached.
- importer = sys.path_importer_cache[path_entry]
- # If None was returned, use default importer factory.
- if importer is None:
- # XXX Would it break backwards-compatibility to set the importer
- # in sys.path_importer_cache, replacing the None entry?
- return self.default_path_hook(path_entry)
- else:
- return importer
- except KeyError:
- # No cached importer found; try to get a new one from
- # sys.path_hooks.
- for importer_factory in sys.path_hooks:
- try:
- importer = importer_factory(path_entry)
- # XXX Going to break backwards-compatibility by storing
- # an instance of the default importer? None still handled
- # properly so shouldn't be any different than some other
- # importer being stored.
- sys.path_importer_cache[path_entry] = importer
- return importer
- except ImportError:
- continue
- else:
- # No importer factory on sys.path_hooks works; use the default
- # importer factory.
- try:
- importer = self.default_path_hook(path_entry)
- sys.path_importer_cache[path_entry] = importer
- return importer
- except ImportError:
- sys.path_importer_cache[path_entry] = None
- raise ImportError("no importer found for %s" % path_entry)
-
- def _search_std_path(self, name, path=None):
- """Check sys.path or 'path' (depending if 'path' is set) for the
- named module and return its loader."""
- if path:
- search_paths = path
- else:
- search_paths = sys.path
- for entry in search_paths:
- try:
- importer = self._sys_path_importer(entry)
- except ImportError:
- continue
- loader = importer.find_module(name)
- if loader:
- return loader
- else:
- raise ImportError("No module found named %s" % name)
-
- def _import_module(self, name, path=None):
- """Import the specified module with no handling of parent modules.
-
- If None is set for a value in sys.modules (to signify that a relative
- import was attempted and failed) then ImportError is raised.
-
- """
- if name in sys.modules:
- value = sys.modules[name]
- if value is None:
- raise ImportError("relative import redirect")
- else:
- return value
- try:
- # Attempt to find a loader on sys.meta_path.
- loader = self._search_meta_path(name, path)
- except ImportError:
- # sys.meta_path search failed. Attempt to find a loader on
- # sys.path. If this fails then module cannot be found.
- loader = self._search_std_path(name, path)
- # A loader was found. It is the loader's responsibility to have put an
- # entry in sys.modules.
- return loader.load_module(name)
-
- def _import_full_module(self, name):
- """Import a module along with its parent modules and set into
- sys.modules."""
- # Import the module (importing its parent modules first).
- name_parts = name.split('.')
- current_name_parts = []
- parent_module = None
- path_list = None
- # XXX Any perk to being optimistic and assuming parent modules were
- # imported already, and thus search in the reverse order for the first module
- # to be found?
- for name_part in name_parts:
- current_name_parts.append(name_part)
- # Recreating name every time around the loop is sub-optimal, but
- # does away with base case of a non-dotted name.
- current_name = ".".join(current_name_parts)
- if parent_module:
- try:
- path_list = parent_module.__path__
- except AttributeError:
- pass
- module = self._import_module(current_name, path_list)
- if parent_module:
- setattr(parent_module, name_part, module)
- parent_module = module
-
- def _classic_resolve_name(self, name, caller_name, caller_is_package):
- """Return the absolute name of the module specified in 'name' as based
- on the name of the caller and whether it is a package."""
- if caller_is_package:
- base_name = caller_name
- else:
- if '.' not in caller_name:
- # Importing in a top-level module, so name is already absolute.
- return name
- else:
- base_name = caller_name.rsplit('.', 1)[0]
- return base_name + '.' + name
-
- def _resolve_name(self, name, caller_name, caller_is_package, level):
- """Return the absolute name of the module specified by 'name' based on
- where the module is being imported and the requested change in dotted
- name level.
-
- Absolute imports always take the form of ``from <name> import ...``.
- This means that the number of leading dots in '<name>' becomes 'level'
- and the rest of '<name>' becomes 'name'. This leads to the possibility
- that 'name' is the empty string, representing the current package.
-
- """
- if caller_is_package:
- level -= 1
- if caller_name.count('.') < level:
- raise ImportError("attempted relative import beyond top-level "
- "pacakge")
- base_name = caller_name.rsplit('.', level)[0]
- if name:
- return base_name + '.' + name
- else:
- return base_name
-
- def _return_module(self, absolute_name, relative_name, fromlist):
- """Return the proper module based on what module was requested (and its
- absolute module name), who is
- requesting it, and whether any speicific attributes were specified.
-
- The semantics of this method revolve around 'fromlist'. When it is
- empty, the module up to the first dot is to be returned. When the
- module being requested is an absolute name this is simple (and
- relative_name is an empty string). But if the requested module was
- a relative import (as signaled by relative_name having a non-false
- value), then the name up to the first dot in the relative name resolved
- to an absolute name is to be returned.
-
- When fromlist is not empty and the module being imported is a package,
- then the values
- in fromlist need to be checked for. If a value is not a pre-existing
- attribute a relative import is attempted. If it fails then suppressed
- the failure silently.
-
- """
- if not fromlist:
- if relative_name:
- absolute_base = absolute_name.rpartition(relative_name)[0]
- relative_head = relative_name.split('.', 1)[0]
- to_return = absolute_base + relative_head
- else:
- to_return = absolute_name.split('.', 1)[0]
- return sys.modules[to_return]
- # When fromlist is not empty, return the actual module specified in
- # the import.
- else:
- module = sys.modules[absolute_name]
- if hasattr(module, '__path__') and hasattr(module, '__name__'):
- # When fromlist has a value and the imported module is a
- # package, then if a name in fromlist is not found as an
- # attribute on module, try a relative import to find it.
- # Failure is fine and the exception is suppressed.
- check_for = list(fromlist)
- if '*' in check_for and hasattr(module, '__all__'):
- check_for.extend(module.__all__)
- for item in check_for:
- if item == '*':
- continue
- if not hasattr(module, item):
- resolved_name = self._resolve_name(item, module.__name__,
- True, 1)
- try:
- self._import_full_module(resolved_name)
- except ImportError:
- pass
- return module
-
- def __call__(self, name, globals={}, locals={}, fromlist=[], level=-1):
- """Import a module.
-
- The 'name' argument is the name of the module to be imported (e.g.,
- 'foo' in ``import foo`` or ``from foo import ...``).
-
- 'globals' and 'locals' are the global and local namespace dictionaries
- of the module where the import statement appears. 'globals' is used to
- introspect the __path__ and __name__ attributes of the module making
- the call. 'local's is ignored.
-
- 'fromlist' lists any specific objects that are to eventually be put
- into the namespace (e.g., ``from for.bar import baz`` would have 'baz'
- in the fromlist, and this includes '*'). An entry of '*' will lead to
- a check for __all__ being defined on the module. If it is defined then
- the values in __all__ will be checked to make sure that all values are
- attributes on the module, attempting a module import relative to 'name'
- to set that attribute.
-
- When 'name' is a dotted name, there are two different situations to
- consider for the return value. One is when the fromlist is empty.
- In this situation the import statement imports and returns the name up
- to the first dot. All subsequent names are imported but set as
- attributes as needed on parent modules. When fromlist is not empty
- then the module represented by the full dotted name is returned.
-
- 'level' represents how to handle possible relative imports. If 'level'
- is set to -1 then the module name could be either relative or absolute.
- A value of 0 is for absolute module names., Any positive value
- represents the number of dots listed in the relative import statement
- (e.g. has a value of 2 for ``from .. import foo``).
-
- """
- if not name and level < 1:
- raise ValueError("Empty module name")
- is_pkg = True if '__path__' in globals else False
- caller_name = globals.get('__name__')
- with ImportLockContext():
- if level and caller_name:
- # Handle the classic style of import: relative first, then
- # absolute.
- if level == -1:
- relative_name = self._classic_resolve_name(name, caller_name,
- is_pkg)
- imported_name = relative_name
- try:
- # Try a relative import.
- self._import_full_module(imported_name)
- except ImportError:
- # If the relative import fails (or is redirected), try an
- # absolute import.
- imported_name = name
- self._import_full_module(imported_name)
- # Redirection entry for resolved relative name to instead
- # redirect to the absolute import.
- sys.modules[relative_name] = None
- # If using absolute imports with a relative path, only attempt with
- # the fully-resolved module name.
- else:
- imported_name = self._resolve_name(name, caller_name, is_pkg,
- level)
- # This call will also handle setting the attribute on the
- # package.
- self._import_full_module(imported_name)
- # Absolute module import of a top-level module.
- else:
- imported_name = name
- self._import_full_module(name)
- relative_name = '' if imported_name == name else name
- return self._return_module(imported_name, relative_name, fromlist)
Deleted: /sandbox/trunk/import_in_py/mock_importer.py
==============================================================================
--- /sandbox/trunk/import_in_py/mock_importer.py Tue Jan 9 23:45:05 2007
+++ (empty file)
@@ -1,278 +0,0 @@
-import sys
-import marshal
-import imp
-from test import test_support
-from importer import _w_long
-
-def log_call(method):
- """Log method calls to self.log."""
- def log_and_call(self, *args, **kwargs):
- self.log.append(method.__name__)
- return method(self, *args, **kwargs)
- return log_and_call
-
-class MockModule(object):
-
- """A mock module."""
-
- def __init__(self, name=None, file_path=None, pkg_list=None, __all__=None):
- if name is not None:
- self.__name__ = name
- if file_path is not None:
- self.__file__ = file_path
- if pkg_list is not None:
- self.__path__ = pkg_list
- if __all__ is not None:
- self.__all__ = __all__
-
-
-class MockHandler(object):
-
- """Mock a handler."""
-
- def __init__(self, *handles):
- self.handles = handles
-
- def handle_code(self, loader, mod_name, path, package=None):
- """Mock implementation of a handler.
-
- An object that can have arbitrary attributes attached to it must be
- returned.
-
- """
- module = sys.modules.get(mod_name)
- if module is None:
- module = self
- sys.modules[mod_name] = self
- try:
- module.loader = loader
- module.module_name = mod_name
- module.path = path
- module.package = package
- except AttributeError:
- pass
- return module
-
-class MockPyPycLoader(object):
-
- """Mock loader object for testing importer.PyPycHandler.
-
- Opaque path objects are two-item tuple consisting of a string representing
- the base path and another string representing the type.
-
- """
-
- def __init__(self, file_path, handler, package=None):
- """Store arguments passed into the constructor for verification."""
- self.file_path = file_path
- self.handler = handler
- self.package = package
-
- @classmethod
- def setup(cls, good_magic=True, good_timestamp=True, pyc_exists=True,
- py_exists=True, good_bytecode=True):
- """Set up the mock loader based on possible scenarios of source and
- bytecode combinations/issues."""
- self = cls('<setup>', '<setup>')
- self.module_name = 'test_module'
- self.py_ext = "source" if py_exists else None
- self.pyc_ext = "bytecode" if pyc_exists else None
- self.base_path = "base path"
- self.py_path = (self.base_path, self.py_ext)
- self.pyc_path = (self.base_path, self.pyc_ext)
- self.modification_time = 1
- # Needed for read_data on source path.
- self.attr_name = 'test_attr'
- self.attr_value = None
- self.source = "%s = %s" % (self.attr_name, self.attr_value)
- code_object = compile(self.source, "<mock loader>", 'exec')
- bytecode = marshal.dumps(code_object)
- if good_magic:
- pyc = imp.get_magic()
- else:
- magic = imp.get_magic()
- pyc = magic[:3] + chr(ord(magic[3]) - 1)
- if good_timestamp:
- pyc += _w_long(self.modification_time)
- else:
- pyc += _w_long(self.modification_time - 1)
- # Needed for read_data on .pyc path.
- if good_bytecode:
- self.pyc = pyc + bytecode
- else:
- self.pyc = pyc + "asd4asfasd4ae4fds"
- self.log = []
- return self
-
- def _create_handler(self, handler):
- if self.py_ext:
- py_ext = (self.py_ext,)
- else:
- py_ext = tuple()
- if self.pyc_ext:
- pyc_ext = (self.pyc_ext,)
- else:
- pyc_ext = tuple()
- return handler(py_ext, pyc_ext)
-
- def _handle_py(self, handler, package=None):
- args = [self, self.module_name, self.py_path]
- if package is not None:
- args.append(package)
- return handler.handle_code(*args)
-
- def _handle_pyc(self, handler, package=None):
- args = [self, self.module_name, self.pyc_path]
- if package is not None:
- args.append(package)
- return handler.handle_code(*args)
-
- def _verify_module(self, module, test_metadata=True):
- if not hasattr(module, 'test_attr'):
- raise test_support.TestFailed("test_attr attribute missing")
- if not module.test_attr is None:
- raise test_support.TestFailed("test_attr not set to None")
- if test_metadata:
- assert module.__name__ == self.module_name
- assert module.__loader__ == self
- assert self.base_path in module.__file__
- assert (self.pyc_ext in module.__file__ or
- self.py_ext in module.__file__)
-
- return True
-
- def load_module(self, fullname):
- """Return what the method was called with."""
- return fullname
-
- @log_call
- def split_path(self, path):
- """'path' should be a two-item tuple, so just return it since the
- caller expects two items back."""
- assert (path[0] == self.base_path and
- path[1] in (self.py_ext, self.pyc_ext))
-
- return path
-
- @log_call
- def create_path(self, base, type_, must_exist=False):
- """Create a tuple from 'base' and type_."""
- assert base == self.base_path
- assert type_ in (self.py_ext, self.pyc_ext)
-
- if must_exist:
- if type_ not in (self.py_ext, self.pyc_ext):
- return None
- else:
- return (base, type_)
- else:
- return (base, type_)
-
- @log_call
- def mod_time(self, path):
- """Consider self.modification_time the baseline modification time."""
- assert path[0] == self.base_path
- assert path[1] == self.py_ext
-
- return self.modification_time
-
- @log_call
- def read_data(self, path, binary):
- """Return the proper source or binary data based on the path."""
- assert path[0] == self.base_path
- assert path[1] in (self.py_ext, self.pyc_ext)
-
- if binary:
- assert self.pyc_ext and path[1] == self.pyc_ext
- return self.pyc
- else:
- assert self.py_ext and path[1] == self.py_ext
- return self.source
-
- @log_call
- def write_data(self, data, path, binary):
- """Should only be requested to write to a bytecode path."""
- assert path[0] == self.base_path
- assert self.pyc_ext
- assert path[1] == self.pyc_ext, "%s != %s" % (path[1], self.pyc_ext)
- assert binary
- assert data[:4] == imp.get_magic()
- assert _w_long(self.modification_time) == data[4:8]
- module = MockModule(self.module_name)
- code = marshal.loads(data[8:])
- exec code in module.__dict__
- assert self._verify_module(module, False)
-
- return None
-
-
-# Mock Importers (with optional path_hooks support).
-
-class ErrorImporter(object):
-
- """Mock importer to have a guaranteed error point."""
-
- def find_module(self, fullname, path=None):
- self.find_request = fullname, path
- raise ImportError
-
- @classmethod
- def set_on_sys_path(cls):
- error_entry = '<error>'
- sys.path.append(error_entry)
- ins = cls()
- sys.path_importer_cache[error_entry] = ins
- return ins
-
-
-class PassImporter(object):
-
- """Mock importer that always pass on importing a module."""
-
- def __call__(self, path_entry):
- """Always pass when asked to create an importer."""
- raise ImportError
-
- def find_module(self, fullname, path=None):
- self.find_request = fullname, path
- return None
-
- @classmethod
- def set_on_sys_path(cls):
- pass_entry = '<pass>'
- sys.path.append(pass_entry)
- ins = cls()
- sys.path_importer_cache[pass_entry] = ins
- return ins
-
-
-class SucceedImporter(object):
-
- """Mock importer that always succeed by returning 'self'."""
-
- def __init__(self):
- self.path_entries = []
- self.loaded_modules = []
-
- def __call__(self, path_entry):
- self.path_entries.append(path_entry)
- return self
-
- def find_module(self, fullname, path=None):
- self.find_request = fullname, path
- return self
-
- def load_module(self, fullname):
- self.load_request = fullname
- module = MockModule(fullname, '<succeed importer>')
- self.loaded_modules.append(module)
- sys.modules[fullname] = module
- return module
-
- @classmethod
- def set_on_sys_path(cls):
- succeed_entry = '<success>'
- sys.path.append(succeed_entry)
- ins = cls()
- sys.path_importer_cache[succeed_entry] = ins
- return ins
Copied: sandbox/trunk/import_in_py/mock_importlib.py (from r53280, sandbox/trunk/import_in_py/mock_importer.py)
==============================================================================
--- sandbox/trunk/import_in_py/mock_importer.py (original)
+++ sandbox/trunk/import_in_py/mock_importlib.py Tue Jan 9 23:45:05 2007
@@ -2,7 +2,7 @@
import marshal
import imp
from test import test_support
-from importer import _w_long
+from importlib import _w_long
def log_call(method):
"""Log method calls to self.log."""
Deleted: /sandbox/trunk/import_in_py/test_importer.py
==============================================================================
--- /sandbox/trunk/import_in_py/test_importer.py Tue Jan 9 23:45:05 2007
+++ (empty file)
@@ -1,1525 +0,0 @@
-import importer
-
-import unittest
-from test import test_support
-import mock_importer
-
-import contextlib
-import imp
-import marshal
-import new
-import os
-import py_compile
-import shutil
-import StringIO
-import sys
-import tempfile
-import warnings
-
-
-class BuiltinFrozen_Tester(unittest.TestCase):
-
- """Common test cases for built-in and frozen modules.
-
- Expected attributes:
- * self.importer
- The meta_path importer to test.
- * self.module_name
- Name of a module that the importer can import.
- * self.bad_module_names
- Sequence of module names that cannot be imported.
-
- """
-
- def test_find_module_basic(self):
- # Make sure expected modules can be found.
- self.failUnless(self.importer.find_module(self.module_name))
-
- def test_find_module_failures(self):
- # Modules of the wrong type should not be found.
- for module_name in self.bad_module_names:
- self.failUnlessEqual(self.importer.find_module(module_name), None)
-
- def test_find_module_arg_count(self):
- # Cover proper number of arguments.
- self.failUnlessRaises(TypeError, self.importer.find_module)
- self.failUnlessRaises(TypeError, self.importer.find_module,
- self.module_name, None, None)
-
- def test_load_module_prev_import_check(self):
- # If a module is already in sys.modules it should be returned without
- # being re-initialized.
- self.failUnlessEqual(self.importer.load_module(self.module_name),
- sys.modules[self.module_name])
-
- def test_load_module_new_import(self):
- # Make sure importing of a module that was not done before works
- # properly.
- # Do not forget to put any removed module back into sys.modules!
- # Certain modules like 'sys' have some attributes that are set
- # only once during interpreter initialization and are never set
- # again afterwards.
- mod = None
- try:
- if self.module_name in sys.modules:
- mod = sys.modules[self.module_name]
- del sys.modules[self.module_name]
- loaded_module = self.importer.load_module(self.module_name)
- self.failUnlessEqual(self.module_name, loaded_module.__name__)
- finally:
- if mod:
- sys.modules[self.module_name] = mod
-
- def test_load_module_ImportError(self):
- self.failUnlessRaises(ImportError,
- self.importer.load_module,
- self.bad_module_names[0])
-
- def test_load_module_arg_count(self):
- self.failUnlessRaises(TypeError, self.importer.load_module)
- self.failUnlessRaises(TypeError, self.importer.load_module,
- self.module_name, None, None)
-
-
-class BuiltinImporterTests(BuiltinFrozen_Tester):
-
- """Test the built-in module importer."""
-
- importer = importer.BuiltinImporter
- module_name = 'sys'
- bad_module_names = ('tokenize', 'time', '__hello__')
-
-
-class FrozenImporterTests(BuiltinFrozen_Tester):
-
- """Test the frozen module importer.
-
- Python include the __hello__ and __phello__ frozen modules (as defined in
- Python/frozen.c). Both do output to the screen, though, which should be
- suppressed during testing.
-
- """
-
- importer = importer.FrozenImporter
- module_name = '__hello__'
- bad_module_names = ('tokenize', 'time', 'sys')
-
- def setUp(self):
- """Importing the testing frozen modules outputs to stdout. Redirect
- stdout to block that."""
- self._orig_stdout = sys.stdout
- sys.stdout = StringIO.StringIO()
-
- def tearDown(self):
- """Reset stdout to what it is by default."""
- sys.stdout = self._orig_stdout
-
-class FrozenPackageModuleTests(FrozenImporterTests):
-
- """Tests the frozen module import for modules in packages."""
-
- module_name = '__phello__.spam'
-
-class FrozenPackageInitTests(FrozenImporterTests):
-
- """Tests the frozen module import for package __init__ modules."""
-
- module_name = '__phello__'
-
-
-class TestPyPycFiles(unittest.TestCase):
-
- """Base class to help in generating a fresh source and bytecode file.
-
- Structure of created files:
- * directory/
- + py_path [module_name + py_ext]
- + pyc_path [module_name +pyc_ext]
-
- """
-
- def setUp(self, faked_names=True):
- """Generate the path to a temporary file to test with.
-
- If faked_names is true then all names are non-standard compared to
- normal Python files.
-
- """
- # Set needed info for file paths.
- if faked_names:
- self.module_name = '<test_module>'
- self.py_ext = '.source'
- self.pyc_ext = '.bytecode'
- else:
- self.module_name = '_test_module'
- self.py_ext = '.py'
- self.pyc_ext = '.pyc' if __debug__ else '.pyo'
- try:
- del sys.modules[self.module_name]
- except KeyError:
- pass
- self.directory = tempfile.gettempdir()
- self.test_attr = ('test_attr', None)
- self.py_path = os.path.join(self.directory,
- self.module_name+self.py_ext)
- self.pyc_path = os.path.join(self.directory,
- self.module_name+self.pyc_ext)
- # Create source file.
- self.source = '%s = %r' % self.test_attr
- with open(self.py_path, 'w') as py_file:
- py_file.write(self.source)
- # Create bytecode file.
- py_compile.compile(self.py_path, self.pyc_path, 'exec')
- code = compile(self.source, self.pyc_path, 'exec')
- self.bytecode = marshal.dumps(code)
- sys.path.insert(0, self.directory)
-
- def tearDown(self):
- """If the temporary path was used, make sure to clean up."""
- if self.directory in sys.path:
- sys.path.remove(self.directory)
- if os.path.exists(self.py_path):
- os.remove(self.py_path)
- if os.path.exists(self.pyc_path):
- os.remove(self.pyc_path)
-
- def verify_module(self, module, file_path=None):
- """Verify that the module is correct."""
- if file_path:
- self.failUnlessEqual(module.__name__, self.module_name)
- self.failUnlessEqual(module.__file__, file_path)
- self.failUnless(hasattr(module, self.test_attr[0]))
- self.failUnlessEqual(getattr(module, self.test_attr[0]),
- self.test_attr[1])
-
-
-class TestPyPycPackages(TestPyPycFiles):
-
- """Create a testing package.
-
- Structure of created files (on top of files created in superclasses):
- * self.directory/
- + top_level_module_path [top_level_module_name + py_ext]
- + pkg_path/ [pkg_name]
- - pkg_init_path [ '__init__' + py_ext]
- - pkg_module_path [module_name + py_ext]
- - sub_pkg_path/ [sub_pkg_name]
- * sub_pkg_init_path ['__init__' + py_ext]
- * sub_pkg_module_path [module_name + py_ext]
-
- """
-
- def setUp(self, faked_names=True):
- TestPyPycFiles.setUp(self, faked_names)
- self.top_level_module_name = 'top_level_' + self.module_name
- self.top_level_module_path = os.path.join(self.directory,
- self.top_level_module_name+self.py_ext)
- with open(self.top_level_module_path, 'w') as top_level_file:
- top_level_file.write(self.source)
- if faked_names:
- self.pkg_name = '<test_pkg>'
- else:
- self.pkg_name = '_test_pkg'
- self.pkg_path = os.path.join(self.directory, self.pkg_name)
- try:
- os.mkdir(self.pkg_path)
- except OSError:
- self.tearDown()
- os.mkdir(self.pkg_path)
- self.pkg_init_path = os.path.join(self.pkg_path,
- '__init__'+self.py_ext)
- with open(self.pkg_init_path, 'w') as pkg_file:
- pkg_file.write(self.source)
- self.pkg_module_name = '.'.join([self.pkg_name, self.module_name])
- self.pkg_module_path = os.path.join(self.pkg_path,
- self.module_name+self.py_ext)
- with open(self.pkg_module_path, 'w') as module_file:
- module_file.write(self.source)
- self.sub_pkg_tail_name = 'sub_pkg'
- self.sub_pkg_name = '.'.join([self.pkg_name, self.sub_pkg_tail_name])
- self.sub_pkg_path = os.path.join(self.pkg_path, self.sub_pkg_tail_name)
- os.mkdir(self.sub_pkg_path)
- self.sub_pkg_init_path = os.path.join(self.sub_pkg_path,
- '__init__'+self.py_ext)
- with open(self.sub_pkg_init_path, 'w') as subpkg_file:
- subpkg_file.write(self.source)
- self.sub_pkg_module_name = '.'.join([self.sub_pkg_name,
- self.module_name])
- self.sub_pkg_module_path = os.path.join(self.sub_pkg_path,
- self.module_name+self.py_ext)
- with open(self.sub_pkg_module_path, 'w') as submodule_file:
- submodule_file.write(self.source)
-
- def tearDown(self):
- TestPyPycFiles.tearDown(self)
- os.remove(self.top_level_module_path)
- pyc_path = (os.path.splitext(self.top_level_module_path)[0] +
- self.pyc_ext)
- if os.path.exists(pyc_path):
- os.remove(pyc_path)
- shutil.rmtree(self.pkg_path)
-
- def verify_package(self, module, actual_name=None):
- self.failUnless(hasattr(module, self.test_attr[0]))
- self.failUnlessEqual(getattr(module, self.test_attr[0]),
- self.test_attr[1])
- if module.__name__ == self.pkg_name:
- self.failUnlessEqual(module.__file__, self.pkg_init_path)
- self.failUnlessEqual(module.__path__, [self.pkg_path])
- # Module in top-level package.
- if actual_name and self.pkg_module_name in actual_name:
- self.failUnless(hasattr(module, self.module_name))
- sub_module = getattr(module, self.module_name)
- self.failUnlessEqual(sub_module.__name__, self.pkg_module_name)
- self.failUnlessEqual(sub_module.__file__, self.pkg_module_path)
- self.verify_module(sub_module)
- # Package within top-level package.
- if actual_name and self.sub_pkg_name in actual_name:
- self.failUnless(hasattr(module, self.sub_pkg_tail_name))
- sub_pkg = getattr(module, self.sub_pkg_tail_name)
- self.failUnlessEqual(sub_pkg.__name__, self.sub_pkg_name)
- self.failUnlessEqual(sub_pkg.__file__, self.sub_pkg_init_path)
- self.failUnlessEqual(sub_pkg.__path__, [self.sub_pkg_path])
- self.verify_module(sub_pkg)
- if actual_name == self.sub_pkg_module_name:
- self.failUnless(hasattr(sub_pkg, self.module_name))
- sub_module = getattr(sub_pkg, self.module_name)
- self.failUnlessEqual(sub_module.__name__,
- self.sub_pkg_module_name)
- self.failUnlessEqual(sub_module.__file__,
- self.sub_pkg_module_path)
- self.verify_module(sub_module)
- if module.__name__ == self.pkg_module_name:
- self.failUnlessEqual(module.__file__, self.pkg_module_path)
-
-
-class FileSystemFactoryTests(unittest.TestCase):
-
- """Test the filesystem path_hooks factory function."""
-
- def setUp(self):
- mock_handler = mock_importer.MockHandler('.X')
- self.factory = importer.FileSystemFactory(mock_handler)
-
- def test_absolute_path_accepted(self):
- # Passing in an absolute path to a directory should be accepted.
- importer_ = self.factory(os.path.abspath(os.getcwd()))
- self.failUnless(isinstance(importer_, importer.FileSystemImporter))
-
- def test_relative_path_accepted(self):
- # Passing in a relative directory path should be accepted.
- importer_ = self.factory('')
- self.failUnless(isinstance(importer_, importer.FileSystemImporter))
-
- def test_bad_directory(self):
- # Should raise ImportError when used on a non-existing directory.
- self.failUnlessRaises(ImportError, self.factory, 'sdadfasdfsdfsadfsdf')
-
- def test_file(self):
- # Passing in a file should raise ImportError.
- with open(test_support.TESTFN, 'w') as test_file:
- test_file.write('for testing FileSystemFactory')
- try:
- self.failUnlessRaises(ImportError, self.factory,
- test_support.TESTFN)
- finally:
- os.remove(test_support.TESTFN)
-
-
-class FileSystemImporterTests(TestPyPycPackages):
-
- """Test the filesystem importer."""
-
- def setUp(self):
- """Create a basic importer."""
- TestPyPycPackages.setUp(self)
- self.handler = mock_importer.MockHandler(self.py_ext)
- self.importer = importer.FileSystemImporter(self.directory,
- self.handler)
- self.importer.loader = mock_importer.MockPyPycLoader
-
- def test_module_case_sensitivity(self):
- # Case-sensitivity should always matter as long as PYTHONCASEOK is not
- # set.
- name_len = len(self.top_level_module_name)
- bad_case_name = (self.top_level_module_name[:name_len/2].upper() +
- self.top_level_module_name[name_len/2:].lower())
- env_guard = test_support.EnvironmentVarGuard()
- env_guard.unset('PYTHONCASEOK')
- with env_guard:
- self.failUnless(not self.importer.find_module(bad_case_name))
- if sys.platform not in ('win32', 'mac', 'darwin', 'cygwin', 'os2emx',
- 'riscos'):
- return
- env_guard = test_support.EnvironmentVarGuard()
- env_guard.set('PYTHONCASEOK', '1')
- with env_guard:
- assert os.environ['PYTHONCASEOK']
- self.failUnless(self.importer.find_module(bad_case_name))
-
- def test_package_case_sensitivity(self):
- # Case-sensitivity should always matter as long as PYTHONCASEOK is not
- # set.
- name_len = len(self.pkg_name)
- bad_case_name = (self.pkg_name[:name_len/2].upper() +
- self.pkg_name[name_len/2:].lower())
- bad_init_name = os.path.join(self.directory, self.pkg_name,
- '__INit__.py')
- env_guard = test_support.EnvironmentVarGuard()
- env_guard.unset('PYTHONCASEOK')
- with env_guard:
- self.failUnless(not self.importer.find_module(bad_case_name))
- os.unlink(self.pkg_init_path)
- with open(bad_init_name, 'w') as init_file:
- init_file.write('# Test case-sensitivity of imports.')
- self.failUnless(not self.importer.find_module(self.pkg_name))
- if sys.platform not in ('win32', 'mac', 'darwin', 'cygwin', 'os2emx',
- 'riscos'):
- return
- os.unlink(bad_init_name)
- with open(self.pkg_init_path, 'w') as init_file:
- init_file.write('# Used for testing import.')
- env_guard = test_support.EnvironmentVarGuard()
- env_guard.set('PYTHONCASEOK', '1')
- with env_guard:
- assert os.environ['PYTHONCASEOK']
- self.failUnless(self.importer.find_module(bad_case_name))
- with open(bad_init_name, 'w') as init_file:
- init_file.write('# Used to test case-insensitivity of import.')
- self.failUnless(self.importer.find_module(self.pkg_name))
-
- def test_find_module_single_handler(self):
- # Having a single handler should work without issue.
- loader = self.importer.find_module(self.module_name)
- self.failUnless(isinstance(loader, mock_importer.MockPyPycLoader))
- self.failUnlessEqual(loader.file_path, self.py_path)
- self.failUnless(isinstance(loader.handler, mock_importer.MockHandler))
- self.failUnless(loader.package is None)
-
- def test_find_module_cannot_find(self):
- # Should return None if it can't find the module.
- found = self.importer.find_module('gobbledeegook')
- self.failUnlessEqual(found, None)
-
- def test_find_module_multiple_handlers(self):
- # Modules should be found based on the order of the handlers.
- # mock
- first_handler = mock_importer.MockHandler('.not_found')
- second_handler = mock_importer.MockHandler(self.py_ext)
- fs_importer = importer.FileSystemImporter(self.directory,
- first_handler,
- second_handler)
- fs_importer.loader = mock_importer.MockPyPycLoader
- loader = fs_importer.find_module(self.module_name)
- self.failUnless(isinstance(loader, mock_importer.MockPyPycLoader))
- self.failUnlessEqual(loader.file_path, self.py_path)
- self.failUnless(isinstance(loader.handler, mock_importer.MockHandler))
-
- def test_pkg_discovery(self):
- # If a module name refers to a directory with an __init__ file it
- # should be recognized as a package.
- loader = self.importer.find_module(self.pkg_name)
- self.failUnless(isinstance(loader, mock_importer.MockPyPycLoader))
- self.failUnlessEqual(loader.file_path, self.pkg_init_path)
- self.failUnlessEqual(loader.handler, self.handler)
- self.failUnlessEqual(loader.package, self.pkg_path)
-
- def test_pkg_before_module(self):
- # Importing a name that is represented as both a package and a module
- # should give precedence to the package.
- module_path = os.path.join(self.directory, self.pkg_name + self.py_ext)
- with open(module_path, 'w') as test_file:
- test_file.write("blah")
- try:
- loader = self.importer.find_module(self.pkg_name)
- self.failUnlessEqual(loader.file_path, self.pkg_init_path)
- finally:
- os.remove(module_path)
-
- def test_directory_no_init_warning(self):
- # If a directory matches for a package name but lacks an __init__.py
- # file then raise ImportWarning.
- os.remove(self.pkg_init_path)
- with test_support.guard_warnings_filter():
- warnings.simplefilter('error', ImportWarning)
- self.failUnlessRaises(ImportWarning, self.importer.find_module,
- self.pkg_name)
-
-
-class FileSystemLoaderMockEnv(unittest.TestCase):
-
- """Helper for settting up mock environment for testing
- importer.FileSystemLoader."""
-
- def setUp(self):
- """Create a fresh loader per run."""
- mock_handler = mock_importer.MockHandler()
- self.test_path = "<test path>"
- self.pkg_path = "<test pkg>"
- self.pkg_init_path = os.path.join(self.pkg_path, '__init__.test')
- self.module_name = "test_module_name"
- self.pkg_name = "test_pkg"
- self.loader = importer.FileSystemLoader(self.test_path,
- mock_handler)
-
- def tearDown(self):
- """Make sure that there is no straggling modules in sys.modules."""
- try:
- del sys.modules[self.module_name]
- except KeyError:
- pass
- try:
- del sys.modules[self.pkg_name]
- except KeyError:
- pass
-
-
-class FileSystemLoaderBlackBoxTests(FileSystemLoaderMockEnv):
-
- """Test the filesystem loader's PEP 302 API compliance."""
-
- def test_load_module_fresh(self):
- # Test a basic module load where there is no sys.modules entry.
- new_module = self.loader.load_module(self.module_name)
- self.failUnlessEqual(new_module.loader, self.loader)
- self.failUnlessEqual(new_module.module_name, self.module_name)
- self.failUnlessEqual(new_module.path, self.test_path)
-
- def test_load_module_sys_modules(self):
- # Make sure that the loader returns the module from sys.modules if it
- # is there.
- sys.modules[self.module_name] = self.module_name
- loaded_module = self.loader.load_module(self.module_name)
- self.failUnless(loaded_module is self.module_name)
-
- def test_sys_module_cleared_on_error(self):
- # Any entry made for module into sys.modules should be cleared upon error.
- class RaiseErrorHandler(object):
- def handle_code(*args):
- raise ImportError
-
- loader = importer.FileSystemLoader(self.test_path, RaiseErrorHandler())
- try:
- loader.load_module(self.module_name)
- except ImportError:
- self.failUnless(self.module_name not in sys.modules)
-
- def test_package_init(self):
- # Test that instantiating a loader for handling a package works
- # properly.
- pkg_loader = importer.FileSystemLoader(self.pkg_init_path,
- mock_importer.MockHandler(),
- self.pkg_path)
- module = pkg_loader.load_module(self.pkg_name)
- self.failUnlessEqual(module.loader, pkg_loader)
- self.failUnlessEqual(module.path, self.pkg_init_path)
- self.failUnlessEqual(module.module_name, self.pkg_name)
- self.failUnlessEqual(module.package, self.pkg_path)
-
-
-class FileSystemLoaderWhiteBoxTests(FileSystemLoaderMockEnv):
-
- """Test the filesystem loader's non-PEP 302 API."""
-
- def setUp(self):
- """Set up a test file."""
- super(FileSystemLoaderWhiteBoxTests, self).setUp()
- self.directory = tempfile.gettempdir()
- self.file_ext = ".test"
- self.module_name = "import_test"
- self.file_name = self.module_name + self.file_ext
- self.file_path = os.path.join(self.directory, self.file_name)
- self.data = "File used for testing 'importer' module.\r\n42"
- with open(self.file_path, 'w') as test_file:
- test_file.write(self.data)
-
- def tearDown(self):
- """Delete the test file."""
- super(FileSystemLoaderWhiteBoxTests, self).tearDown()
- try:
- os.remove(self.file_path)
- except OSError:
- pass
-
- def test_mod_time(self):
- # Modification time for the passed-in path should match the file.
- true_mod_time = os.stat(self.file_path).st_mtime
- mod_time = self.loader.mod_time(self.file_path)
- self.failUnless(isinstance(mod_time, (int, long)))
- self.failUnlessEqual(mod_time, true_mod_time)
-
- def test_split_path(self):
- # Should split a path just like os.path.splitext().
- true_split_path = os.path.splitext(self.file_path)
- split_path = self.loader.split_path(self.file_path)
- self.failUnlessEqual(split_path, true_split_path)
-
- def test_create_path(self):
- # Should work like concatenating two strings.
- true_path = self.file_path
- path = self.loader.create_path(*self.loader.split_path(
- self.file_path))
- self.failUnlessEqual(path, true_path)
- self.failUnlessEqual(None, self.loader.create_path('sadfasdfd', 'aaa',
- True))
- self.failUnlessEqual('ab', self.loader.create_path('a', 'b'))
-
- def test_read_data(self):
- # Should be able to read a file.
- data = self.loader.read_data(self.file_path, False)
- self.failUnlessEqual(data, self.data.replace('\r', ''))
- data = self.loader.read_data(self.file_path, True)
- self.failUnlessEqual(data, self.data)
- test_text = '1\r\n2'
-
- def test_write_data(self):
- # Should be able to write a file.
- self.loader.write_data(self.data, self.file_path, True)
- with open(self.file_path, 'rb') as test_file:
- data = test_file.read()
- self.failUnlessEqual(data, self.data)
- # XXX How to test data written with/without 'b'?
-
-
-class PyPycHandlerSupportingMethodTests(TestPyPycFiles):
-
- """Test the py/pyc handler."""
-
- def setUp(self):
- TestPyPycFiles.setUp(self)
- self.handler = importer.PyPycHandler()
-
- def test_init(self):
- # Test __init__ usage.
- proper_bytecode_ext = '.pyc' if __debug__ else '.pyo'
- for source_ext, bytecode_ext in ((None, None), (('A',), None),
- (None, ('A',)), (('A',), ('B',))):
- handler = importer.PyPycHandler(source_ext, bytecode_ext)
- if source_ext is None:
- source = ('.py',)
- if bytecode_ext is None:
- bytecode = (proper_bytecode_ext,)
- self.failUnlessEqual(self.handler.source_handles, source)
- self.failUnlessEqual(self.handler.bytecode_handles, bytecode)
- self.failUnlessEqual(self.handler.handles, bytecode + source)
-
- def test_new_module(self):
- # Should return a new module with the proper value for __name__.
- module = self.handler.new_module('test')
- self.failUnlessEqual('test', module.__name__)
- self.failUnless(isinstance(module, importer.__class__))
-
- def test_parse_pyc(self):
- # Split up data from .pyc file for the magic number, timestamp,
- # and bytecode.
- with open(self.pyc_path, 'rb') as bytecode_file:
- pyc = bytecode_file.read()
- magic, timestamp, bytecode = self.handler.parse_pyc(pyc)
- code = marshal.loads(bytecode)
- module = mock_importer.MockModule(self.module_name, self.py_path)
- exec code in module.__dict__
- self.verify_module(module, self.py_path)
-
- def test_check_magic(self):
- # Compare a number against the magic number.
- magic_number = imp.get_magic()
- self.failUnless(self.handler.check_magic(magic_number))
- smaller_number = magic_number[:3] + chr(ord(magic_number[3]) - 1)
- self.failUnless(not self.handler.check_magic(smaller_number))
- larger_number = magic_number[:3] + chr(ord(magic_number[3]) + 1)
- self.failUnless(not self.handler.check_magic(larger_number))
-
- def test_code_from_bytecode(self):
- # Create a code object from bytecode; raises ValueError if code object
- # cannot be created.
- code_object = self.handler.code_from_bytecode(self.bytecode)
- module = mock_importer.MockModule(self.module_name)
- exec code_object in module.__dict__
- self.verify_module(module)
- self.failUnlessRaises(ValueError, self.handler.code_from_bytecode,
- "234lkjfdase4")
-
- def test_code_from_source(self):
- # Create a code object from source.
- code = self.handler.code_from_source(self.source, self.py_path)
- module = mock_importer.MockModule(self.module_name)
- exec code in module.__dict__
- self.verify_module(module)
-
- def test_create_pyc(self):
- # Test creating bytes for creating a .pyc file.
- bytecode = 'bytecode'
- timestamp = 42
- data = self.handler.create_pyc(bytecode, timestamp)
- self.failUnlessEqual(imp.get_magic(), data[:4])
- # XXX Using importer module's marshal long function.
- self.failUnlessEqual(timestamp, importer._r_long(data[4:8]))
- self.failUnlessEqual(marshal.dumps(bytecode), data[8:])
-
-
-class PyPycHandlerHandleCodeTests(unittest.TestCase):
-
- """Test PyPycHandler.handle_code().
-
- Various situations that must be handled (and thus tested):
- * Valid .pyc
- + .py exists [test_good_pyc_w_py]
- + No .py .
- * Invalid .pyc
- + Reasons it is invalid
- - Bad magic number.
- * With .py [test_bad_magic_w_py]
- * Without .py [test_bad_magic_no_py]
- - .pyc stale based on timestamp.
- * Requires .py [test_bad_timestamp_w_py]
- - Bytecode is malformed.
- * With .py [test_bad_bytecode_w_py]
- * Without .py [test_bad_bytecode_no_py]
- * No .pyc
- + Valid .py
- - Regenerate .pyc [test_py_w_pyc]
- - Do not create .pyc [test_py_no_pyc]
-
- """
-
- def test_good_pyc_w_py(self):
- # Test using a .pyc file that is valid and a .py file exists.
- loader = mock_importer.MockPyPycLoader.setup()
- handler = loader._create_handler(importer.PyPycHandler)
- module = loader._handle_pyc(handler)
- loader._verify_module(module)
- # Source code should never be read, only bytecode.
- self.failUnlessEqual(loader.log.count('read_data'), 1)
- # Bytecode should not be written.
- self.failUnless("write_data" not in loader.log)
-
- def test_bad_magic_no_py(self):
- # ImportError should be raised when a .pyc has a bad magic number and
- # there is no corresponding .py file.
- loader = mock_importer.MockPyPycLoader.setup(good_magic=False,
- py_exists=False)
- handler = loader._create_handler(importer.PyPycHandler)
- self.failUnlessRaises(ImportError, loader._handle_pyc, handler)
-
- def test_bad_bytecode_no_py(self):
- # A .pyc file with bad bytecode (but good magic number and timestamp)
- # should raise an ImportError.
- loader = mock_importer.MockPyPycLoader.setup(py_exists=False,
- good_bytecode=False)
- handler = loader._create_handler(importer.PyPycHandler)
- self.failUnlessRaises(ImportError, loader._handle_pyc, handler)
-
- def test_bad_magic_w_py(self):
- # A .pyc file with a bad magic number should lead to the .py file being
- # used to generate a new .pyc.
- loader = mock_importer.MockPyPycLoader.setup(good_magic=False)
- handler = loader._create_handler(importer.PyPycHandler)
- module = loader._handle_pyc(handler)
- loader._verify_module(module)
- self.failUnless("write_data" in loader.log)
-
- def test_bad_timestamp_w_py(self):
- # A .pyc file with a outdated timestamp should be regenerated.
- loader = mock_importer.MockPyPycLoader.setup(good_timestamp=False)
- handler = loader._create_handler(importer.PyPycHandler)
- module = loader._handle_pyc(handler)
- loader._verify_module(module)
- self.failUnless("write_data" in loader.log)
-
- def test_bad_bytecode_w_py(self):
- # Even when there is a valid .py file, if the .pyc file has bad bytecode
- # ImportError is raised.
- loader = mock_importer.MockPyPycLoader.setup(good_bytecode=False)
- handler = loader._create_handler(importer.PyPycHandler)
- self.failUnlessRaises(ImportError, loader._handle_pyc, handler)
-
- def test_py_no_pyc(self):
- # Test importing a .py file where no .pyc path is available.
- loader = mock_importer.MockPyPycLoader.setup(pyc_exists=False)
- handler = loader._create_handler(importer.PyPycHandler)
- module = loader._handle_py(handler)
- loader._verify_module(module)
- self.failUnless('write_data' not in loader.log)
- # No attempt should be made to read bytecode.
- self.failUnlessEqual(loader.log.count('read_data'), 1)
-
- def test_py_w_pyc(self):
- # Test importing a .py file and a .pyc path is available.
- loader = mock_importer.MockPyPycLoader.setup()
- handler = loader._create_handler(importer.PyPycHandler)
- module = loader._handle_py(handler)
- loader._verify_module(module)
- self.failUnless('write_data' in loader.log)
-
- def test_package_init(self):
- # Handling a package should set __path__ properly.
- loader = mock_importer.MockPyPycLoader.setup(pyc_exists=False)
- handler = loader._create_handler(importer.PyPycHandler)
- pkg_path = 'pkg path'
- module = loader._handle_py(handler, pkg_path)
- loader._verify_module(module)
- self.failUnlessEqual(module.__path__, [pkg_path])
-
- def test_sys_modules_used(self):
- # Handler should re-initialize an existing module in sys.modules
- # (needed for 'reload').
- loader = mock_importer.MockPyPycLoader.setup()
- original_module = mock_importer.MockModule(loader.module_name)
- original_value = -13
- assert loader.attr_value != original_value
- setattr(original_module, loader.attr_name, original_value)
- sys.modules[loader.module_name] = original_module
- handler = loader._create_handler(importer.PyPycHandler)
- new_module = loader._handle_pyc(handler)
- self.failUnless(new_module is original_module)
- self.failUnlessEqual(getattr(new_module, loader.attr_name),
- loader.attr_value)
-
-
-class ExtensionHandlerTests(unittest.TestCase):
-
- """Test that extension modules can be loaded."""
-
- def setUp(self):
- """Find an extension module to test against."""
- self.handler = importer.ExtensionFileHandler()
- for entry in sys.path:
- if not os.path.isdir(entry):
- continue
- ext_paths = [ext for ext in os.listdir(entry)
- if any(True for suffix in self.handler.handles
- if ext.endswith(suffix))]
- if ext_paths:
- break
- else:
- raise test_support.TestSkipped("not extension modules found")
- self.ext_path = os.path.join(entry, ext_paths[0])
- self.module_name = os.path.splitext(os.path.split(self.ext_path)[1])[0]
- self.loader = mock_importer.MockHandler()
-
- def test_handle_code(self):
- # Make sure an extension module can be loaded.
- module = self.handler.handle_code(self.loader, self.module_name,
- self.ext_path)
- # There should be at least one attribute that does not start with '_'.
- self.failUnless(any(True for attr in dir(module)
- if not attr.startswith('_')))
-
-
-class ImportHelper(unittest.TestCase):
-
- """Common helper methods for testing the Importer class."""
-
- def setUp(self):
- """Store a copy of the 'sys' attribute pertaining to imports."""
- # Don't backup sys.modules since dict is cached.
- # Don't clear sys.modules as it can wreak havoc
- # (e.g., losing __builtin__).
- self.old_sys_modules = sys.modules.copy()
- self.old_meta_path = sys.meta_path[:]
- sys.meta_path = []
- self.old_sys_path = sys.path[:]
- sys.path = []
- self.old_path_hooks = sys.path_hooks[:]
- sys.path_hooks = []
- self.old_path_importer_cache = sys.path_importer_cache.copy()
- sys.path_importer_cache.clear()
- self.default_importer = mock_importer.PassImporter()
- self.importer = importer.Import(self.default_importer, tuple())
-
- def tearDown(self):
- """Restore backup of import-related attributes in 'sys'."""
- sys.modules.clear()
- sys.modules.update(self.old_sys_modules)
- sys.meta_path = self.old_meta_path
- sys.path = self.old_sys_path
- sys.path_hooks = self.old_path_hooks
- sys.path_importer_cache = self.old_path_importer_cache
-
- def clear_sys_modules(*modules):
- for module in modules:
- try:
- del sys.modules[module]
- except KeyError:
- pass
-
-
-class ImportHelper2(ImportHelper):
-
- """Create mock modules."""
-
- def setUp(self):
- ImportHelper.setUp(self)
- self.parent_name = '<parent>'
- self.child_name = '<child>'
- self.full_child_name = '.'.join([self.parent_name, self.child_name])
- self.parent_module = mock_importer.MockModule(self.parent_name)
- self.child_module = mock_importer.MockModule(self.full_child_name)
- setattr(self.parent_module, self.child_name, self.child_module)
-
-class ImportNameResolutionTests(ImportHelper2):
-
- """Test the absolute name resolution for relative imports."""
-
- def test_classic_relative_import_in_package(self):
- # Importing from within a package's __init__ file should lead to a
- # resolved import name of the package name tacked on to the name of the
- # module being imported.
- resolved_name = self.importer._classic_resolve_name(self.child_name,
- self.parent_name,
- True)
- self.failUnlessEqual(resolved_name, self.full_child_name)
-
- def test_classic_relative_import_in_module(self):
- # Importing within a module in a package should lead to the importer's
- # module name being removed and replaced with the name of what is to be
- # imported.
- calling_from = self.parent_name + '.' + '<calling from>'
- resolved_name = self.importer._classic_resolve_name(self.child_name,
- calling_from,
- False)
- self.failUnlessEqual(resolved_name, self.full_child_name)
-
- def test_relative_import_in_package_for_a_module(self):
- # Trying to import a single level within a package within it's __init__
- # module should stay within the package.
- # ``from .child_name import ...`` in a package.
- resolved_name = self.importer._resolve_name(self.child_name,
- self.parent_name, True, 1)
- self.failUnlessEqual(resolved_name, self.full_child_name)
-
- def test_relative_import_in_module_for_a_module(self):
- # Importing from within a module in a package should try to import from
- # within the same directory as the module requesting the import.
- # ``from .child_name import ...`` in a package module.
- calling_from = self.parent_name + '.' + '<calling from>'
- resolved_name = self.importer._resolve_name(self.child_name,
- calling_from, False, 1)
- self.failUnlessEqual(resolved_name, self.full_child_name)
-
- def test_relative_import_deep_in_package(self):
- # Calling from a deep point in the package should still work.
- depth = 10
- name_extension = (str(x) for x in xrange(10))
- calling_from = self.parent_name + '.' + '.'.join(name_extension)
- resolved_name = self.importer._resolve_name(self.child_name,
- calling_from, False, depth)
- self.failUnlessEqual(resolved_name, self.full_child_name)
-
- def test_attempt_to_escape_out_of_package_init(self):
- # Attempting to go too high out of a package in its __init__ file
- # should raise ImportError.
- # ``from ..child_name import ...`` in a top-level package.
- self.failUnlessRaises(ImportError, self.importer._resolve_name,
- self.child_name, self.parent_name, True, 2)
-
- def test_attempt_to_escape_out_of_package_module(self):
- # Attempting to go too high in the package from a module should raise
- # ImportError.
- # ``from ..child_name import ...`` in a top-level package module.
- calling_from = self.parent_name + '.' + '<calling from>'
- self.failUnlessRaises(ImportError, self.importer._resolve_name,
- self.child_name, calling_from, False, 2)
-
- def test_relative_import_in_top_level(self):
- # Attempting a relative import in a top-level location should raise
- # ImportError.
- # ``from .child_name import ...`` outside of a package.
- self.failUnlessRaises(ImportError, self.importer._resolve_name,
- self.child_name, self.parent_name, False, 1)
-
- def test_relative_import_in_package_init(self):
- # ``from . import ...`` in a package.
- resolved_name = self.importer._resolve_name('', self.parent_name, True,
- 1)
- self.failUnlessEqual(resolved_name, self.parent_name)
-
- def test_relative_import_in_package_module(self):
- # ``from . import ...`` in a package module.
- resolved_name = self.importer._resolve_name('', self.full_child_name,
- False, 1)
- self.failUnlessEqual(resolved_name, self.parent_name)
-
- def test_relative_import_redirection(self):
- # Having a relative module name resolve to a name that has a value of
- # None in sys.modules should redirect to import an absolute import for
- # the specified name.
- module_name = '<to import>'
- pkg_name = '<pkg>'
- resolved_relative_name = module_name + '.' + pkg_name
- expected_module = mock_importer.MockModule(module_name)
- sys.modules[resolved_relative_name] = None
- sys.modules[module_name] = expected_module
- importing_globals = {'__name__':pkg_name, '__path__':['some path']}
- imported = self.importer(module_name, importing_globals, level=-1)
- self.failUnless(imported is expected_module)
-
-
-class ImportFromListTests(ImportHelper2):
-
- """Test conditions based on fromlist."""
-
- def test_fromlist_relative_import(self):
- # Any items specified in fromlist while importing a package needs to be
- # checked as to whether it is a pre-existing attribute or should be
- # considered a declaration for a relative import.
- module_name = '<module name>'
- pkg_name = '<pkg name>'
- full_module_name = pkg_name + '.' + module_name
- # Already have package imported.
- pkg_module = mock_importer.MockModule(pkg_name, pkg_list=['some path'])
- sys.modules[pkg_name] = pkg_module
- # Make sure implicit import succeeds.
- succeed = mock_importer.SucceedImporter()
- sys.meta_path.append(succeed)
- # Import the package with a fromlist of the module.
- module = self.importer._return_module(pkg_name, '',
- fromlist=[module_name])
- self.failUnless(hasattr(module, module_name))
- fromlist_module = getattr(module, module_name)
- self.failUnlessEqual(fromlist_module.__name__, full_module_name)
-
- def test_fromlist_nonexistent(self):
- # If something listed in a fromlist does not exist the import
- # should still succeed.
- pkg_name = '<pkg name>'
- pkg_module = mock_importer.MockModule(pkg_name, pkg_list=['some path'])
- sys.modules[pkg_name] = pkg_module
- nonexistent_attr = 'asdfsdfd'
- module = self.importer._return_module(pkg_name, '',
- fromlist=[nonexistent_attr])
- self.failUnless(not hasattr(module, nonexistent_attr))
-
- def test_fromlist_existing(self):
- # A value in fromlist that already exists should not lead to a relative
- # import.
- pkg_name = '<pkg name>'
- pkg_module = mock_importer.MockModule(pkg_name, pkg_list=['some path'])
- attr = 'some_attr'
- setattr(pkg_module, attr, None)
- sys.modules[pkg_name] = pkg_module
- failing_import = mock_importer.ErrorImporter()
- sys.meta_path.append(failing_import)
- module = self.importer(pkg_name, fromlist=[attr])
- self.failUnless(hasattr(module, attr))
- self.failUnless(not hasattr(failing_import, 'find_request'))
-
- def test_fromlist_nonpackage(self):
- # No implicit imports of values in fromlist should be done if a module
- # is what is being imported specifically.
- module_name = '<module>'
- module = mock_importer.MockModule(module_name)
- sys.modules[module_name] = module
- failing_import = mock_importer.ErrorImporter()
- sys.meta_path.append(failing_import)
- imported_module = self.importer(module_name, fromlist=['sadfsdd'])
- self.failUnless(not hasattr(failing_import, 'find_request'))
-
- def test_fromlist_relative_import_all(self):
- # When '*' is passed in for fromlist, __all__ should be used for the
- # possibility of a relative import.
- module_name = '<module name>'
- pkg_name = '<pkg name>'
- full_module_name = pkg_name + '.' + module_name
- pkg_module = mock_importer.MockModule(pkg_name, pkg_list=['some path'],
- __all__=[module_name])
- sys.modules[pkg_name] = pkg_module
- succeed = mock_importer.SucceedImporter()
- sys.meta_path.append(succeed)
- # Also tests that fromlist can be a tuple and still work.
- module = self.importer(pkg_name, fromlist=('*',))
- self.failUnless(hasattr(module, module_name))
- relative_module = getattr(module, module_name)
- self.failUnlessEqual(relative_module.__name__, full_module_name)
-
- def test_empty_fromlist(self):
- # An empty fromlist means that the root module is returned.
- sys.modules[self.parent_name] = self.parent_module
- sys.modules[self.full_child_name] = self.child_module
- module = self.importer._return_module(self.full_child_name, '', [])
- self.failUnless(module is self.parent_module)
-
- def test_nonempty_fromlist(self):
- # A fromlist with values should return the specified module.
- sys.modules[self.parent_name] = self.parent_module
- sys.modules[self.full_child_name] = self.child_module
- test_attr_name = 'test_attr'
- setattr(self.child_module, test_attr_name, None)
- module = self.importer._return_module(self.full_child_name, '',
- [test_attr_name])
- self.failUnless(module is self.child_module)
-
- def test_relative_import_empty_fromlist(self):
- # If a relative import (with no dot) is performed with an empty fromlist
- # then the module specified in the relative name is returned.
- sys.modules[self.full_child_name] = self.child_module
- sys.modules[self.parent_name] = self.parent_module
- module = self.importer._return_module(self.full_child_name,
- self.child_name, [])
- self.failUnless(module is self.child_module)
-
- def test_deep_relative_import_empty_fromlist(self):
- # If the relative name of a module has a dot, return the module that
- # resolves to the absolute name of the module up to the first dot.
- sys.modules[self.full_child_name] = self.child_module
- sys.modules[self.parent_name] = self.parent_module
- extra_depth = '.baz'
- absolute_name = self.full_child_name + extra_depth
- relative_name = self.child_name + extra_depth
- module = self.importer._return_module(absolute_name, relative_name, [])
- self.failUnless(module is self.child_module)
-
-
-class ImportMiscTests(ImportHelper2):
-
- """Test miscellaneous parts of the Import class.
-
- Tests of the default values for __init__ are handled in the integration
- tests.
-
- """
-
- def test_sys_module_return(self):
- # A module found in sys.modules should be returned immediately.
- sys.modules[self.parent_name] = self.parent_module
- module = self.importer._import_module(self.parent_name)
- self.failUnless(module is self.parent_module)
-
- def test_sys_module_None(self):
- # If sys.modules contains None for a module name, then raise ImportError.
- module_name = '<module>'
- sys.modules[module_name] = None
- self.failUnlessRaises(ImportError, self.importer._import_module,
- module_name)
-
- def test_parent_missing(self):
- # An import should fail if a parent module cannot be found.
- sys.modules[self.full_child_name] = self.child_module
- self.failUnlessRaises(ImportError, self.importer, self.full_child_name)
-
- def test_parent_imported(self):
- # If a parent module is already imported, importing a child module
- # should work (along with setting the attribute on the parent for the
- # child module).
- delattr(self.parent_module, self.child_name)
- succeed_importer = mock_importer.SucceedImporter()
- sys.meta_path.append(succeed_importer)
- sys.modules[self.parent_name] = self.parent_module
- self.importer(self.full_child_name)
- self.failUnless(hasattr(self.parent_module, self.child_name))
- self.failUnlessEqual(getattr(self.parent_module, self.child_name),
- sys.modules[self.full_child_name])
-
- def test_parent_not_imported(self):
- # If a parent module is not imported yet, it should be imported.
- # The attribute on the parent module for the child module should also
- # be set.
- delattr(self.parent_module, self.child_name)
- succeed_importer = mock_importer.SucceedImporter()
- sys.meta_path.append(succeed_importer)
- self.importer(self.full_child_name)
- self.failUnless(self.parent_name in sys.modules)
- self.failUnless(self.full_child_name in sys.modules)
- self.failUnless(hasattr(sys.modules[self.parent_name], self.child_name))
- self.failUnlessEqual(getattr(sys.modules[self.parent_name],
- self.child_name),
- sys.modules[self.full_child_name])
-
- def test_None_not_set_for_import_failure(self):
- # If an import that is tried both relative and absolute fails there
- # should not be an entry of None for the resolved relative name.
- module_name = '<should fail>'
- pkg_name = '<non-existent package>'
- resolved_name = module_name + '.' + pkg_name
- importing_globals = {'__name__':pkg_name, '__path__':['path']}
- self.failUnlessRaises(ImportError, self.importer, module_name,
- importing_globals, {}, [], -1)
- self.failUnless(resolved_name not in sys.modules)
-
- def test_empty_string(self):
- # An empty string should raise ValueError if level is not > 0.
- for level in (-1, 0):
- self.failUnlessRaises(ValueError, self.importer, '', {}, {}, level)
-
-
-class ImportMetaPathTests(ImportHelper):
-
- """Test meta_path usage."""
-
- def test_search_meta_path(self):
- # Test search method of sys.meta_path.
- # Should raise ImportError on error.
- self.clear_sys_modules('sys')
- self.failUnlessRaises(ImportError, self.importer._search_meta_path,
- 'sys')
- # Verify call order.
- meta_path = (mock_importer.PassImporter(),
- mock_importer.SucceedImporter())
- sys.meta_path = meta_path
- loader = self.importer._search_meta_path('sys')
- for entry in meta_path:
- self.failUnlessEqual(entry.find_request, ('sys', None))
- self.failUnless(loader is meta_path[-1])
-
- def test_extended_meta_path(self):
- # Default meta_path entries set during initialization should be
- # queried after sys.meta_path.
- self.clear_sys_modules('sys')
- pass_importer = mock_importer.PassImporter()
- sys.meta_path = [pass_importer]
- succeed_importer = mock_importer.SucceedImporter()
- importer_ = importer.Import(extended_meta_path=(succeed_importer,))
- module = importer_._import_module('sys')
- for meta_importer in (pass_importer, succeed_importer):
- self.failUnlessEqual(meta_importer.find_request, ('sys', None))
- self.failUnless(module in succeed_importer.loaded_modules)
-
- def test_parent_path(self):
- # If a parent module has __path__ defined it should be passed as an
- # argument during importing.
- pkg_name = '<pkg>'
- module_name = '<module>'
- test_path = ['<test path>']
- pkg_module = mock_importer.MockModule(pkg_name)
- pkg_module.__path__ = test_path
- sys.modules[pkg_name] = pkg_module
- succeed_importer = mock_importer.SucceedImporter()
- sys.meta_path.append(succeed_importer)
- full_module_name = '.'.join([pkg_name, module_name])
- lookup_args = (full_module_name, test_path)
- self.importer(full_module_name)
- self.failUnless(full_module_name in sys.modules)
- self.failUnlessEqual(succeed_importer.find_request, lookup_args)
- self.failUnlessEqual(succeed_importer.load_request, lookup_args[0])
-
-
-class ImportStdPathTests(ImportHelper):
-
- """Test sys.path usage."""
-
- def test_default_importer_factory(self):
- # Make sure that the object passed in during initialization is used
- # when sys.path_importer_cache has a value of None.
- module_name = '<dummy>'
- self.clear_sys_modules(module_name)
- succeed_importer = mock_importer.SucceedImporter()
- importer_ = importer.Import(succeed_importer, tuple())
- sys.meta_path = []
- sys.path = ['<succeed>']
- sys.path_importer_cache['<succeed>'] = None
- module = importer_._import_module(module_name)
- self.failUnlessEqual(succeed_importer.find_request,
- (module_name, None))
- self.failUnless(module in succeed_importer.loaded_modules)
-
- def test_search_std_path(self):
- # Test sys.path searching for a loader.
- module_name = '<dummy>'
- self.clear_sys_modules(module_name)
- importer_ = importer.Import(extended_meta_path=())
- sys.path = []
- pass_importer = mock_importer.PassImporter.set_on_sys_path()
- succeed_importer = mock_importer.SucceedImporter.set_on_sys_path()
- sys_path = (pass_importer, succeed_importer)
- module = importer_._import_module(module_name)
- for entry in sys_path:
- self.failUnlessEqual(entry.find_request, (module_name, None))
- self.failUnless(module in succeed_importer.loaded_modules)
-
- def test_importer_cache_preexisting(self):
- # A pre-existing importer should be returned if it exists in
- # sys.path_importer_cache.
- module_name = '<dummy>'
- self.clear_sys_modules(module_name)
- sys.path = []
- succeed_importer = mock_importer.SucceedImporter.set_on_sys_path()
- loader = self.importer._search_std_path(module_name)
- self.failUnless(loader is succeed_importer)
-
- def test_importer_cache_from_path_hooks(self):
- # If an entry does not exist for a sys.path entry in the importer cache
- # then sys.path_hooks should be searched and if one is found then cache
- # it.
- module_name = '<dummy>'
- self.clear_sys_modules(module_name)
- path_entry = '<succeed>'
- succeed_importer = mock_importer.SucceedImporter()
- sys.path = [path_entry]
- sys.path_importer_cache.clear()
- sys.path_hooks = [succeed_importer]
- loader = self.importer._search_std_path(module_name)
- self.failUnless(loader is succeed_importer)
- self.failUnless(sys.path_importer_cache[path_entry] is
- succeed_importer)
-
- def test_importer_cache_no_path_hooks(self):
- # If an entry does not exist for a sys.path entry in the importer cache
- # and sys.path_hooks has nothing for the entry, None should be set.
- module_name = '<dummy>'
- self.clear_sys_modules(module_name)
- path_entry = '<test>'
- sys.path = [path_entry]
- sys.path_hooks = []
- sys.path_importer_cache.clear()
- self.failUnlessRaises(ImportError, self.importer._search_std_path,
- module_name)
- self.failUnless(sys.path_importer_cache[path_entry] is None)
-
- def test_searching_package_path(self):
- # If importing in a package then search path is the package's __path__
- # value; otherwise it is sys.path.
- succeed_importer = mock_importer.SucceedImporter()
- sys.path_hooks.append(succeed_importer)
- search_paths = ['test path']
- module_name = '<pkg>.<dummy>'
- loader = self.importer._search_std_path(module_name, search_paths)
- self.failUnless(loader is succeed_importer)
- self.failUnless(search_paths[0] in succeed_importer.path_entries)
- self.failUnlessEqual(succeed_importer.find_request,
- (module_name, None))
- self.failUnless(search_paths[0] in sys.path_importer_cache)
- self.clear_sys_modules(module_name)
- del sys.path_importer_cache[search_paths[0]]
- succeed_importer.path_entries = []
- self.importer._import_module(module_name, search_paths)
- self.failUnless(search_paths[0] in succeed_importer.path_entries)
-
-
-class IntegrationTests(TestPyPycPackages):
-
- """Tests that verify the default semantics are what is expected.
-
- Tests should verify that:
- * The proper module was returned.
- * All expected modules were added to sys.modules.
- * All modules imported by the call have the proper attributes.
-
- There are currently no tests for the import lock.
-
- Need to test (both relative and absolute imports as needed):
- * import module
- * import package
- * import package.module
- * from module import attribute
- * from package import module
- * from package import attribute
- * from package.module import attribute
- * from package import *
- + With __all__
-
- """
-
- def setUp(self):
- TestPyPycPackages.setUp(self, False)
- self.import_ = importer.Import()
- self.cached_modules = []
- if self.module_name in sys.modules:
- del sys.modules[self.module_name]
- if self.pkg_name in sys.modules:
- del sys.modules[self.pkg_name]
- if self.pkg_module_name in sys.modules:
- del sys.modules[self.pkg_module_name]
-
- def tearDown(self):
- TestPyPycPackages.tearDown(self)
- for module_name, module in self.cached_modules:
- sys.modules[module_name] = module
-
- def clear_sys_modules(self, *modules):
- """Remove specified modules from sys.modules for a test and put back
- during teardown."""
- for module_name in modules:
- try:
- self.cached_modules.append((module_name,
- sys.modules[module_name]))
- del sys.modules[module_name]
- except KeyError:
- pass
-
- def test_builtin(self):
- # Test importing a built-in module.
- # ``import sys``
- self.clear_sys_modules('sys')
- module = self.import_('sys')
- self.failUnlessEqual(module.__name__, 'sys')
- # Only test for attributes that are not set during interpreter
- # creation!
- self.failUnless(hasattr(module, 'exc_info'))
- self.failUnless(hasattr(module, 'version'))
-
- def test_frozen(self):
- # Importing a frozen module should work.
- # ``import __hello__``
- self.clear_sys_modules('__hello__')
- faked_stdout = StringIO.StringIO()
- sys.stdout = faked_stdout
- try:
- module = self.import_('__hello__')
- self.failUnlessEqual(module.__name__, '__hello__')
- self.failUnless('frozen' in module.__file__)
- finally:
- sys.stdout = sys.__stdout__
-
- def test_extension(self):
- # Should be able to import extension modules.
- # ``import time``
- module = self.import_('time')
- self.failUnlessEqual(module.__name__, 'time')
- self.failUnless(hasattr(module, 'time'))
-
- def test_pyc_w_py(self):
- # Should be able to import a .pyc file when a .py is also present.
- # ``import pyc`` with a corresponding .py .
- module = self.import_(self.module_name)
- self.verify_module(module, self.pyc_path)
-
- def test_pyc_wo_py(self):
- # Importing just a .pyc file (w/ no .py) should be okay.
- # ``import pyc`` from a .pyc .
- os.remove(self.py_path)
- module = self.import_(self.module_name)
- self.verify_module(module, self.pyc_path)
-
- def test_sys_modules(self):
- # Should be able to pull from sys.modules even if a file does not exist
- # for the module.
- # ``import module`` from sys.modules.
- test_module_name = '<' + self.module_name + '>'
- test_module = mock_importer.MockModule(test_module_name)
- sys.modules[test_module_name] = test_module
- try:
- module = self.import_(test_module_name)
- self.failUnless(module is test_module)
- finally:
- del sys.modules[test_module_name]
-
- def test_py_creating_pyc(self):
- # Importing a .py file should work and generate a .pyc file.
- # ``import py`` creating a .pyc .
- os.remove(self.pyc_path)
- module = self.import_(self.module_name)
- self.verify_module(module)
- self.failUnless(os.path.exists(self.pyc_path))
- with open(self.pyc_path, 'rb') as pyc_file:
- data = pyc_file.read()
- self.failUnlessEqual(data[:4], imp.get_magic())
- py_mod = int(os.stat(self.py_path).st_mtime)
- # XXX Using importer's _r_long.
- pyc_mod = importer._r_long(data[4:8])
- self.failUnlessEqual(py_mod, pyc_mod)
- code = marshal.loads(data[8:])
- module = mock_importer.MockModule(self.module_name)
- exec code in module.__dict__
- self.verify_module(module)
-
- def test_top_level_package(self):
- # Should be able to import a top-level package.
- # ``import package``
- module = self.import_(self.pkg_name)
- self.verify_package(module)
-
- def test_package_module(self):
- # A module within a top-level package should work with the package not
- # already imported.
- # ``import package.module``
- assert '.' in self.pkg_module_name
- module = self.import_(self.pkg_module_name)
- self.verify_package(module, self.pkg_module_name)
-
- def test_sub_package(self):
- # A package within a package should work.
- # ``import package.subpackage``
- module = self.import_(self.sub_pkg_name)
- self.verify_package(module, self.sub_pkg_name)
-
- def test_sub_package_module(self):
- # A module contained within a sub-package should work.
- # ``import package.subpackage.module``
- module = self.import_(self.sub_pkg_module_name)
- self.verify_package(module, self.sub_pkg_module_name)
-
- def test_classic_relative_import_in_package_init(self):
- # Importing within a package's __init__ file using a relative name
- # should work properly.
- # ``import module`` for 'package' where 'module' is 'package.module'.
- package_globals = {'__name__':self.pkg_name, '__path__':['some_path']}
- module = self.import_(self.module_name, package_globals, level=-1)
- self.verify_package(module, self.pkg_module_name)
-
- def test_classic_relative_import_in_module(self):
- # Importing using a relative name in a module in a package should work.
- # ``import module`` for 'package.some_module' where 'module' is
- # 'package.module'.
- module_globals = {'__name__':self.pkg_name + '.' + 'another_module'}
- module = self.import_(self.module_name, module_globals, level=-1)
- self.verify_package(module, self.pkg_module_name)
-
- def test_absolute_name_in_classic_relative_context(self):
- # Importing a module that happens to be ambiguous in terms of being
- # relative or absolute, but only exists in an absolute name context,
- # should work. It should also lead to a value for None in sys.modules
- # for the resolved relative name.
- # ``import module`` for 'package' where 'module' is 'module'.
- package_module_globals = {'__name__':self.pkg_module_name}
- module = self.import_(self.top_level_module_name,
- package_module_globals, level=-1)
- resolved_name = self.pkg_name + '.' + self.top_level_module_name
- self.verify_package(module)
- self.failUnlessEqual(module.__name__, self.top_level_module_name)
- self.failUnless(sys.modules[resolved_name] is None)
-
- def test_relative_import_in_package_init(self):
- # Importing a module with a relative name in a package's __init__ file
- # should work.
- # ``from . import module`` for 'package'.
- caller_globals = {'__name__':self.pkg_name, '__path__':[self.pkg_path]}
- module = self.import_('', caller_globals, fromlist=[self.module_name],
- level=1)
- self.verify_package(module, self.pkg_name)
-
- def test_relative_import_in_package(self):
- # Importing a module with a relative name in another module should
- # work.
- # ``from . import module`` for 'package.module'.
- caller_globals = {'__name__':self.pkg_module_name}
- module = self.import_('', caller_globals, fromlist=[self.module_name],
- level=1)
- self.verify_package(module, self.pkg_name)
-
- def test_relative_import_in_subpackages(self):
- # ``from .. import module`` in 'package.subpackage'.
- caller_globals = {'__name__':self.sub_pkg_name,
- '__path__':[self.sub_pkg_path]}
- module = self.import_('', caller_globals, fromlist=[self.module_name],
- level=2)
- self.verify_package(module, self.pkg_name)
-
- def test_relative_import_of_package(self):
- # ``from ..subpackage import module`` in 'package.subpackage'.
- # XXX
- caller_globals = {'__name__':self.sub_pkg_name,
- '__path__':[self.sub_pkg_path]}
- module = self.import_(self.sub_pkg_tail_name, caller_globals,
- fromlist=[self.module_name], level=2)
- self.verify_package(module, self.sub_pkg_name)
-
- def test_relative_import_return(self):
- # When importing from a relative name, the module up to the first dot
- # of that relative name (made absolute) should be returned.
- # ``import subpackage.module`` for 'package.module'.
- module_globals = {'__name__':self.pkg_module_name}
- relative_name = self.sub_pkg_tail_name + '.' + self.module_name
- module = self.import_(relative_name, module_globals)
- self.verify_package(module, self.sub_pkg_name)
-
-
-
-def test_main():
- test_classes = [cls for cls in globals().itervalues()
- if isinstance(cls, type) and
- cls.__name__.endswith('Tests')]
- test_support.run_unittest(*test_classes)
-
-
-if __name__ == '__main__':
- test_main()
Copied: sandbox/trunk/import_in_py/test_importlib.py (from r53280, sandbox/trunk/import_in_py/test_importer.py)
==============================================================================
--- sandbox/trunk/import_in_py/test_importer.py (original)
+++ sandbox/trunk/import_in_py/test_importlib.py Tue Jan 9 23:45:05 2007
@@ -1,8 +1,8 @@
-import importer
+import importlib
import unittest
from test import test_support
-import mock_importer
+import mock_importlib
import contextlib
import imp
@@ -85,7 +85,7 @@
"""Test the built-in module importer."""
- importer = importer.BuiltinImporter
+ importer = importlib.BuiltinImporter
module_name = 'sys'
bad_module_names = ('tokenize', 'time', '__hello__')
@@ -100,7 +100,7 @@
"""
- importer = importer.FrozenImporter
+ importer = importlib.FrozenImporter
module_name = '__hello__'
bad_module_names = ('tokenize', 'time', 'sys')
@@ -298,18 +298,18 @@
"""Test the filesystem path_hooks factory function."""
def setUp(self):
- mock_handler = mock_importer.MockHandler('.X')
- self.factory = importer.FileSystemFactory(mock_handler)
+ mock_handler = mock_importlib.MockHandler('.X')
+ self.factory = importlib.FileSystemFactory(mock_handler)
def test_absolute_path_accepted(self):
# Passing in an absolute path to a directory should be accepted.
importer_ = self.factory(os.path.abspath(os.getcwd()))
- self.failUnless(isinstance(importer_, importer.FileSystemImporter))
+ self.failUnless(isinstance(importer_, importlib.FileSystemImporter))
def test_relative_path_accepted(self):
# Passing in a relative directory path should be accepted.
importer_ = self.factory('')
- self.failUnless(isinstance(importer_, importer.FileSystemImporter))
+ self.failUnless(isinstance(importer_, importlib.FileSystemImporter))
def test_bad_directory(self):
# Should raise ImportError when used on a non-existing directory.
@@ -333,10 +333,10 @@
def setUp(self):
"""Create a basic importer."""
TestPyPycPackages.setUp(self)
- self.handler = mock_importer.MockHandler(self.py_ext)
- self.importer = importer.FileSystemImporter(self.directory,
+ self.handler = mock_importlib.MockHandler(self.py_ext)
+ self.importer = importlib.FileSystemImporter(self.directory,
self.handler)
- self.importer.loader = mock_importer.MockPyPycLoader
+ self.importer.loader = mock_importlib.MockPyPycLoader
def test_module_case_sensitivity(self):
# Case-sensitivity should always matter as long as PYTHONCASEOK is not
@@ -391,9 +391,9 @@
def test_find_module_single_handler(self):
# Having a single handler should work without issue.
loader = self.importer.find_module(self.module_name)
- self.failUnless(isinstance(loader, mock_importer.MockPyPycLoader))
+ self.failUnless(isinstance(loader, mock_importlib.MockPyPycLoader))
self.failUnlessEqual(loader.file_path, self.py_path)
- self.failUnless(isinstance(loader.handler, mock_importer.MockHandler))
+ self.failUnless(isinstance(loader.handler, mock_importlib.MockHandler))
self.failUnless(loader.package is None)
def test_find_module_cannot_find(self):
@@ -404,22 +404,22 @@
def test_find_module_multiple_handlers(self):
# Modules should be found based on the order of the handlers.
# mock
- first_handler = mock_importer.MockHandler('.not_found')
- second_handler = mock_importer.MockHandler(self.py_ext)
- fs_importer = importer.FileSystemImporter(self.directory,
+ first_handler = mock_importlib.MockHandler('.not_found')
+ second_handler = mock_importlib.MockHandler(self.py_ext)
+ fs_importer = importlib.FileSystemImporter(self.directory,
first_handler,
second_handler)
- fs_importer.loader = mock_importer.MockPyPycLoader
+ fs_importer.loader = mock_importlib.MockPyPycLoader
loader = fs_importer.find_module(self.module_name)
- self.failUnless(isinstance(loader, mock_importer.MockPyPycLoader))
+ self.failUnless(isinstance(loader, mock_importlib.MockPyPycLoader))
self.failUnlessEqual(loader.file_path, self.py_path)
- self.failUnless(isinstance(loader.handler, mock_importer.MockHandler))
+ self.failUnless(isinstance(loader.handler, mock_importlib.MockHandler))
def test_pkg_discovery(self):
# If a module name refers to a directory with an __init__ file it
# should be recognized as a package.
loader = self.importer.find_module(self.pkg_name)
- self.failUnless(isinstance(loader, mock_importer.MockPyPycLoader))
+ self.failUnless(isinstance(loader, mock_importlib.MockPyPycLoader))
self.failUnlessEqual(loader.file_path, self.pkg_init_path)
self.failUnlessEqual(loader.handler, self.handler)
self.failUnlessEqual(loader.package, self.pkg_path)
@@ -449,17 +449,17 @@
class FileSystemLoaderMockEnv(unittest.TestCase):
"""Helper for settting up mock environment for testing
- importer.FileSystemLoader."""
+ importlib.FileSystemLoader."""
def setUp(self):
"""Create a fresh loader per run."""
- mock_handler = mock_importer.MockHandler()
+ mock_handler = mock_importlib.MockHandler()
self.test_path = "<test path>"
self.pkg_path = "<test pkg>"
self.pkg_init_path = os.path.join(self.pkg_path, '__init__.test')
self.module_name = "test_module_name"
self.pkg_name = "test_pkg"
- self.loader = importer.FileSystemLoader(self.test_path,
+ self.loader = importlib.FileSystemLoader(self.test_path,
mock_handler)
def tearDown(self):
@@ -498,7 +498,7 @@
def handle_code(*args):
raise ImportError
- loader = importer.FileSystemLoader(self.test_path, RaiseErrorHandler())
+ loader = importlib.FileSystemLoader(self.test_path, RaiseErrorHandler())
try:
loader.load_module(self.module_name)
except ImportError:
@@ -507,8 +507,8 @@
def test_package_init(self):
# Test that instantiating a loader for handling a package works
# properly.
- pkg_loader = importer.FileSystemLoader(self.pkg_init_path,
- mock_importer.MockHandler(),
+ pkg_loader = importlib.FileSystemLoader(self.pkg_init_path,
+ mock_importlib.MockHandler(),
self.pkg_path)
module = pkg_loader.load_module(self.pkg_name)
self.failUnlessEqual(module.loader, pkg_loader)
@@ -529,7 +529,7 @@
self.module_name = "import_test"
self.file_name = self.module_name + self.file_ext
self.file_path = os.path.join(self.directory, self.file_name)
- self.data = "File used for testing 'importer' module.\r\n42"
+ self.data = "File used for testing 'importlib' module.\r\n42"
with open(self.file_path, 'w') as test_file:
test_file.write(self.data)
@@ -587,14 +587,14 @@
def setUp(self):
TestPyPycFiles.setUp(self)
- self.handler = importer.PyPycHandler()
+ self.handler = importlib.PyPycHandler()
def test_init(self):
# Test __init__ usage.
proper_bytecode_ext = '.pyc' if __debug__ else '.pyo'
for source_ext, bytecode_ext in ((None, None), (('A',), None),
(None, ('A',)), (('A',), ('B',))):
- handler = importer.PyPycHandler(source_ext, bytecode_ext)
+ handler = importlib.PyPycHandler(source_ext, bytecode_ext)
if source_ext is None:
source = ('.py',)
if bytecode_ext is None:
@@ -607,7 +607,7 @@
# Should return a new module with the proper value for __name__.
module = self.handler.new_module('test')
self.failUnlessEqual('test', module.__name__)
- self.failUnless(isinstance(module, importer.__class__))
+ self.failUnless(isinstance(module, importlib.__class__))
def test_parse_pyc(self):
# Split up data from .pyc file for the magic number, timestamp,
@@ -616,7 +616,7 @@
pyc = bytecode_file.read()
magic, timestamp, bytecode = self.handler.parse_pyc(pyc)
code = marshal.loads(bytecode)
- module = mock_importer.MockModule(self.module_name, self.py_path)
+ module = mock_importlib.MockModule(self.module_name, self.py_path)
exec code in module.__dict__
self.verify_module(module, self.py_path)
@@ -633,7 +633,7 @@
# Create a code object from bytecode; raises ValueError if code object
# cannot be created.
code_object = self.handler.code_from_bytecode(self.bytecode)
- module = mock_importer.MockModule(self.module_name)
+ module = mock_importlib.MockModule(self.module_name)
exec code_object in module.__dict__
self.verify_module(module)
self.failUnlessRaises(ValueError, self.handler.code_from_bytecode,
@@ -642,7 +642,7 @@
def test_code_from_source(self):
# Create a code object from source.
code = self.handler.code_from_source(self.source, self.py_path)
- module = mock_importer.MockModule(self.module_name)
+ module = mock_importlib.MockModule(self.module_name)
exec code in module.__dict__
self.verify_module(module)
@@ -652,8 +652,8 @@
timestamp = 42
data = self.handler.create_pyc(bytecode, timestamp)
self.failUnlessEqual(imp.get_magic(), data[:4])
- # XXX Using importer module's marshal long function.
- self.failUnlessEqual(timestamp, importer._r_long(data[4:8]))
+ # XXX Using importlib module's marshal long function.
+ self.failUnlessEqual(timestamp, importlib._r_long(data[4:8]))
self.failUnlessEqual(marshal.dumps(bytecode), data[8:])
@@ -684,8 +684,8 @@
def test_good_pyc_w_py(self):
# Test using a .pyc file that is valid and a .py file exists.
- loader = mock_importer.MockPyPycLoader.setup()
- handler = loader._create_handler(importer.PyPycHandler)
+ loader = mock_importlib.MockPyPycLoader.setup()
+ handler = loader._create_handler(importlib.PyPycHandler)
module = loader._handle_pyc(handler)
loader._verify_module(module)
# Source code should never be read, only bytecode.
@@ -696,32 +696,32 @@
def test_bad_magic_no_py(self):
# ImportError should be raised when a .pyc has a bad magic number and
# there is no corresponding .py file.
- loader = mock_importer.MockPyPycLoader.setup(good_magic=False,
+ loader = mock_importlib.MockPyPycLoader.setup(good_magic=False,
py_exists=False)
- handler = loader._create_handler(importer.PyPycHandler)
+ handler = loader._create_handler(importlib.PyPycHandler)
self.failUnlessRaises(ImportError, loader._handle_pyc, handler)
def test_bad_bytecode_no_py(self):
# A .pyc file with bad bytecode (but good magic number and timestamp)
# should raise an ImportError.
- loader = mock_importer.MockPyPycLoader.setup(py_exists=False,
+ loader = mock_importlib.MockPyPycLoader.setup(py_exists=False,
good_bytecode=False)
- handler = loader._create_handler(importer.PyPycHandler)
+ handler = loader._create_handler(importlib.PyPycHandler)
self.failUnlessRaises(ImportError, loader._handle_pyc, handler)
def test_bad_magic_w_py(self):
# A .pyc file with a bad magic number should lead to the .py file being
# used to generate a new .pyc.
- loader = mock_importer.MockPyPycLoader.setup(good_magic=False)
- handler = loader._create_handler(importer.PyPycHandler)
+ loader = mock_importlib.MockPyPycLoader.setup(good_magic=False)
+ handler = loader._create_handler(importlib.PyPycHandler)
module = loader._handle_pyc(handler)
loader._verify_module(module)
self.failUnless("write_data" in loader.log)
def test_bad_timestamp_w_py(self):
# A .pyc file with a outdated timestamp should be regenerated.
- loader = mock_importer.MockPyPycLoader.setup(good_timestamp=False)
- handler = loader._create_handler(importer.PyPycHandler)
+ loader = mock_importlib.MockPyPycLoader.setup(good_timestamp=False)
+ handler = loader._create_handler(importlib.PyPycHandler)
module = loader._handle_pyc(handler)
loader._verify_module(module)
self.failUnless("write_data" in loader.log)
@@ -729,14 +729,14 @@
def test_bad_bytecode_w_py(self):
# Even when there is a valid .py file, if the .pyc file has bad bytecode
# ImportError is raised.
- loader = mock_importer.MockPyPycLoader.setup(good_bytecode=False)
- handler = loader._create_handler(importer.PyPycHandler)
+ loader = mock_importlib.MockPyPycLoader.setup(good_bytecode=False)
+ handler = loader._create_handler(importlib.PyPycHandler)
self.failUnlessRaises(ImportError, loader._handle_pyc, handler)
def test_py_no_pyc(self):
# Test importing a .py file where no .pyc path is available.
- loader = mock_importer.MockPyPycLoader.setup(pyc_exists=False)
- handler = loader._create_handler(importer.PyPycHandler)
+ loader = mock_importlib.MockPyPycLoader.setup(pyc_exists=False)
+ handler = loader._create_handler(importlib.PyPycHandler)
module = loader._handle_py(handler)
loader._verify_module(module)
self.failUnless('write_data' not in loader.log)
@@ -745,16 +745,16 @@
def test_py_w_pyc(self):
# Test importing a .py file and a .pyc path is available.
- loader = mock_importer.MockPyPycLoader.setup()
- handler = loader._create_handler(importer.PyPycHandler)
+ loader = mock_importlib.MockPyPycLoader.setup()
+ handler = loader._create_handler(importlib.PyPycHandler)
module = loader._handle_py(handler)
loader._verify_module(module)
self.failUnless('write_data' in loader.log)
def test_package_init(self):
# Handling a package should set __path__ properly.
- loader = mock_importer.MockPyPycLoader.setup(pyc_exists=False)
- handler = loader._create_handler(importer.PyPycHandler)
+ loader = mock_importlib.MockPyPycLoader.setup(pyc_exists=False)
+ handler = loader._create_handler(importlib.PyPycHandler)
pkg_path = 'pkg path'
module = loader._handle_py(handler, pkg_path)
loader._verify_module(module)
@@ -763,13 +763,13 @@
def test_sys_modules_used(self):
# Handler should re-initialize an existing module in sys.modules
# (needed for 'reload').
- loader = mock_importer.MockPyPycLoader.setup()
- original_module = mock_importer.MockModule(loader.module_name)
+ loader = mock_importlib.MockPyPycLoader.setup()
+ original_module = mock_importlib.MockModule(loader.module_name)
original_value = -13
assert loader.attr_value != original_value
setattr(original_module, loader.attr_name, original_value)
sys.modules[loader.module_name] = original_module
- handler = loader._create_handler(importer.PyPycHandler)
+ handler = loader._create_handler(importlib.PyPycHandler)
new_module = loader._handle_pyc(handler)
self.failUnless(new_module is original_module)
self.failUnlessEqual(getattr(new_module, loader.attr_name),
@@ -782,7 +782,7 @@
def setUp(self):
"""Find an extension module to test against."""
- self.handler = importer.ExtensionFileHandler()
+ self.handler = importlib.ExtensionFileHandler()
for entry in sys.path:
if not os.path.isdir(entry):
continue
@@ -795,7 +795,7 @@
raise test_support.TestSkipped("not extension modules found")
self.ext_path = os.path.join(entry, ext_paths[0])
self.module_name = os.path.splitext(os.path.split(self.ext_path)[1])[0]
- self.loader = mock_importer.MockHandler()
+ self.loader = mock_importlib.MockHandler()
def test_handle_code(self):
# Make sure an extension module can be loaded.
@@ -824,8 +824,8 @@
sys.path_hooks = []
self.old_path_importer_cache = sys.path_importer_cache.copy()
sys.path_importer_cache.clear()
- self.default_importer = mock_importer.PassImporter()
- self.importer = importer.Import(self.default_importer, tuple())
+ self.default_importer = mock_importlib.PassImporter()
+ self.importer = importlib.Import(self.default_importer, tuple())
def tearDown(self):
"""Restore backup of import-related attributes in 'sys'."""
@@ -853,8 +853,8 @@
self.parent_name = '<parent>'
self.child_name = '<child>'
self.full_child_name = '.'.join([self.parent_name, self.child_name])
- self.parent_module = mock_importer.MockModule(self.parent_name)
- self.child_module = mock_importer.MockModule(self.full_child_name)
+ self.parent_module = mock_importlib.MockModule(self.parent_name)
+ self.child_module = mock_importlib.MockModule(self.full_child_name)
setattr(self.parent_module, self.child_name, self.child_module)
class ImportNameResolutionTests(ImportHelper2):
@@ -947,7 +947,7 @@
module_name = '<to import>'
pkg_name = '<pkg>'
resolved_relative_name = module_name + '.' + pkg_name
- expected_module = mock_importer.MockModule(module_name)
+ expected_module = mock_importlib.MockModule(module_name)
sys.modules[resolved_relative_name] = None
sys.modules[module_name] = expected_module
importing_globals = {'__name__':pkg_name, '__path__':['some path']}
@@ -967,10 +967,10 @@
pkg_name = '<pkg name>'
full_module_name = pkg_name + '.' + module_name
# Already have package imported.
- pkg_module = mock_importer.MockModule(pkg_name, pkg_list=['some path'])
+ pkg_module = mock_importlib.MockModule(pkg_name, pkg_list=['some path'])
sys.modules[pkg_name] = pkg_module
# Make sure implicit import succeeds.
- succeed = mock_importer.SucceedImporter()
+ succeed = mock_importlib.SucceedImporter()
sys.meta_path.append(succeed)
# Import the package with a fromlist of the module.
module = self.importer._return_module(pkg_name, '',
@@ -983,7 +983,7 @@
# If something listed in a fromlist does not exist the import
# should still succeed.
pkg_name = '<pkg name>'
- pkg_module = mock_importer.MockModule(pkg_name, pkg_list=['some path'])
+ pkg_module = mock_importlib.MockModule(pkg_name, pkg_list=['some path'])
sys.modules[pkg_name] = pkg_module
nonexistent_attr = 'asdfsdfd'
module = self.importer._return_module(pkg_name, '',
@@ -994,11 +994,11 @@
# A value in fromlist that already exists should not lead to a relative
# import.
pkg_name = '<pkg name>'
- pkg_module = mock_importer.MockModule(pkg_name, pkg_list=['some path'])
+ pkg_module = mock_importlib.MockModule(pkg_name, pkg_list=['some path'])
attr = 'some_attr'
setattr(pkg_module, attr, None)
sys.modules[pkg_name] = pkg_module
- failing_import = mock_importer.ErrorImporter()
+ failing_import = mock_importlib.ErrorImporter()
sys.meta_path.append(failing_import)
module = self.importer(pkg_name, fromlist=[attr])
self.failUnless(hasattr(module, attr))
@@ -1008,9 +1008,9 @@
# No implicit imports of values in fromlist should be done if a module
# is what is being imported specifically.
module_name = '<module>'
- module = mock_importer.MockModule(module_name)
+ module = mock_importlib.MockModule(module_name)
sys.modules[module_name] = module
- failing_import = mock_importer.ErrorImporter()
+ failing_import = mock_importlib.ErrorImporter()
sys.meta_path.append(failing_import)
imported_module = self.importer(module_name, fromlist=['sadfsdd'])
self.failUnless(not hasattr(failing_import, 'find_request'))
@@ -1021,10 +1021,10 @@
module_name = '<module name>'
pkg_name = '<pkg name>'
full_module_name = pkg_name + '.' + module_name
- pkg_module = mock_importer.MockModule(pkg_name, pkg_list=['some path'],
+ pkg_module = mock_importlib.MockModule(pkg_name, pkg_list=['some path'],
__all__=[module_name])
sys.modules[pkg_name] = pkg_module
- succeed = mock_importer.SucceedImporter()
+ succeed = mock_importlib.SucceedImporter()
sys.meta_path.append(succeed)
# Also tests that fromlist can be a tuple and still work.
module = self.importer(pkg_name, fromlist=('*',))
@@ -1102,7 +1102,7 @@
# should work (along with setting the attribute on the parent for the
# child module).
delattr(self.parent_module, self.child_name)
- succeed_importer = mock_importer.SucceedImporter()
+ succeed_importer = mock_importlib.SucceedImporter()
sys.meta_path.append(succeed_importer)
sys.modules[self.parent_name] = self.parent_module
self.importer(self.full_child_name)
@@ -1115,7 +1115,7 @@
# The attribute on the parent module for the child module should also
# be set.
delattr(self.parent_module, self.child_name)
- succeed_importer = mock_importer.SucceedImporter()
+ succeed_importer = mock_importlib.SucceedImporter()
sys.meta_path.append(succeed_importer)
self.importer(self.full_child_name)
self.failUnless(self.parent_name in sys.modules)
@@ -1153,8 +1153,8 @@
self.failUnlessRaises(ImportError, self.importer._search_meta_path,
'sys')
# Verify call order.
- meta_path = (mock_importer.PassImporter(),
- mock_importer.SucceedImporter())
+ meta_path = (mock_importlib.PassImporter(),
+ mock_importlib.SucceedImporter())
sys.meta_path = meta_path
loader = self.importer._search_meta_path('sys')
for entry in meta_path:
@@ -1165,10 +1165,10 @@
# Default meta_path entries set during initialization should be
# queried after sys.meta_path.
self.clear_sys_modules('sys')
- pass_importer = mock_importer.PassImporter()
+ pass_importer = mock_importlib.PassImporter()
sys.meta_path = [pass_importer]
- succeed_importer = mock_importer.SucceedImporter()
- importer_ = importer.Import(extended_meta_path=(succeed_importer,))
+ succeed_importer = mock_importlib.SucceedImporter()
+ importer_ = importlib.Import(extended_meta_path=(succeed_importer,))
module = importer_._import_module('sys')
for meta_importer in (pass_importer, succeed_importer):
self.failUnlessEqual(meta_importer.find_request, ('sys', None))
@@ -1180,10 +1180,10 @@
pkg_name = '<pkg>'
module_name = '<module>'
test_path = ['<test path>']
- pkg_module = mock_importer.MockModule(pkg_name)
+ pkg_module = mock_importlib.MockModule(pkg_name)
pkg_module.__path__ = test_path
sys.modules[pkg_name] = pkg_module
- succeed_importer = mock_importer.SucceedImporter()
+ succeed_importer = mock_importlib.SucceedImporter()
sys.meta_path.append(succeed_importer)
full_module_name = '.'.join([pkg_name, module_name])
lookup_args = (full_module_name, test_path)
@@ -1202,8 +1202,8 @@
# when sys.path_importer_cache has a value of None.
module_name = '<dummy>'
self.clear_sys_modules(module_name)
- succeed_importer = mock_importer.SucceedImporter()
- importer_ = importer.Import(succeed_importer, tuple())
+ succeed_importer = mock_importlib.SucceedImporter()
+ importer_ = importlib.Import(succeed_importer, tuple())
sys.meta_path = []
sys.path = ['<succeed>']
sys.path_importer_cache['<succeed>'] = None
@@ -1216,10 +1216,10 @@
# Test sys.path searching for a loader.
module_name = '<dummy>'
self.clear_sys_modules(module_name)
- importer_ = importer.Import(extended_meta_path=())
+ importer_ = importlib.Import(extended_meta_path=())
sys.path = []
- pass_importer = mock_importer.PassImporter.set_on_sys_path()
- succeed_importer = mock_importer.SucceedImporter.set_on_sys_path()
+ pass_importer = mock_importlib.PassImporter.set_on_sys_path()
+ succeed_importer = mock_importlib.SucceedImporter.set_on_sys_path()
sys_path = (pass_importer, succeed_importer)
module = importer_._import_module(module_name)
for entry in sys_path:
@@ -1232,7 +1232,7 @@
module_name = '<dummy>'
self.clear_sys_modules(module_name)
sys.path = []
- succeed_importer = mock_importer.SucceedImporter.set_on_sys_path()
+ succeed_importer = mock_importlib.SucceedImporter.set_on_sys_path()
loader = self.importer._search_std_path(module_name)
self.failUnless(loader is succeed_importer)
@@ -1243,7 +1243,7 @@
module_name = '<dummy>'
self.clear_sys_modules(module_name)
path_entry = '<succeed>'
- succeed_importer = mock_importer.SucceedImporter()
+ succeed_importer = mock_importlib.SucceedImporter()
sys.path = [path_entry]
sys.path_importer_cache.clear()
sys.path_hooks = [succeed_importer]
@@ -1268,7 +1268,7 @@
def test_searching_package_path(self):
# If importing in a package then search path is the package's __path__
# value; otherwise it is sys.path.
- succeed_importer = mock_importer.SucceedImporter()
+ succeed_importer = mock_importlib.SucceedImporter()
sys.path_hooks.append(succeed_importer)
search_paths = ['test path']
module_name = '<pkg>.<dummy>'
@@ -1311,7 +1311,7 @@
def setUp(self):
TestPyPycPackages.setUp(self, False)
- self.import_ = importer.Import()
+ self.import_ = importlib.Import()
self.cached_modules = []
if self.module_name in sys.modules:
del sys.modules[self.module_name]
@@ -1385,7 +1385,7 @@
# for the module.
# ``import module`` from sys.modules.
test_module_name = '<' + self.module_name + '>'
- test_module = mock_importer.MockModule(test_module_name)
+ test_module = mock_importlib.MockModule(test_module_name)
sys.modules[test_module_name] = test_module
try:
module = self.import_(test_module_name)
@@ -1405,10 +1405,10 @@
self.failUnlessEqual(data[:4], imp.get_magic())
py_mod = int(os.stat(self.py_path).st_mtime)
# XXX Using importer's _r_long.
- pyc_mod = importer._r_long(data[4:8])
+ pyc_mod = importlib._r_long(data[4:8])
self.failUnlessEqual(py_mod, pyc_mod)
code = marshal.loads(data[8:])
- module = mock_importer.MockModule(self.module_name)
+ module = mock_importlib.MockModule(self.module_name)
exec code in module.__dict__
self.verify_module(module)
More information about the Python-checkins
mailing list