ยปCore Development>Code coverage>Lib/imputil.py

Python code coverage for Lib/imputil.py

#countcontent
1n/a"""
2n/aImport utilities
3n/a
4n/aExported classes:
5n/a ImportManager Manage the import process
6n/a
7n/a Importer Base class for replacing standard import functions
8n/a BuiltinImporter Emulate the import mechanism for builtin and frozen modules
9n/a
10n/a DynLoadSuffixImporter
111"""
121from warnings import warnpy3k
131warnpy3k("the imputil module has been removed in Python 3.0", stacklevel=2)
141del warnpy3k
15n/a
16n/a# note: avoid importing non-builtin modules
171import imp ### not available in Jython?
181import sys
191import __builtin__
20n/a
21n/a# for the DirectoryImporter
221import struct
231import marshal
24n/a
251__all__ = ["ImportManager","Importer","BuiltinImporter"]
26n/a
271_StringType = type('')
281_ModuleType = type(sys) ### doesn't work in Jython...
29n/a
302class ImportManager:
311 "Manage the import process."
32n/a
331 def install(self, namespace=vars(__builtin__)):
34n/a "Install this ImportManager into the specified namespace."
35n/a
360 if isinstance(namespace, _ModuleType):
370 namespace = vars(namespace)
38n/a
39n/a # Note: we have no notion of "chaining"
40n/a
41n/a # Record the previous import hook, then install our own.
420 self.previous_importer = namespace['__import__']
430 self.namespace = namespace
440 namespace['__import__'] = self._import_hook
45n/a
46n/a ### fix this
47n/a #namespace['reload'] = self._reload_hook
48n/a
491 def uninstall(self):
50n/a "Restore the previous import mechanism."
510 self.namespace['__import__'] = self.previous_importer
52n/a
531 def add_suffix(self, suffix, importFunc):
540 assert hasattr(importFunc, '__call__')
550 self.fs_imp.add_suffix(suffix, importFunc)
56n/a
57n/a ######################################################################
58n/a #
59n/a # PRIVATE METHODS
60n/a #
61n/a
621 clsFilesystemImporter = None
63n/a
641 def __init__(self, fs_imp=None):
65n/a # we're definitely going to be importing something in the future,
66n/a # so let's just load the OS-related facilities.
670 if not _os_stat:
680 _os_bootstrap()
69n/a
70n/a # This is the Importer that we use for grabbing stuff from the
71n/a # filesystem. It defines one more method (import_from_dir) for our use.
720 if fs_imp is None:
730 cls = self.clsFilesystemImporter or _FilesystemImporter
740 fs_imp = cls()
750 self.fs_imp = fs_imp
76n/a
77n/a # Initialize the set of suffixes that we recognize and import.
78n/a # The default will import dynamic-load modules first, followed by
79n/a # .py files (or a .py file's cached bytecode)
800 for desc in imp.get_suffixes():
810 if desc[2] == imp.C_EXTENSION:
820 self.add_suffix(desc[0],
830 DynLoadSuffixImporter(desc).import_file)
840 self.add_suffix('.py', py_suffix_importer)
85n/a
861 def _import_hook(self, fqname, globals=None, locals=None, fromlist=None):
87n/a """Python calls this hook to locate and import a module."""
88n/a
890 parts = fqname.split('.')
90n/a
91n/a # determine the context of this import
920 parent = self._determine_import_context(globals)
93n/a
94n/a # if there is a parent, then its importer should manage this import
950 if parent:
960 module = parent.__importer__._do_import(parent, parts, fromlist)
970 if module:
980 return module
99n/a
100n/a # has the top module already been imported?
1010 try:
1020 top_module = sys.modules[parts[0]]
1030 except KeyError:
104n/a
105n/a # look for the topmost module
1060 top_module = self._import_top_module(parts[0])
1070 if not top_module:
108n/a # the topmost module wasn't found at all.
1090 raise ImportError, 'No module named ' + fqname
110n/a
111n/a # fast-path simple imports
1120 if len(parts) == 1:
1130 if not fromlist:
1140 return top_module
115n/a
1160 if not top_module.__dict__.get('__ispkg__'):
117n/a # __ispkg__ isn't defined (the module was not imported by us),
118n/a # or it is zero.
119n/a #
120n/a # In the former case, there is no way that we could import
121n/a # sub-modules that occur in the fromlist (but we can't raise an
122n/a # error because it may just be names) because we don't know how
123n/a # to deal with packages that were imported by other systems.
124n/a #
125n/a # In the latter case (__ispkg__ == 0), there can't be any sub-
126n/a # modules present, so we can just return.
127n/a #
128n/a # In both cases, since len(parts) == 1, the top_module is also
129n/a # the "bottom" which is the defined return when a fromlist
130n/a # exists.
1310 return top_module
132n/a
1330 importer = top_module.__dict__.get('__importer__')
1340 if importer:
1350 return importer._finish_import(top_module, parts[1:], fromlist)
136n/a
137n/a # Grrr, some people "import os.path" or do "from os.path import ..."
1380 if len(parts) == 2 and hasattr(top_module, parts[1]):
1390 if fromlist:
1400 return getattr(top_module, parts[1])
141n/a else:
1420 return top_module
143n/a
144n/a # If the importer does not exist, then we have to bail. A missing
145n/a # importer means that something else imported the module, and we have
146n/a # no knowledge of how to get sub-modules out of the thing.
1470 raise ImportError, 'No module named ' + fqname
148n/a
1491 def _determine_import_context(self, globals):
150n/a """Returns the context in which a module should be imported.
151n/a
152n/a The context could be a loaded (package) module and the imported module
153n/a will be looked for within that package. The context could also be None,
154n/a meaning there is no context -- the module should be looked for as a
155n/a "top-level" module.
156n/a """
157n/a
1580 if not globals or not globals.get('__importer__'):
159n/a # globals does not refer to one of our modules or packages. That
160n/a # implies there is no relative import context (as far as we are
161n/a # concerned), and it should just pick it off the standard path.
1620 return None
163n/a
164n/a # The globals refer to a module or package of ours. It will define
165n/a # the context of the new import. Get the module/package fqname.
1660 parent_fqname = globals['__name__']
167n/a
168n/a # if a package is performing the import, then return itself (imports
169n/a # refer to pkg contents)
1700 if globals['__ispkg__']:
1710 parent = sys.modules[parent_fqname]
1720 assert globals is parent.__dict__
1730 return parent
174n/a
1750 i = parent_fqname.rfind('.')
176n/a
177n/a # a module outside of a package has no particular import context
1780 if i == -1:
1790 return None
180n/a
181n/a # if a module in a package is performing the import, then return the
182n/a # package (imports refer to siblings)
1830 parent_fqname = parent_fqname[:i]
1840 parent = sys.modules[parent_fqname]
1850 assert parent.__name__ == parent_fqname
1860 return parent
187n/a
1881 def _import_top_module(self, name):
189n/a # scan sys.path looking for a location in the filesystem that contains
190n/a # the module, or an Importer object that can import the module.
1910 for item in sys.path:
1920 if isinstance(item, _StringType):
1930 module = self.fs_imp.import_from_dir(item, name)
194n/a else:
1950 module = item.import_top(name)
1960 if module:
1970 return module
1980 return None
199n/a
2001 def _reload_hook(self, module):
201n/a "Python calls this hook to reload a module."
202n/a
203n/a # reloading of a module may or may not be possible (depending on the
204n/a # importer), but at least we can validate that it's ours to reload
2050 importer = module.__dict__.get('__importer__')
2060 if not importer:
207n/a ### oops. now what...
2080 pass
209n/a
210n/a # okay. it is using the imputil system, and we must delegate it, but
211n/a # we don't know what to do (yet)
212n/a ### we should blast the module dict and do another get_code(). need to
213n/a ### flesh this out and add proper docco...
2140 raise SystemError, "reload not yet implemented"
215n/a
216n/a
2172class Importer:
2181 "Base class for replacing standard import functions."
219n/a
2201 def import_top(self, name):
221n/a "Import a top-level module."
2220 return self._import_one(None, name, name)
223n/a
224n/a ######################################################################
225n/a #
226n/a # PRIVATE METHODS
227n/a #
2281 def _finish_import(self, top, parts, fromlist):
229n/a # if "a.b.c" was provided, then load the ".b.c" portion down from
230n/a # below the top-level module.
2310 bottom = self._load_tail(top, parts)
232n/a
233n/a # if the form is "import a.b.c", then return "a"
2340 if not fromlist:
235n/a # no fromlist: return the top of the import tree
2360 return top
237n/a
238n/a # the top module was imported by self.
239n/a #
240n/a # this means that the bottom module was also imported by self (just
241n/a # now, or in the past and we fetched it from sys.modules).
242n/a #
243n/a # since we imported/handled the bottom module, this means that we can
244n/a # also handle its fromlist (and reliably use __ispkg__).
245n/a
246n/a # if the bottom node is a package, then (potentially) import some
247n/a # modules.
248n/a #
249n/a # note: if it is not a package, then "fromlist" refers to names in
250n/a # the bottom module rather than modules.
251n/a # note: for a mix of names and modules in the fromlist, we will
252n/a # import all modules and insert those into the namespace of
253n/a # the package module. Python will pick up all fromlist names
254n/a # from the bottom (package) module; some will be modules that
255n/a # we imported and stored in the namespace, others are expected
256n/a # to be present already.
2570 if bottom.__ispkg__:
2580 self._import_fromlist(bottom, fromlist)
259n/a
260n/a # if the form is "from a.b import c, d" then return "b"
2610 return bottom
262n/a
2631 def _import_one(self, parent, modname, fqname):
264n/a "Import a single module."
265n/a
266n/a # has the module already been imported?
2670 try:
2680 return sys.modules[fqname]
2690 except KeyError:
2700 pass
271n/a
272n/a # load the module's code, or fetch the module itself
2730 result = self.get_code(parent, modname, fqname)
2740 if result is None:
2750 return None
276n/a
2770 module = self._process_result(result, fqname)
278n/a
279n/a # insert the module into its parent
2800 if parent:
2810 setattr(parent, modname, module)
2820 return module
283n/a
2841 def _process_result(self, result, fqname):
2850 ispkg, code, values = result
286n/a # did get_code() return an actual module? (rather than a code object)
2870 is_module = isinstance(code, _ModuleType)
288n/a
289n/a # use the returned module, or create a new one to exec code into
2900 if is_module:
2910 module = code
292n/a else:
2930 module = imp.new_module(fqname)
294n/a
295n/a ### record packages a bit differently??
2960 module.__importer__ = self
2970 module.__ispkg__ = ispkg
298n/a
299n/a # insert additional values into the module (before executing the code)
3000 module.__dict__.update(values)
301n/a
302n/a # the module is almost ready... make it visible
3030 sys.modules[fqname] = module
304n/a
305n/a # execute the code within the module's namespace
3060 if not is_module:
3070 try:
3080 exec code in module.__dict__
3090 except:
3100 if fqname in sys.modules:
3110 del sys.modules[fqname]
3120 raise
313n/a
314n/a # fetch from sys.modules instead of returning module directly.
315n/a # also make module's __name__ agree with fqname, in case
316n/a # the "exec code in module.__dict__" played games on us.
3170 module = sys.modules[fqname]
3180 module.__name__ = fqname
3190 return module
320n/a
3211 def _load_tail(self, m, parts):
322n/a """Import the rest of the modules, down from the top-level module.
323n/a
324n/a Returns the last module in the dotted list of modules.
325n/a """
3260 for part in parts:
3270 fqname = "%s.%s" % (m.__name__, part)
3280 m = self._import_one(m, part, fqname)
3290 if not m:
3300 raise ImportError, "No module named " + fqname
3310 return m
332n/a
3331 def _import_fromlist(self, package, fromlist):
334n/a 'Import any sub-modules in the "from" list.'
335n/a
336n/a # if '*' is present in the fromlist, then look for the '__all__'
337n/a # variable to find additional items (modules) to import.
3380 if '*' in fromlist:
3390 fromlist = list(fromlist) + \
3400 list(package.__dict__.get('__all__', []))
341n/a
3420 for sub in fromlist:
343n/a # if the name is already present, then don't try to import it (it
344n/a # might not be a module!).
3450 if sub != '*' and not hasattr(package, sub):
3460 subname = "%s.%s" % (package.__name__, sub)
3470 submod = self._import_one(package, sub, subname)
3480 if not submod:
3490 raise ImportError, "cannot import name " + subname
350n/a
3511 def _do_import(self, parent, parts, fromlist):
352n/a """Attempt to import the module relative to parent.
353n/a
354n/a This method is used when the import context specifies that <self>
355n/a imported the parent module.
356n/a """
3570 top_name = parts[0]
3580 top_fqname = parent.__name__ + '.' + top_name
3590 top_module = self._import_one(parent, top_name, top_fqname)
3600 if not top_module:
361n/a # this importer and parent could not find the module (relatively)
3620 return None
363n/a
3640 return self._finish_import(top_module, parts[1:], fromlist)
365n/a
366n/a ######################################################################
367n/a #
368n/a # METHODS TO OVERRIDE
369n/a #
3701 def get_code(self, parent, modname, fqname):
371n/a """Find and retrieve the code for the given module.
372n/a
373n/a parent specifies a parent module to define a context for importing. It
374n/a may be None, indicating no particular context for the search.
375n/a
376n/a modname specifies a single module (not dotted) within the parent.
377n/a
378n/a fqname specifies the fully-qualified module name. This is a
379n/a (potentially) dotted name from the "root" of the module namespace
380n/a down to the modname.
381n/a If there is no parent, then modname==fqname.
382n/a
383n/a This method should return None, or a 3-tuple.
384n/a
385n/a * If the module was not found, then None should be returned.
386n/a
387n/a * The first item of the 2- or 3-tuple should be the integer 0 or 1,
388n/a specifying whether the module that was found is a package or not.
389n/a
390n/a * The second item is the code object for the module (it will be
391n/a executed within the new module's namespace). This item can also
392n/a be a fully-loaded module object (e.g. loaded from a shared lib).
393n/a
394n/a * The third item is a dictionary of name/value pairs that will be
395n/a inserted into new module before the code object is executed. This
396n/a is provided in case the module's code expects certain values (such
397n/a as where the module was found). When the second item is a module
398n/a object, then these names/values will be inserted *after* the module
399n/a has been loaded/initialized.
400n/a """
4010 raise RuntimeError, "get_code not implemented"
402n/a
403n/a
404n/a######################################################################
405n/a#
406n/a# Some handy stuff for the Importers
407n/a#
408n/a
409n/a# byte-compiled file suffix character
4101_suffix_char = __debug__ and 'c' or 'o'
411n/a
412n/a# byte-compiled file suffix
4131_suffix = '.py' + _suffix_char
414n/a
4151def _compile(pathname, timestamp):
416n/a """Compile (and cache) a Python source file.
417n/a
418n/a The file specified by <pathname> is compiled to a code object and
419n/a returned.
420n/a
421n/a Presuming the appropriate privileges exist, the bytecodes will be
422n/a saved back to the filesystem for future imports. The source file's
423n/a modification timestamp must be provided as a Long value.
424n/a """
4250 codestring = open(pathname, 'rU').read()
4260 if codestring and codestring[-1] != '\n':
4270 codestring = codestring + '\n'
4280 code = __builtin__.compile(codestring, pathname, 'exec')
429n/a
430n/a # try to cache the compiled code
4310 try:
4320 f = open(pathname + _suffix_char, 'wb')
4330 except IOError:
4340 pass
435n/a else:
4360 f.write('\0\0\0\0')
4370 f.write(struct.pack('<I', timestamp))
4380 marshal.dump(code, f)
4390 f.flush()
4400 f.seek(0, 0)
4410 f.write(imp.get_magic())
4420 f.close()
443n/a
4440 return code
445n/a
4461_os_stat = _os_path_join = None
4471def _os_bootstrap():
448n/a "Set up 'os' module replacement functions for use during import bootstrap."
449n/a
4500 names = sys.builtin_module_names
451n/a
4520 join = None
4530 if 'posix' in names:
4540 sep = '/'
4550 from posix import stat
4560 elif 'nt' in names:
4570 sep = '\\'
4580 from nt import stat
4590 elif 'dos' in names:
4600 sep = '\\'
4610 from dos import stat
4620 elif 'os2' in names:
4630 sep = '\\'
4640 from os2 import stat
465n/a else:
4660 raise ImportError, 'no os specific module found'
467n/a
4680 if join is None:
4690 def join(a, b, sep=sep):
4700 if a == '':
4710 return b
4720 lastchar = a[-1:]
4730 if lastchar == '/' or lastchar == sep:
4740 return a + b
4750 return a + sep + b
476n/a
477n/a global _os_stat
4780 _os_stat = stat
479n/a
480n/a global _os_path_join
4810 _os_path_join = join
482n/a
4831def _os_path_isdir(pathname):
484n/a "Local replacement for os.path.isdir()."
4850 try:
4860 s = _os_stat(pathname)
4870 except OSError:
4880 return None
4890 return (s.st_mode & 0170000) == 0040000
490n/a
4911def _timestamp(pathname):
492n/a "Return the file modification time as a Long."
4930 try:
4940 s = _os_stat(pathname)
4950 except OSError:
4960 return None
4970 return long(s.st_mtime)
498n/a
499n/a
500n/a######################################################################
501n/a#
502n/a# Emulate the import mechanism for builtin and frozen modules
503n/a#
5042class BuiltinImporter(Importer):
5051 def get_code(self, parent, modname, fqname):
5060 if parent:
507n/a # these modules definitely do not occur within a package context
5080 return None
509n/a
510n/a # look for the module
5110 if imp.is_builtin(modname):
5120 type = imp.C_BUILTIN
5130 elif imp.is_frozen(modname):
5140 type = imp.PY_FROZEN
515n/a else:
516n/a # not found
5170 return None
518n/a
519n/a # got it. now load and return it.
5200 module = imp.load_module(modname, None, modname, ('', '', type))
5210 return 0, module, { }
522n/a
523n/a
524n/a######################################################################
525n/a#
526n/a# Internal importer used for importing from the filesystem
527n/a#
5282class _FilesystemImporter(Importer):
5291 def __init__(self):
5300 self.suffixes = [ ]
531n/a
5321 def add_suffix(self, suffix, importFunc):
5330 assert hasattr(importFunc, '__call__')
5340 self.suffixes.append((suffix, importFunc))
535n/a
5361 def import_from_dir(self, dir, fqname):
5370 result = self._import_pathname(_os_path_join(dir, fqname), fqname)
5380 if result:
5390 return self._process_result(result, fqname)
5400 return None
541n/a
5421 def get_code(self, parent, modname, fqname):
543n/a # This importer is never used with an empty parent. Its existence is
544n/a # private to the ImportManager. The ImportManager uses the
545n/a # import_from_dir() method to import top-level modules/packages.
546n/a # This method is only used when we look for a module within a package.
5470 assert parent
548n/a
5490 for submodule_path in parent.__path__:
5500 code = self._import_pathname(_os_path_join(submodule_path, modname), fqname)
5510 if code is not None:
5520 return code
5530 return self._import_pathname(_os_path_join(parent.__pkgdir__, modname),
5540 fqname)
555n/a
5561 def _import_pathname(self, pathname, fqname):
5570 if _os_path_isdir(pathname):
5580 result = self._import_pathname(_os_path_join(pathname, '__init__'),
5590 fqname)
5600 if result:
5610 values = result[2]
5620 values['__pkgdir__'] = pathname
5630 values['__path__'] = [ pathname ]
5640 return 1, result[1], values
5650 return None
566n/a
5670 for suffix, importFunc in self.suffixes:
5680 filename = pathname + suffix
5690 try:
5700 finfo = _os_stat(filename)
5710 except OSError:
5720 pass
573n/a else:
5740 return importFunc(filename, finfo, fqname)
5750 return None
576n/a
577n/a######################################################################
578n/a#
579n/a# SUFFIX-BASED IMPORTERS
580n/a#
581n/a
5821def py_suffix_importer(filename, finfo, fqname):
5830 file = filename[:-3] + _suffix
5840 t_py = long(finfo[8])
5850 t_pyc = _timestamp(file)
586n/a
5870 code = None
5880 if t_pyc is not None and t_pyc >= t_py:
5890 f = open(file, 'rb')
5900 if f.read(4) == imp.get_magic():
5910 t = struct.unpack('<I', f.read(4))[0]
5920 if t == t_py:
5930 code = marshal.load(f)
5940 f.close()
5950 if code is None:
5960 file = filename
5970 code = _compile(file, t_py)
598n/a
5990 return 0, code, { '__file__' : file }
600n/a
6012class DynLoadSuffixImporter:
6021 def __init__(self, desc):
6030 self.desc = desc
604n/a
6051 def import_file(self, filename, finfo, fqname):
6060 fp = open(filename, self.desc[1])
6070 module = imp.load_module(fqname, fp, filename, self.desc)
6080 module.__file__ = filename
6090 return 0, module, { }
610n/a
611n/a
612n/a######################################################################
613n/a
6141def _print_importers():
6150 items = sys.modules.items()
6160 items.sort()
6170 for name, module in items:
6180 if module:
6190 print name, module.__dict__.get('__importer__', '-- no importer')
620n/a else:
6210 print name, '-- non-existent module'
622n/a
6231def _test_revamp():
6240 ImportManager().install()
6250 sys.path.insert(0, BuiltinImporter())
626n/a
627n/a######################################################################
628n/a
629n/a#
630n/a# TODO
631n/a#
632n/a# from Finn Bock:
633n/a# type(sys) is not a module in Jython. what to use instead?
634n/a# imp.C_EXTENSION is not in Jython. same for get_suffixes and new_module
635n/a#
636n/a# given foo.py of:
637n/a# import sys
638n/a# sys.modules['foo'] = sys
639n/a#
640n/a# ---- standard import mechanism
641n/a# >>> import foo
642n/a# >>> foo
643n/a# <module 'sys' (built-in)>
644n/a#
645n/a# ---- revamped import mechanism
646n/a# >>> import imputil
647n/a# >>> imputil._test_revamp()
648n/a# >>> import foo
649n/a# >>> foo
650n/a# <module 'foo' from 'foo.py'>
651n/a#
652n/a#
653n/a# from MAL:
654n/a# should BuiltinImporter exist in sys.path or hard-wired in ImportManager?
655n/a# need __path__ processing
656n/a# performance
657n/a# move chaining to a subclass [gjs: it's been nuked]
658n/a# deinstall should be possible
659n/a# query mechanism needed: is a specific Importer installed?
660n/a# py/pyc/pyo piping hooks to filter/process these files
661n/a# wish list:
662n/a# distutils importer hooked to list of standard Internet repositories
663n/a# module->file location mapper to speed FS-based imports
664n/a# relative imports
665n/a# keep chaining so that it can play nice with other import hooks
666n/a#
667n/a# from Gordon:
668n/a# push MAL's mapper into sys.path[0] as a cache (hard-coded for apps)
669n/a#
670n/a# from Guido:
671n/a# need to change sys.* references for rexec environs
672n/a# need hook for MAL's walk-me-up import strategy, or Tim's absolute strategy
673n/a# watch out for sys.modules[...] is None
674n/a# flag to force absolute imports? (speeds _determine_import_context and
675n/a# checking for a relative module)
676n/a# insert names of archives into sys.path (see quote below)
677n/a# note: reload does NOT blast module dict
678n/a# shift import mechanisms and policies around; provide for hooks, overrides
679n/a# (see quote below)
680n/a# add get_source stuff
681n/a# get_topcode and get_subcode
682n/a# CRLF handling in _compile
683n/a# race condition in _compile
684n/a# refactoring of os.py to deal with _os_bootstrap problem
685n/a# any special handling to do for importing a module with a SyntaxError?
686n/a# (e.g. clean up the traceback)
687n/a# implement "domain" for path-type functionality using pkg namespace
688n/a# (rather than FS-names like __path__)
689n/a# don't use the word "private"... maybe "internal"
690n/a#
691n/a#
692n/a# Guido's comments on sys.path caching:
693n/a#
694n/a# We could cache this in a dictionary: the ImportManager can have a
695n/a# cache dict mapping pathnames to importer objects, and a separate
696n/a# method for coming up with an importer given a pathname that's not yet
697n/a# in the cache. The method should do a stat and/or look at the
698n/a# extension to decide which importer class to use; you can register new
699n/a# importer classes by registering a suffix or a Boolean function, plus a
700n/a# class. If you register a new importer class, the cache is zapped.
701n/a# The cache is independent from sys.path (but maintained per
702n/a# ImportManager instance) so that rearrangements of sys.path do the
703n/a# right thing. If a path is dropped from sys.path the corresponding
704n/a# cache entry is simply no longer used.
705n/a#
706n/a# My/Guido's comments on factoring ImportManager and Importer:
707n/a#
708n/a# > However, we still have a tension occurring here:
709n/a# >
710n/a# > 1) implementing policy in ImportManager assists in single-point policy
711n/a# > changes for app/rexec situations
712n/a# > 2) implementing policy in Importer assists in package-private policy
713n/a# > changes for normal, operating conditions
714n/a# >
715n/a# > I'll see if I can sort out a way to do this. Maybe the Importer class will
716n/a# > implement the methods (which can be overridden to change policy) by
717n/a# > delegating to ImportManager.
718n/a#
719n/a# Maybe also think about what kind of policies an Importer would be
720n/a# likely to want to change. I have a feeling that a lot of the code
721n/a# there is actually not so much policy but a *necessity* to get things
722n/a# working given the calling conventions for the __import__ hook: whether
723n/a# to return the head or tail of a dotted name, or when to do the "finish
724n/a# fromlist" stuff.
725n/a#