Merged revisions 85429 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r85429 | benjamin.peterson | 2010-10-13 16:59:36 -0500 (Wed, 13 Oct 2010) | 1 line remove obselete import implementation #7287 ........
This commit is contained in:
parent
9e1ef1a11d
commit
4de6b06134
|
@ -1,248 +0,0 @@
|
|||
#
|
||||
# importers.py
|
||||
#
|
||||
# Demonstration subclasses of imputil.Importer
|
||||
#
|
||||
|
||||
# There should be consideration for the imports below if it is desirable
|
||||
# to have "all" modules be imported through the imputil system.
|
||||
|
||||
# these are C extensions
|
||||
import sys
|
||||
import imp
|
||||
import struct
|
||||
import marshal
|
||||
|
||||
# these are .py modules
|
||||
import imputil
|
||||
import os
|
||||
|
||||
######################################################################
|
||||
|
||||
_TupleType = type(())
|
||||
_StringType = type('')
|
||||
|
||||
######################################################################
|
||||
|
||||
# byte-compiled file suffic character
|
||||
_suffix_char = __debug__ and 'c' or 'o'
|
||||
|
||||
# byte-compiled file suffix
|
||||
_suffix = '.py' + _suffix_char
|
||||
|
||||
# the C_EXTENSION suffixes
|
||||
_c_suffixes = filter(lambda x: x[2] == imp.C_EXTENSION, imp.get_suffixes())
|
||||
|
||||
def _timestamp(pathname):
|
||||
"Return the file modification time as a Long."
|
||||
try:
|
||||
s = os.stat(pathname)
|
||||
except OSError:
|
||||
return None
|
||||
return long(s[8])
|
||||
|
||||
def _fs_import(dir, modname, fqname):
|
||||
"Fetch a module from the filesystem."
|
||||
|
||||
pathname = os.path.join(dir, modname)
|
||||
if os.path.isdir(pathname):
|
||||
values = { '__pkgdir__' : pathname, '__path__' : [ pathname ] }
|
||||
ispkg = 1
|
||||
pathname = os.path.join(pathname, '__init__')
|
||||
else:
|
||||
values = { }
|
||||
ispkg = 0
|
||||
|
||||
# look for dynload modules
|
||||
for desc in _c_suffixes:
|
||||
file = pathname + desc[0]
|
||||
try:
|
||||
fp = open(file, desc[1])
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
module = imp.load_module(fqname, fp, file, desc)
|
||||
values['__file__'] = file
|
||||
return 0, module, values
|
||||
|
||||
t_py = _timestamp(pathname + '.py')
|
||||
t_pyc = _timestamp(pathname + _suffix)
|
||||
if t_py is None and t_pyc is None:
|
||||
return None
|
||||
code = None
|
||||
if t_py is None or (t_pyc is not None and t_pyc >= t_py):
|
||||
file = pathname + _suffix
|
||||
f = open(file, 'rb')
|
||||
if f.read(4) == imp.get_magic():
|
||||
t = struct.unpack('<I', f.read(4))[0]
|
||||
if t == t_py:
|
||||
code = marshal.load(f)
|
||||
f.close()
|
||||
if code is None:
|
||||
file = pathname + '.py'
|
||||
code = _compile(file, t_py)
|
||||
|
||||
values['__file__'] = file
|
||||
return ispkg, code, values
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Simple function-based importer
|
||||
#
|
||||
class FuncImporter(imputil.Importer):
|
||||
"Importer subclass to delegate to a function rather than method overrides."
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
def get_code(self, parent, modname, fqname):
|
||||
return self.func(parent, modname, fqname)
|
||||
|
||||
def install_with(func):
|
||||
FuncImporter(func).install()
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Base class for archive-based importing
|
||||
#
|
||||
class PackageArchiveImporter(imputil.Importer):
|
||||
"""Importer subclass to import from (file) archives.
|
||||
|
||||
This Importer handles imports of the style <archive>.<subfile>, where
|
||||
<archive> can be located using a subclass-specific mechanism and the
|
||||
<subfile> is found in the archive using a subclass-specific mechanism.
|
||||
|
||||
This class defines two hooks for subclasses: one to locate an archive
|
||||
(and possibly return some context for future subfile lookups), and one
|
||||
to locate subfiles.
|
||||
"""
|
||||
|
||||
def get_code(self, parent, modname, fqname):
|
||||
if parent:
|
||||
# the Importer._finish_import logic ensures that we handle imports
|
||||
# under the top level module (package / archive).
|
||||
assert parent.__importer__ == self
|
||||
|
||||
# if a parent "package" is provided, then we are importing a
|
||||
# sub-file from the archive.
|
||||
result = self.get_subfile(parent.__archive__, modname)
|
||||
if result is None:
|
||||
return None
|
||||
if isinstance(result, _TupleType):
|
||||
assert len(result) == 2
|
||||
return (0,) + result
|
||||
return 0, result, {}
|
||||
|
||||
# no parent was provided, so the archive should exist somewhere on the
|
||||
# default "path".
|
||||
archive = self.get_archive(modname)
|
||||
if archive is None:
|
||||
return None
|
||||
return 1, "", {'__archive__':archive}
|
||||
|
||||
def get_archive(self, modname):
|
||||
"""Get an archive of modules.
|
||||
|
||||
This method should locate an archive and return a value which can be
|
||||
used by get_subfile to load modules from it. The value may be a simple
|
||||
pathname, an open file, or a complex object that caches information
|
||||
for future imports.
|
||||
|
||||
Return None if the archive was not found.
|
||||
"""
|
||||
raise RuntimeError, "get_archive not implemented"
|
||||
|
||||
def get_subfile(self, archive, modname):
|
||||
"""Get code from a subfile in the specified archive.
|
||||
|
||||
Given the specified archive (as returned by get_archive()), locate
|
||||
and return a code object for the specified module name.
|
||||
|
||||
A 2-tuple may be returned, consisting of a code object and a dict
|
||||
of name/values to place into the target module.
|
||||
|
||||
Return None if the subfile was not found.
|
||||
"""
|
||||
raise RuntimeError, "get_subfile not implemented"
|
||||
|
||||
|
||||
class PackageArchive(PackageArchiveImporter):
|
||||
"PackageArchiveImporter subclass that refers to a specific archive."
|
||||
|
||||
def __init__(self, modname, archive_pathname):
|
||||
self.__modname = modname
|
||||
self.__path = archive_pathname
|
||||
|
||||
def get_archive(self, modname):
|
||||
if modname == self.__modname:
|
||||
return self.__path
|
||||
return None
|
||||
|
||||
# get_subfile is passed the full pathname of the archive
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Emulate the standard directory-based import mechanism
|
||||
#
|
||||
class DirectoryImporter(imputil.Importer):
|
||||
"Importer subclass to emulate the standard importer."
|
||||
|
||||
def __init__(self, dir):
|
||||
self.dir = dir
|
||||
|
||||
def get_code(self, parent, modname, fqname):
|
||||
if parent:
|
||||
dir = parent.__pkgdir__
|
||||
else:
|
||||
dir = self.dir
|
||||
|
||||
# Return the module (and other info) if found in the specified
|
||||
# directory. Otherwise, return None.
|
||||
return _fs_import(dir, modname, fqname)
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s.%s for "%s" at 0x%x>' % (self.__class__.__module__,
|
||||
self.__class__.__name__,
|
||||
self.dir,
|
||||
id(self))
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# Emulate the standard path-style import mechanism
|
||||
#
|
||||
class PathImporter(imputil.Importer):
|
||||
def __init__(self, path=sys.path):
|
||||
self.path = path
|
||||
|
||||
def get_code(self, parent, modname, fqname):
|
||||
if parent:
|
||||
# we are looking for a module inside of a specific package
|
||||
return _fs_import(parent.__pkgdir__, modname, fqname)
|
||||
|
||||
# scan sys.path, looking for the requested module
|
||||
for dir in self.path:
|
||||
if isinstance(dir, _StringType):
|
||||
result = _fs_import(dir, modname, fqname)
|
||||
if result:
|
||||
return result
|
||||
|
||||
# not found
|
||||
return None
|
||||
|
||||
######################################################################
|
||||
|
||||
def _test_dir():
|
||||
"Debug/test function to create DirectoryImporters from sys.path."
|
||||
imputil.ImportManager().install()
|
||||
path = sys.path[:]
|
||||
path.reverse()
|
||||
for d in path:
|
||||
sys.path.insert(0, DirectoryImporter(d))
|
||||
sys.path.insert(0, imputil.BuiltinImporter())
|
||||
|
||||
def _test_revamp():
|
||||
"Debug/test function for the revamped import system."
|
||||
imputil.ImportManager().install()
|
||||
sys.path.insert(0, PathImporter())
|
||||
sys.path.insert(0, imputil.BuiltinImporter())
|
|
@ -1,126 +0,0 @@
|
|||
"""An Python re-implementation of hierarchical module import.
|
||||
|
||||
This code is intended to be read, not executed. However, it does work
|
||||
-- all you need to do to enable it is "import knee".
|
||||
|
||||
(The name is a pun on the klunkier predecessor of this module, "ni".)
|
||||
|
||||
"""
|
||||
|
||||
import sys, imp, __builtin__
|
||||
|
||||
|
||||
# Replacement for __import__()
|
||||
def import_hook(name, globals=None, locals=None, fromlist=None):
|
||||
parent = determine_parent(globals)
|
||||
q, tail = find_head_package(parent, name)
|
||||
m = load_tail(q, tail)
|
||||
if not fromlist:
|
||||
return q
|
||||
if hasattr(m, "__path__"):
|
||||
ensure_fromlist(m, fromlist)
|
||||
return m
|
||||
|
||||
def determine_parent(globals):
|
||||
if not globals or not globals.has_key("__name__"):
|
||||
return None
|
||||
pname = globals['__name__']
|
||||
if globals.has_key("__path__"):
|
||||
parent = sys.modules[pname]
|
||||
assert globals is parent.__dict__
|
||||
return parent
|
||||
if '.' in pname:
|
||||
i = pname.rfind('.')
|
||||
pname = pname[:i]
|
||||
parent = sys.modules[pname]
|
||||
assert parent.__name__ == pname
|
||||
return parent
|
||||
return None
|
||||
|
||||
def find_head_package(parent, name):
|
||||
if '.' in name:
|
||||
i = name.find('.')
|
||||
head = name[:i]
|
||||
tail = name[i+1:]
|
||||
else:
|
||||
head = name
|
||||
tail = ""
|
||||
if parent:
|
||||
qname = "%s.%s" % (parent.__name__, head)
|
||||
else:
|
||||
qname = head
|
||||
q = import_module(head, qname, parent)
|
||||
if q: return q, tail
|
||||
if parent:
|
||||
qname = head
|
||||
parent = None
|
||||
q = import_module(head, qname, parent)
|
||||
if q: return q, tail
|
||||
raise ImportError, "No module named " + qname
|
||||
|
||||
def load_tail(q, tail):
|
||||
m = q
|
||||
while tail:
|
||||
i = tail.find('.')
|
||||
if i < 0: i = len(tail)
|
||||
head, tail = tail[:i], tail[i+1:]
|
||||
mname = "%s.%s" % (m.__name__, head)
|
||||
m = import_module(head, mname, m)
|
||||
if not m:
|
||||
raise ImportError, "No module named " + mname
|
||||
return m
|
||||
|
||||
def ensure_fromlist(m, fromlist, recursive=0):
|
||||
for sub in fromlist:
|
||||
if sub == "*":
|
||||
if not recursive:
|
||||
try:
|
||||
all = m.__all__
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
ensure_fromlist(m, all, 1)
|
||||
continue
|
||||
if sub != "*" and not hasattr(m, sub):
|
||||
subname = "%s.%s" % (m.__name__, sub)
|
||||
submod = import_module(sub, subname, m)
|
||||
if not submod:
|
||||
raise ImportError, "No module named " + subname
|
||||
|
||||
def import_module(partname, fqname, parent):
|
||||
try:
|
||||
return sys.modules[fqname]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
fp, pathname, stuff = imp.find_module(partname,
|
||||
parent and parent.__path__)
|
||||
except ImportError:
|
||||
return None
|
||||
try:
|
||||
m = imp.load_module(fqname, fp, pathname, stuff)
|
||||
finally:
|
||||
if fp: fp.close()
|
||||
if parent:
|
||||
setattr(parent, partname, m)
|
||||
return m
|
||||
|
||||
|
||||
# Replacement for reload()
|
||||
def reload_hook(module):
|
||||
name = module.__name__
|
||||
if '.' not in name:
|
||||
return import_module(name, name, None)
|
||||
i = name.rfind('.')
|
||||
pname = name[:i]
|
||||
parent = sys.modules[pname]
|
||||
return import_module(name[i+1:], name, parent)
|
||||
|
||||
|
||||
# Save the original hooks
|
||||
original_import = __builtin__.__import__
|
||||
original_reload = __builtin__.reload
|
||||
|
||||
# Now install our hooks
|
||||
__builtin__.__import__ = import_hook
|
||||
__builtin__.reload = reload_hook
|
|
@ -374,6 +374,8 @@ Extension Modules
|
|||
Tools/Demos
|
||||
-----------
|
||||
|
||||
- Issue #7287: Demo/imputil/knee.py was removed.
|
||||
|
||||
- Issue #9188: The gdb extension now handles correctly narrow (UCS2) as well
|
||||
as wide (UCS4) unicode builds for both the host interpreter (embedded
|
||||
inside gdb) and the interpreter under test.
|
||||
|
|
Loading…
Reference in New Issue