mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 02:15:10 +00:00 
			
		
		
		
	 cf297e46b8
			
		
	
	
		cf297e46b8
		
	
	
	
	
		
			
			svn+ssh://pythondev@svn.python.org/python/trunk
........
  r53624 | peter.astrand | 2007-02-02 20:06:36 +0100 (Fri, 02 Feb 2007) | 1 line
  We had several if statements checking the value of a fd. This is unsafe, since valid fds might be zero. We should check for not None instead.
........
  r53635 | kurt.kaiser | 2007-02-05 07:03:18 +0100 (Mon, 05 Feb 2007) | 2 lines
  Add 'raw' support to configHandler. Patch 1650174 Tal Einat.
........
  r53641 | kurt.kaiser | 2007-02-06 00:02:16 +0100 (Tue, 06 Feb 2007) | 5 lines
  1. Calltips now 'handle' tuples in the argument list (display '<tuple>' :)
     Suggested solution by Christos Georgiou, Bug 791968.
  2. Clean up tests, were not failing when they should have been.
  4. Remove some camelcase and an unneeded try/except block.
........
  r53644 | kurt.kaiser | 2007-02-06 04:21:40 +0100 (Tue, 06 Feb 2007) | 2 lines
  Clean up ModifiedInterpreter.runcode() structure
........
  r53646 | peter.astrand | 2007-02-06 16:37:50 +0100 (Tue, 06 Feb 2007) | 1 line
  Applied patch 1124861.3.patch to solve bug #1124861: Automatically create pipes on Windows, if GetStdHandle fails. Will backport.
........
  r53648 | lars.gustaebel | 2007-02-06 19:38:13 +0100 (Tue, 06 Feb 2007) | 4 lines
  Patch #1652681: create nonexistent files in append mode and
  allow appending to empty files.
........
  r53649 | kurt.kaiser | 2007-02-06 20:09:43 +0100 (Tue, 06 Feb 2007) | 4 lines
  Updated patch (CodeContext.061217.patch) to
  [ 1362975 ] CodeContext - Improved text indentation
  Tal Einat 16Dec06
........
  r53650 | kurt.kaiser | 2007-02-06 20:21:19 +0100 (Tue, 06 Feb 2007) | 2 lines
  narrow exception per [ 1540849 ] except too broad
........
  r53653 | kurt.kaiser | 2007-02-07 04:39:41 +0100 (Wed, 07 Feb 2007) | 4 lines
  [ 1621265 ] Auto-completion list placement
  Move AC window below input line unless not enough space, then put it above.
  Patch: Tal Einat
........
  r53654 | kurt.kaiser | 2007-02-07 09:07:13 +0100 (Wed, 07 Feb 2007) | 2 lines
  Handle AttributeError during calltip lookup
........
  r53656 | raymond.hettinger | 2007-02-07 21:08:22 +0100 (Wed, 07 Feb 2007) | 3 lines
  SF #1615701:  make d.update(m) honor __getitem__() and keys() in dict subclasses
........
  r53658 | raymond.hettinger | 2007-02-07 22:04:20 +0100 (Wed, 07 Feb 2007) | 1 line
  SF: 1397711 Set docs conflated immutable and hashable
........
  r53660 | raymond.hettinger | 2007-02-07 22:42:17 +0100 (Wed, 07 Feb 2007) | 1 line
  Check for a common user error with defaultdict().
........
  r53662 | raymond.hettinger | 2007-02-07 23:24:07 +0100 (Wed, 07 Feb 2007) | 1 line
  Bug #1575169: operator.isSequenceType() now returns False for subclasses of dict.
........
  r53664 | raymond.hettinger | 2007-02-08 00:49:03 +0100 (Thu, 08 Feb 2007) | 1 line
  Silence compiler warning
........
  r53666 | raymond.hettinger | 2007-02-08 01:07:32 +0100 (Thu, 08 Feb 2007) | 1 line
  Do not let overflows in enumerate() and count() pass silently.
........
  r53668 | raymond.hettinger | 2007-02-08 01:50:39 +0100 (Thu, 08 Feb 2007) | 1 line
  Bypass set specific optimizations for set and frozenset subclasses.
........
  r53670 | raymond.hettinger | 2007-02-08 02:42:35 +0100 (Thu, 08 Feb 2007) | 1 line
  Fix docstring bug
........
  r53671 | martin.v.loewis | 2007-02-08 10:13:36 +0100 (Thu, 08 Feb 2007) | 3 lines
  Bug #1653736: Complain about keyword arguments to time.isoformat.
  Will backport to 2.5.
........
  r53679 | kurt.kaiser | 2007-02-08 23:58:18 +0100 (Thu, 08 Feb 2007) | 6 lines
  Corrected some bugs in AutoComplete.  Also, Page Up/Down in ACW implemented;
  mouse and cursor selection in ACWindow implemented; double Tab inserts current
  selection and closes ACW (similar to double-click and Return); scroll wheel now
  works in ACW.  Added AutoComplete instructions to IDLE Help.
........
  r53689 | martin.v.loewis | 2007-02-09 13:19:32 +0100 (Fri, 09 Feb 2007) | 3 lines
  Bug #1653736: Properly discard third argument to slot_nb_inplace_power.
  Will backport.
........
  r53691 | martin.v.loewis | 2007-02-09 13:36:48 +0100 (Fri, 09 Feb 2007) | 4 lines
  Bug #1600860: Search for shared python library in LIBDIR, not
  lib/python/config, on "linux" and "gnu" systems.
  Will backport.
........
  r53693 | martin.v.loewis | 2007-02-09 13:58:49 +0100 (Fri, 09 Feb 2007) | 2 lines
  Update broken link. Will backport to 2.5.
........
  r53697 | georg.brandl | 2007-02-09 19:48:41 +0100 (Fri, 09 Feb 2007) | 2 lines
  Bug #1656078: typo in in profile docs.
........
  r53731 | brett.cannon | 2007-02-11 06:36:00 +0100 (Sun, 11 Feb 2007) | 3 lines
  Change a very minor inconsistency (that is purely cosmetic) in the AST
  definition.
........
  r53735 | skip.montanaro | 2007-02-11 19:24:37 +0100 (Sun, 11 Feb 2007) | 1 line
  fix trace.py --ignore-dir
........
  r53741 | brett.cannon | 2007-02-11 20:44:41 +0100 (Sun, 11 Feb 2007) | 3 lines
  Check in changed Python-ast.c from a cosmetic change to Python.asdl (in
  r53731).
........
  r53751 | brett.cannon | 2007-02-12 04:51:02 +0100 (Mon, 12 Feb 2007) | 5 lines
  Modify Parser/asdl_c.py so that the __version__ number for Python/Python-ast.c
  is specified at the top of the file.  Also add a note that Python/Python-ast.c
  needs to be committed separately after a change to the AST grammar to capture
  the revision number of the change (which is what __version__ is set to).
........
  r53752 | lars.gustaebel | 2007-02-12 10:25:53 +0100 (Mon, 12 Feb 2007) | 3 lines
  Bug #1656581: Point out that external file objects are supposed to be
  at position 0.
........
  r53754 | martin.v.loewis | 2007-02-12 13:21:10 +0100 (Mon, 12 Feb 2007) | 3 lines
  Patch 1463026: Support default namespace in XMLGenerator.
  Fixes #847665. Will backport.
........
  r53757 | armin.rigo | 2007-02-12 17:23:24 +0100 (Mon, 12 Feb 2007) | 4 lines
  Fix the line to what is my guess at the original author's meaning.
  (The line has no effect anyway, but is present because it's
  customary call the base class __init__).
........
  r53763 | martin.v.loewis | 2007-02-13 09:34:45 +0100 (Tue, 13 Feb 2007) | 3 lines
  Patch #685268: Consider a package's __path__ in imputil.
  Will backport.
........
  r53765 | martin.v.loewis | 2007-02-13 10:49:38 +0100 (Tue, 13 Feb 2007) | 2 lines
  Patch #698833: Support file decryption in zipfile.
........
  r53766 | martin.v.loewis | 2007-02-13 11:10:39 +0100 (Tue, 13 Feb 2007) | 3 lines
  Patch #1517891: Make 'a' create the file if it doesn't exist.
  Fixes #1514451.
........
  r53767 | martin.v.loewis | 2007-02-13 13:08:24 +0100 (Tue, 13 Feb 2007) | 3 lines
  Bug #1658794: Remove extraneous 'this'.
  Will backport to 2.5.
........
  r53769 | martin.v.loewis | 2007-02-13 13:14:19 +0100 (Tue, 13 Feb 2007) | 3 lines
  Patch #1657276: Make NETLINK_DNRTMSG conditional.
  Will backport.
........
  r53771 | lars.gustaebel | 2007-02-13 17:09:24 +0100 (Tue, 13 Feb 2007) | 4 lines
  Patch #1647484: Renamed GzipFile's filename attribute to name. The
  filename attribute is still accessible as a property that emits a
  DeprecationWarning.
........
  r53772 | lars.gustaebel | 2007-02-13 17:24:00 +0100 (Tue, 13 Feb 2007) | 3 lines
  Strip the '.gz' extension from the filename that is written to the
  gzip header.
........
  r53774 | martin.v.loewis | 2007-02-14 11:07:37 +0100 (Wed, 14 Feb 2007) | 2 lines
  Patch #1432399: Add HCI sockets.
........
  r53775 | martin.v.loewis | 2007-02-14 12:30:07 +0100 (Wed, 14 Feb 2007) | 2 lines
  Update 1432399 to removal of _BT_SOCKADDR_MEMB.
........
  r53776 | martin.v.loewis | 2007-02-14 12:30:56 +0100 (Wed, 14 Feb 2007) | 3 lines
  Ignore directory time stamps when considering
  whether to rerun libffi configure.
........
  r53778 | lars.gustaebel | 2007-02-14 15:45:12 +0100 (Wed, 14 Feb 2007) | 4 lines
  A missing binary mode in AppendTest caused failures in Windows
  Buildbot.
........
  r53782 | martin.v.loewis | 2007-02-15 10:51:35 +0100 (Thu, 15 Feb 2007) | 2 lines
  Patch #1397848: add the reasoning behind no-resize-on-shrinkage.
........
  r53783 | georg.brandl | 2007-02-15 11:37:59 +0100 (Thu, 15 Feb 2007) | 2 lines
  Make functools.wraps() docs a bit clearer.
........
  r53785 | georg.brandl | 2007-02-15 12:29:04 +0100 (Thu, 15 Feb 2007) | 2 lines
  Patch #1494140: Add documentation for the new struct.Struct object.
........
  r53787 | georg.brandl | 2007-02-15 12:29:55 +0100 (Thu, 15 Feb 2007) | 2 lines
  Add missing \versionadded.
........
  r53800 | brett.cannon | 2007-02-15 23:54:39 +0100 (Thu, 15 Feb 2007) | 11 lines
  Update the encoding package's search function to use absolute imports when
  calling __import__.  This helps make the expected search locations for encoding
  modules be more explicit.
  One could use an explicit value for __path__ when making the call to __import__
  to force the exact location searched for encodings.  This would give the most
  strict search path possible if one is worried about malicious code being
  imported.  The unfortunate side-effect of that is that if __path__ was modified
  on 'encodings' on purpose in a safe way it would not be picked up in future
  __import__ calls.
........
  r53801 | brett.cannon | 2007-02-16 20:33:01 +0100 (Fri, 16 Feb 2007) | 2 lines
  Make the __import__ call in encodings.__init__ absolute with a level 0 call.
........
  r53809 | vinay.sajip | 2007-02-16 23:36:24 +0100 (Fri, 16 Feb 2007) | 1 line
  Minor fix for currentframe (SF #1652788).
........
  r53818 | raymond.hettinger | 2007-02-19 03:03:19 +0100 (Mon, 19 Feb 2007) | 3 lines
  Extend work on revision 52962:  Eliminate redundant calls to PyObject_Hash().
........
  r53820 | raymond.hettinger | 2007-02-19 05:08:43 +0100 (Mon, 19 Feb 2007) | 1 line
  Add merge() function to heapq.
........
  r53821 | raymond.hettinger | 2007-02-19 06:28:28 +0100 (Mon, 19 Feb 2007) | 1 line
  Add tie-breaker count to preserve sort stability.
........
  r53822 | raymond.hettinger | 2007-02-19 07:59:32 +0100 (Mon, 19 Feb 2007) | 1 line
  Use C heapreplace() instead of slower _siftup() in pure python.
........
  r53823 | raymond.hettinger | 2007-02-19 08:30:21 +0100 (Mon, 19 Feb 2007) | 1 line
  Add test for merge stability
........
  r53824 | raymond.hettinger | 2007-02-19 10:14:10 +0100 (Mon, 19 Feb 2007) | 1 line
  Provide an example of defaultdict with non-zero constant factory function.
........
  r53825 | lars.gustaebel | 2007-02-19 10:54:47 +0100 (Mon, 19 Feb 2007) | 2 lines
  Moved misplaced news item.
........
  r53826 | martin.v.loewis | 2007-02-19 11:55:19 +0100 (Mon, 19 Feb 2007) | 3 lines
  Patch #1490190: posixmodule now includes os.chflags() and os.lchflags()
  functions on platforms where the underlying system calls are available.
........
  r53827 | raymond.hettinger | 2007-02-19 19:15:04 +0100 (Mon, 19 Feb 2007) | 1 line
  Fixup docstrings for merge().
........
  r53829 | raymond.hettinger | 2007-02-19 21:44:04 +0100 (Mon, 19 Feb 2007) | 1 line
  Fixup set/dict interoperability.
........
  r53837 | raymond.hettinger | 2007-02-21 06:20:38 +0100 (Wed, 21 Feb 2007) | 1 line
  Add itertools.izip_longest().
........
  r53838 | raymond.hettinger | 2007-02-21 18:22:05 +0100 (Wed, 21 Feb 2007) | 1 line
  Remove filler struct item and fix leak.
........
		
	
			
		
			
				
	
	
		
			731 lines
		
	
	
	
		
			25 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			731 lines
		
	
	
	
		
			25 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | |
| Import utilities
 | |
| 
 | |
| Exported classes:
 | |
|     ImportManager   Manage the import process
 | |
| 
 | |
|     Importer        Base class for replacing standard import functions
 | |
|     BuiltinImporter Emulate the import mechanism for builtin and frozen modules
 | |
| 
 | |
|     DynLoadSuffixImporter
 | |
| """
 | |
| 
 | |
| # note: avoid importing non-builtin modules
 | |
| import imp                      ### not available in JPython?
 | |
| import sys
 | |
| import __builtin__
 | |
| 
 | |
| # for the DirectoryImporter
 | |
| import struct
 | |
| import marshal
 | |
| 
 | |
| __all__ = ["ImportManager","Importer","BuiltinImporter"]
 | |
| 
 | |
| _StringType = type('')
 | |
| _ModuleType = type(sys)         ### doesn't work in JPython...
 | |
| 
 | |
| class ImportManager:
 | |
|     "Manage the import process."
 | |
| 
 | |
|     def install(self, namespace=vars(__builtin__)):
 | |
|         "Install this ImportManager into the specified namespace."
 | |
| 
 | |
|         if isinstance(namespace, _ModuleType):
 | |
|             namespace = vars(namespace)
 | |
| 
 | |
|         # Note: we have no notion of "chaining"
 | |
| 
 | |
|         # Record the previous import hook, then install our own.
 | |
|         self.previous_importer = namespace['__import__']
 | |
|         self.namespace = namespace
 | |
|         namespace['__import__'] = self._import_hook
 | |
| 
 | |
|         ### fix this
 | |
|         #namespace['reload'] = self._reload_hook
 | |
| 
 | |
|     def uninstall(self):
 | |
|         "Restore the previous import mechanism."
 | |
|         self.namespace['__import__'] = self.previous_importer
 | |
| 
 | |
|     def add_suffix(self, suffix, importFunc):
 | |
|         assert callable(importFunc)
 | |
|         self.fs_imp.add_suffix(suffix, importFunc)
 | |
| 
 | |
|     ######################################################################
 | |
|     #
 | |
|     # PRIVATE METHODS
 | |
|     #
 | |
| 
 | |
|     clsFilesystemImporter = None
 | |
| 
 | |
|     def __init__(self, fs_imp=None):
 | |
|         # we're definitely going to be importing something in the future,
 | |
|         # so let's just load the OS-related facilities.
 | |
|         if not _os_stat:
 | |
|             _os_bootstrap()
 | |
| 
 | |
|         # This is the Importer that we use for grabbing stuff from the
 | |
|         # filesystem. It defines one more method (import_from_dir) for our use.
 | |
|         if fs_imp is None:
 | |
|             cls = self.clsFilesystemImporter or _FilesystemImporter
 | |
|             fs_imp = cls()
 | |
|         self.fs_imp = fs_imp
 | |
| 
 | |
|         # Initialize the set of suffixes that we recognize and import.
 | |
|         # The default will import dynamic-load modules first, followed by
 | |
|         # .py files (or a .py file's cached bytecode)
 | |
|         for desc in imp.get_suffixes():
 | |
|             if desc[2] == imp.C_EXTENSION:
 | |
|                 self.add_suffix(desc[0],
 | |
|                                 DynLoadSuffixImporter(desc).import_file)
 | |
|         self.add_suffix('.py', py_suffix_importer)
 | |
| 
 | |
|     def _import_hook(self, fqname, globals=None, locals=None, fromlist=None):
 | |
|         """Python calls this hook to locate and import a module."""
 | |
| 
 | |
|         parts = fqname.split('.')
 | |
| 
 | |
|         # determine the context of this import
 | |
|         parent = self._determine_import_context(globals)
 | |
| 
 | |
|         # if there is a parent, then its importer should manage this import
 | |
|         if parent:
 | |
|             module = parent.__importer__._do_import(parent, parts, fromlist)
 | |
|             if module:
 | |
|                 return module
 | |
| 
 | |
|         # has the top module already been imported?
 | |
|         try:
 | |
|             top_module = sys.modules[parts[0]]
 | |
|         except KeyError:
 | |
| 
 | |
|             # look for the topmost module
 | |
|             top_module = self._import_top_module(parts[0])
 | |
|             if not top_module:
 | |
|                 # the topmost module wasn't found at all.
 | |
|                 raise ImportError, 'No module named ' + fqname
 | |
| 
 | |
|         # fast-path simple imports
 | |
|         if len(parts) == 1:
 | |
|             if not fromlist:
 | |
|                 return top_module
 | |
| 
 | |
|             if not top_module.__dict__.get('__ispkg__'):
 | |
|                 # __ispkg__ isn't defined (the module was not imported by us),
 | |
|                 # or it is zero.
 | |
|                 #
 | |
|                 # In the former case, there is no way that we could import
 | |
|                 # sub-modules that occur in the fromlist (but we can't raise an
 | |
|                 # error because it may just be names) because we don't know how
 | |
|                 # to deal with packages that were imported by other systems.
 | |
|                 #
 | |
|                 # In the latter case (__ispkg__ == 0), there can't be any sub-
 | |
|                 # modules present, so we can just return.
 | |
|                 #
 | |
|                 # In both cases, since len(parts) == 1, the top_module is also
 | |
|                 # the "bottom" which is the defined return when a fromlist
 | |
|                 # exists.
 | |
|                 return top_module
 | |
| 
 | |
|         importer = top_module.__dict__.get('__importer__')
 | |
|         if importer:
 | |
|             return importer._finish_import(top_module, parts[1:], fromlist)
 | |
| 
 | |
|         # Grrr, some people "import os.path" or do "from os.path import ..."
 | |
|         if len(parts) == 2 and hasattr(top_module, parts[1]):
 | |
|             if fromlist:
 | |
|                 return getattr(top_module, parts[1])
 | |
|             else:
 | |
|                 return top_module
 | |
| 
 | |
|         # If the importer does not exist, then we have to bail. A missing
 | |
|         # importer means that something else imported the module, and we have
 | |
|         # no knowledge of how to get sub-modules out of the thing.
 | |
|         raise ImportError, 'No module named ' + fqname
 | |
| 
 | |
|     def _determine_import_context(self, globals):
 | |
|         """Returns the context in which a module should be imported.
 | |
| 
 | |
|         The context could be a loaded (package) module and the imported module
 | |
|         will be looked for within that package. The context could also be None,
 | |
|         meaning there is no context -- the module should be looked for as a
 | |
|         "top-level" module.
 | |
|         """
 | |
| 
 | |
|         if not globals or not globals.get('__importer__'):
 | |
|             # globals does not refer to one of our modules or packages. That
 | |
|             # implies there is no relative import context (as far as we are
 | |
|             # concerned), and it should just pick it off the standard path.
 | |
|             return None
 | |
| 
 | |
|         # The globals refer to a module or package of ours. It will define
 | |
|         # the context of the new import. Get the module/package fqname.
 | |
|         parent_fqname = globals['__name__']
 | |
| 
 | |
|         # if a package is performing the import, then return itself (imports
 | |
|         # refer to pkg contents)
 | |
|         if globals['__ispkg__']:
 | |
|             parent = sys.modules[parent_fqname]
 | |
|             assert globals is parent.__dict__
 | |
|             return parent
 | |
| 
 | |
|         i = parent_fqname.rfind('.')
 | |
| 
 | |
|         # a module outside of a package has no particular import context
 | |
|         if i == -1:
 | |
|             return None
 | |
| 
 | |
|         # if a module in a package is performing the import, then return the
 | |
|         # package (imports refer to siblings)
 | |
|         parent_fqname = parent_fqname[:i]
 | |
|         parent = sys.modules[parent_fqname]
 | |
|         assert parent.__name__ == parent_fqname
 | |
|         return parent
 | |
| 
 | |
|     def _import_top_module(self, name):
 | |
|         # scan sys.path looking for a location in the filesystem that contains
 | |
|         # the module, or an Importer object that can import the module.
 | |
|         for item in sys.path:
 | |
|             if isinstance(item, _StringType):
 | |
|                 module = self.fs_imp.import_from_dir(item, name)
 | |
|             else:
 | |
|                 module = item.import_top(name)
 | |
|             if module:
 | |
|                 return module
 | |
|         return None
 | |
| 
 | |
|     def _reload_hook(self, module):
 | |
|         "Python calls this hook to reload a module."
 | |
| 
 | |
|         # reloading of a module may or may not be possible (depending on the
 | |
|         # importer), but at least we can validate that it's ours to reload
 | |
|         importer = module.__dict__.get('__importer__')
 | |
|         if not importer:
 | |
|             ### oops. now what...
 | |
|             pass
 | |
| 
 | |
|         # okay. it is using the imputil system, and we must delegate it, but
 | |
|         # we don't know what to do (yet)
 | |
|         ### we should blast the module dict and do another get_code(). need to
 | |
|         ### flesh this out and add proper docco...
 | |
|         raise SystemError, "reload not yet implemented"
 | |
| 
 | |
| 
 | |
| class Importer:
 | |
|     "Base class for replacing standard import functions."
 | |
| 
 | |
|     def import_top(self, name):
 | |
|         "Import a top-level module."
 | |
|         return self._import_one(None, name, name)
 | |
| 
 | |
|     ######################################################################
 | |
|     #
 | |
|     # PRIVATE METHODS
 | |
|     #
 | |
|     def _finish_import(self, top, parts, fromlist):
 | |
|         # if "a.b.c" was provided, then load the ".b.c" portion down from
 | |
|         # below the top-level module.
 | |
|         bottom = self._load_tail(top, parts)
 | |
| 
 | |
|         # if the form is "import a.b.c", then return "a"
 | |
|         if not fromlist:
 | |
|             # no fromlist: return the top of the import tree
 | |
|             return top
 | |
| 
 | |
|         # the top module was imported by self.
 | |
|         #
 | |
|         # this means that the bottom module was also imported by self (just
 | |
|         # now, or in the past and we fetched it from sys.modules).
 | |
|         #
 | |
|         # since we imported/handled the bottom module, this means that we can
 | |
|         # also handle its fromlist (and reliably use __ispkg__).
 | |
| 
 | |
|         # if the bottom node is a package, then (potentially) import some
 | |
|         # modules.
 | |
|         #
 | |
|         # note: if it is not a package, then "fromlist" refers to names in
 | |
|         #       the bottom module rather than modules.
 | |
|         # note: for a mix of names and modules in the fromlist, we will
 | |
|         #       import all modules and insert those into the namespace of
 | |
|         #       the package module. Python will pick up all fromlist names
 | |
|         #       from the bottom (package) module; some will be modules that
 | |
|         #       we imported and stored in the namespace, others are expected
 | |
|         #       to be present already.
 | |
|         if bottom.__ispkg__:
 | |
|             self._import_fromlist(bottom, fromlist)
 | |
| 
 | |
|         # if the form is "from a.b import c, d" then return "b"
 | |
|         return bottom
 | |
| 
 | |
|     def _import_one(self, parent, modname, fqname):
 | |
|         "Import a single module."
 | |
| 
 | |
|         # has the module already been imported?
 | |
|         try:
 | |
|             return sys.modules[fqname]
 | |
|         except KeyError:
 | |
|             pass
 | |
| 
 | |
|         # load the module's code, or fetch the module itself
 | |
|         result = self.get_code(parent, modname, fqname)
 | |
|         if result is None:
 | |
|             return None
 | |
| 
 | |
|         module = self._process_result(result, fqname)
 | |
| 
 | |
|         # insert the module into its parent
 | |
|         if parent:
 | |
|             setattr(parent, modname, module)
 | |
|         return module
 | |
| 
 | |
|     def _process_result(self, (ispkg, code, values), fqname):
 | |
|         # did get_code() return an actual module? (rather than a code object)
 | |
|         is_module = isinstance(code, _ModuleType)
 | |
| 
 | |
|         # use the returned module, or create a new one to exec code into
 | |
|         if is_module:
 | |
|             module = code
 | |
|         else:
 | |
|             module = imp.new_module(fqname)
 | |
| 
 | |
|         ### record packages a bit differently??
 | |
|         module.__importer__ = self
 | |
|         module.__ispkg__ = ispkg
 | |
| 
 | |
|         # insert additional values into the module (before executing the code)
 | |
|         module.__dict__.update(values)
 | |
| 
 | |
|         # the module is almost ready... make it visible
 | |
|         sys.modules[fqname] = module
 | |
| 
 | |
|         # execute the code within the module's namespace
 | |
|         if not is_module:
 | |
|             try:
 | |
|                 exec(code, module.__dict__)
 | |
|             except:
 | |
|                 if fqname in sys.modules:
 | |
|                     del sys.modules[fqname]
 | |
|                 raise
 | |
| 
 | |
|         # fetch from sys.modules instead of returning module directly.
 | |
|         # also make module's __name__ agree with fqname, in case
 | |
|         # the "exec code in module.__dict__" played games on us.
 | |
|         module = sys.modules[fqname]
 | |
|         module.__name__ = fqname
 | |
|         return module
 | |
| 
 | |
|     def _load_tail(self, m, parts):
 | |
|         """Import the rest of the modules, down from the top-level module.
 | |
| 
 | |
|         Returns the last module in the dotted list of modules.
 | |
|         """
 | |
|         for part in parts:
 | |
|             fqname = "%s.%s" % (m.__name__, part)
 | |
|             m = self._import_one(m, part, fqname)
 | |
|             if not m:
 | |
|                 raise ImportError, "No module named " + fqname
 | |
|         return m
 | |
| 
 | |
|     def _import_fromlist(self, package, fromlist):
 | |
|         'Import any sub-modules in the "from" list.'
 | |
| 
 | |
|         # if '*' is present in the fromlist, then look for the '__all__'
 | |
|         # variable to find additional items (modules) to import.
 | |
|         if '*' in fromlist:
 | |
|             fromlist = list(fromlist) + \
 | |
|                        list(package.__dict__.get('__all__', []))
 | |
| 
 | |
|         for sub in fromlist:
 | |
|             # if the name is already present, then don't try to import it (it
 | |
|             # might not be a module!).
 | |
|             if sub != '*' and not hasattr(package, sub):
 | |
|                 subname = "%s.%s" % (package.__name__, sub)
 | |
|                 submod = self._import_one(package, sub, subname)
 | |
|                 if not submod:
 | |
|                     raise ImportError, "cannot import name " + subname
 | |
| 
 | |
|     def _do_import(self, parent, parts, fromlist):
 | |
|         """Attempt to import the module relative to parent.
 | |
| 
 | |
|         This method is used when the import context specifies that <self>
 | |
|         imported the parent module.
 | |
|         """
 | |
|         top_name = parts[0]
 | |
|         top_fqname = parent.__name__ + '.' + top_name
 | |
|         top_module = self._import_one(parent, top_name, top_fqname)
 | |
|         if not top_module:
 | |
|             # this importer and parent could not find the module (relatively)
 | |
|             return None
 | |
| 
 | |
|         return self._finish_import(top_module, parts[1:], fromlist)
 | |
| 
 | |
|     ######################################################################
 | |
|     #
 | |
|     # METHODS TO OVERRIDE
 | |
|     #
 | |
|     def get_code(self, parent, modname, fqname):
 | |
|         """Find and retrieve the code for the given module.
 | |
| 
 | |
|         parent specifies a parent module to define a context for importing. It
 | |
|         may be None, indicating no particular context for the search.
 | |
| 
 | |
|         modname specifies a single module (not dotted) within the parent.
 | |
| 
 | |
|         fqname specifies the fully-qualified module name. This is a
 | |
|         (potentially) dotted name from the "root" of the module namespace
 | |
|         down to the modname.
 | |
|         If there is no parent, then modname==fqname.
 | |
| 
 | |
|         This method should return None, or a 3-tuple.
 | |
| 
 | |
|         * If the module was not found, then None should be returned.
 | |
| 
 | |
|         * The first item of the 2- or 3-tuple should be the integer 0 or 1,
 | |
|             specifying whether the module that was found is a package or not.
 | |
| 
 | |
|         * The second item is the code object for the module (it will be
 | |
|             executed within the new module's namespace). This item can also
 | |
|             be a fully-loaded module object (e.g. loaded from a shared lib).
 | |
| 
 | |
|         * The third item is a dictionary of name/value pairs that will be
 | |
|             inserted into new module before the code object is executed. This
 | |
|             is provided in case the module's code expects certain values (such
 | |
|             as where the module was found). When the second item is a module
 | |
|             object, then these names/values will be inserted *after* the module
 | |
|             has been loaded/initialized.
 | |
|         """
 | |
|         raise RuntimeError, "get_code not implemented"
 | |
| 
 | |
| 
 | |
| ######################################################################
 | |
| #
 | |
| # Some handy stuff for the Importers
 | |
| #
 | |
| 
 | |
| # byte-compiled file suffix character
 | |
| _suffix_char = __debug__ and 'c' or 'o'
 | |
| 
 | |
| # byte-compiled file suffix
 | |
| _suffix = '.py' + _suffix_char
 | |
| 
 | |
| def _compile(pathname, timestamp):
 | |
|     """Compile (and cache) a Python source file.
 | |
| 
 | |
|     The file specified by <pathname> is compiled to a code object and
 | |
|     returned.
 | |
| 
 | |
|     Presuming the appropriate privileges exist, the bytecodes will be
 | |
|     saved back to the filesystem for future imports. The source file's
 | |
|     modification timestamp must be provided as a Long value.
 | |
|     """
 | |
|     codestring = open(pathname, 'rU').read()
 | |
|     if codestring and codestring[-1] != '\n':
 | |
|         codestring = codestring + '\n'
 | |
|     code = __builtin__.compile(codestring, pathname, 'exec')
 | |
| 
 | |
|     # try to cache the compiled code
 | |
|     try:
 | |
|         f = open(pathname + _suffix_char, 'wb')
 | |
|     except IOError:
 | |
|         pass
 | |
|     else:
 | |
|         f.write('\0\0\0\0')
 | |
|         f.write(struct.pack('<I', timestamp))
 | |
|         marshal.dump(code, f)
 | |
|         f.flush()
 | |
|         f.seek(0, 0)
 | |
|         f.write(imp.get_magic())
 | |
|         f.close()
 | |
| 
 | |
|     return code
 | |
| 
 | |
| _os_stat = _os_path_join = None
 | |
| def _os_bootstrap():
 | |
|     "Set up 'os' module replacement functions for use during import bootstrap."
 | |
| 
 | |
|     names = sys.builtin_module_names
 | |
| 
 | |
|     join = None
 | |
|     if 'posix' in names:
 | |
|         sep = '/'
 | |
|         from posix import stat
 | |
|     elif 'nt' in names:
 | |
|         sep = '\\'
 | |
|         from nt import stat
 | |
|     elif 'dos' in names:
 | |
|         sep = '\\'
 | |
|         from dos import stat
 | |
|     elif 'os2' in names:
 | |
|         sep = '\\'
 | |
|         from os2 import stat
 | |
|     elif 'mac' in names:
 | |
|         from mac import stat
 | |
|         def join(a, b):
 | |
|             if a == '':
 | |
|                 return b
 | |
|             if ':' not in a:
 | |
|                 a = ':' + a
 | |
|             if a[-1:] != ':':
 | |
|                 a = a + ':'
 | |
|             return a + b
 | |
|     else:
 | |
|         raise ImportError, 'no os specific module found'
 | |
| 
 | |
|     if join is None:
 | |
|         def join(a, b, sep=sep):
 | |
|             if a == '':
 | |
|                 return b
 | |
|             lastchar = a[-1:]
 | |
|             if lastchar == '/' or lastchar == sep:
 | |
|                 return a + b
 | |
|             return a + sep + b
 | |
| 
 | |
|     global _os_stat
 | |
|     _os_stat = stat
 | |
| 
 | |
|     global _os_path_join
 | |
|     _os_path_join = join
 | |
| 
 | |
| def _os_path_isdir(pathname):
 | |
|     "Local replacement for os.path.isdir()."
 | |
|     try:
 | |
|         s = _os_stat(pathname)
 | |
|     except OSError:
 | |
|         return None
 | |
|     return (s.st_mode & 0170000) == 0040000
 | |
| 
 | |
| def _timestamp(pathname):
 | |
|     "Return the file modification time as a Long."
 | |
|     try:
 | |
|         s = _os_stat(pathname)
 | |
|     except OSError:
 | |
|         return None
 | |
|     return int(s.st_mtime)
 | |
| 
 | |
| 
 | |
| ######################################################################
 | |
| #
 | |
| # Emulate the import mechanism for builtin and frozen modules
 | |
| #
 | |
| class BuiltinImporter(Importer):
 | |
|     def get_code(self, parent, modname, fqname):
 | |
|         if parent:
 | |
|             # these modules definitely do not occur within a package context
 | |
|             return None
 | |
| 
 | |
|         # look for the module
 | |
|         if imp.is_builtin(modname):
 | |
|             type = imp.C_BUILTIN
 | |
|         elif imp.is_frozen(modname):
 | |
|             type = imp.PY_FROZEN
 | |
|         else:
 | |
|             # not found
 | |
|             return None
 | |
| 
 | |
|         # got it. now load and return it.
 | |
|         module = imp.load_module(modname, None, modname, ('', '', type))
 | |
|         return 0, module, { }
 | |
| 
 | |
| 
 | |
| ######################################################################
 | |
| #
 | |
| # Internal importer used for importing from the filesystem
 | |
| #
 | |
| class _FilesystemImporter(Importer):
 | |
|     def __init__(self):
 | |
|         self.suffixes = [ ]
 | |
| 
 | |
|     def add_suffix(self, suffix, importFunc):
 | |
|         assert callable(importFunc)
 | |
|         self.suffixes.append((suffix, importFunc))
 | |
| 
 | |
|     def import_from_dir(self, dir, fqname):
 | |
|         result = self._import_pathname(_os_path_join(dir, fqname), fqname)
 | |
|         if result:
 | |
|             return self._process_result(result, fqname)
 | |
|         return None
 | |
| 
 | |
|     def get_code(self, parent, modname, fqname):
 | |
|         # This importer is never used with an empty parent. Its existence is
 | |
|         # private to the ImportManager. The ImportManager uses the
 | |
|         # import_from_dir() method to import top-level modules/packages.
 | |
|         # This method is only used when we look for a module within a package.
 | |
|         assert parent
 | |
| 
 | |
|         for submodule_path in parent.__path__:
 | |
|             code = self._import_pathname(_os_path_join(submodule_path, modname), fqname)
 | |
|             if code is not None:
 | |
|                 return code
 | |
|         return self._import_pathname(_os_path_join(parent.__pkgdir__, modname),
 | |
|                                      fqname)
 | |
| 
 | |
|     def _import_pathname(self, pathname, fqname):
 | |
|         if _os_path_isdir(pathname):
 | |
|             result = self._import_pathname(_os_path_join(pathname, '__init__'),
 | |
|                                            fqname)
 | |
|             if result:
 | |
|                 values = result[2]
 | |
|                 values['__pkgdir__'] = pathname
 | |
|                 values['__path__'] = [ pathname ]
 | |
|                 return 1, result[1], values
 | |
|             return None
 | |
| 
 | |
|         for suffix, importFunc in self.suffixes:
 | |
|             filename = pathname + suffix
 | |
|             try:
 | |
|                 finfo = _os_stat(filename)
 | |
|             except OSError:
 | |
|                 pass
 | |
|             else:
 | |
|                 return importFunc(filename, finfo, fqname)
 | |
|         return None
 | |
| 
 | |
| ######################################################################
 | |
| #
 | |
| # SUFFIX-BASED IMPORTERS
 | |
| #
 | |
| 
 | |
| def py_suffix_importer(filename, finfo, fqname):
 | |
|     file = filename[:-3] + _suffix
 | |
|     t_py = int(finfo[8])
 | |
|     t_pyc = _timestamp(file)
 | |
| 
 | |
|     code = None
 | |
|     if t_pyc is not None and t_pyc >= t_py:
 | |
|         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 = filename
 | |
|         code = _compile(file, t_py)
 | |
| 
 | |
|     return 0, code, { '__file__' : file }
 | |
| 
 | |
| class DynLoadSuffixImporter:
 | |
|     def __init__(self, desc):
 | |
|         self.desc = desc
 | |
| 
 | |
|     def import_file(self, filename, finfo, fqname):
 | |
|         fp = open(filename, self.desc[1])
 | |
|         module = imp.load_module(fqname, fp, filename, self.desc)
 | |
|         module.__file__ = filename
 | |
|         return 0, module, { }
 | |
| 
 | |
| 
 | |
| ######################################################################
 | |
| 
 | |
| def _print_importers():
 | |
|     items = sys.modules.items()
 | |
|     items.sort()
 | |
|     for name, module in items:
 | |
|         if module:
 | |
|             print(name, module.__dict__.get('__importer__', '-- no importer'))
 | |
|         else:
 | |
|             print(name, '-- non-existent module')
 | |
| 
 | |
| def _test_revamp():
 | |
|     ImportManager().install()
 | |
|     sys.path.insert(0, BuiltinImporter())
 | |
| 
 | |
| ######################################################################
 | |
| 
 | |
| #
 | |
| # TODO
 | |
| #
 | |
| # from Finn Bock:
 | |
| #   type(sys) is not a module in JPython. what to use instead?
 | |
| #   imp.C_EXTENSION is not in JPython. same for get_suffixes and new_module
 | |
| #
 | |
| #   given foo.py of:
 | |
| #      import sys
 | |
| #      sys.modules['foo'] = sys
 | |
| #
 | |
| #   ---- standard import mechanism
 | |
| #   >>> import foo
 | |
| #   >>> foo
 | |
| #   <module 'sys' (built-in)>
 | |
| #
 | |
| #   ---- revamped import mechanism
 | |
| #   >>> import imputil
 | |
| #   >>> imputil._test_revamp()
 | |
| #   >>> import foo
 | |
| #   >>> foo
 | |
| #   <module 'foo' from 'foo.py'>
 | |
| #
 | |
| #
 | |
| # from MAL:
 | |
| #   should BuiltinImporter exist in sys.path or hard-wired in ImportManager?
 | |
| #   need __path__ processing
 | |
| #   performance
 | |
| #   move chaining to a subclass [gjs: it's been nuked]
 | |
| #   deinstall should be possible
 | |
| #   query mechanism needed: is a specific Importer installed?
 | |
| #   py/pyc/pyo piping hooks to filter/process these files
 | |
| #   wish list:
 | |
| #     distutils importer hooked to list of standard Internet repositories
 | |
| #     module->file location mapper to speed FS-based imports
 | |
| #     relative imports
 | |
| #     keep chaining so that it can play nice with other import hooks
 | |
| #
 | |
| # from Gordon:
 | |
| #   push MAL's mapper into sys.path[0] as a cache (hard-coded for apps)
 | |
| #
 | |
| # from Guido:
 | |
| #   need to change sys.* references for rexec environs
 | |
| #   need hook for MAL's walk-me-up import strategy, or Tim's absolute strategy
 | |
| #   watch out for sys.modules[...] is None
 | |
| #   flag to force absolute imports? (speeds _determine_import_context and
 | |
| #       checking for a relative module)
 | |
| #   insert names of archives into sys.path  (see quote below)
 | |
| #   note: reload does NOT blast module dict
 | |
| #   shift import mechanisms and policies around; provide for hooks, overrides
 | |
| #       (see quote below)
 | |
| #   add get_source stuff
 | |
| #   get_topcode and get_subcode
 | |
| #   CRLF handling in _compile
 | |
| #   race condition in _compile
 | |
| #   refactoring of os.py to deal with _os_bootstrap problem
 | |
| #   any special handling to do for importing a module with a SyntaxError?
 | |
| #       (e.g. clean up the traceback)
 | |
| #   implement "domain" for path-type functionality using pkg namespace
 | |
| #       (rather than FS-names like __path__)
 | |
| #   don't use the word "private"... maybe "internal"
 | |
| #
 | |
| #
 | |
| # Guido's comments on sys.path caching:
 | |
| #
 | |
| # We could cache this in a dictionary: the ImportManager can have a
 | |
| # cache dict mapping pathnames to importer objects, and a separate
 | |
| # method for coming up with an importer given a pathname that's not yet
 | |
| # in the cache.  The method should do a stat and/or look at the
 | |
| # extension to decide which importer class to use; you can register new
 | |
| # importer classes by registering a suffix or a Boolean function, plus a
 | |
| # class.  If you register a new importer class, the cache is zapped.
 | |
| # The cache is independent from sys.path (but maintained per
 | |
| # ImportManager instance) so that rearrangements of sys.path do the
 | |
| # right thing.  If a path is dropped from sys.path the corresponding
 | |
| # cache entry is simply no longer used.
 | |
| #
 | |
| # My/Guido's comments on factoring ImportManager and Importer:
 | |
| #
 | |
| # > However, we still have a tension occurring here:
 | |
| # >
 | |
| # > 1) implementing policy in ImportManager assists in single-point policy
 | |
| # >    changes for app/rexec situations
 | |
| # > 2) implementing policy in Importer assists in package-private policy
 | |
| # >    changes for normal, operating conditions
 | |
| # >
 | |
| # > I'll see if I can sort out a way to do this. Maybe the Importer class will
 | |
| # > implement the methods (which can be overridden to change policy) by
 | |
| # > delegating to ImportManager.
 | |
| #
 | |
| # Maybe also think about what kind of policies an Importer would be
 | |
| # likely to want to change.  I have a feeling that a lot of the code
 | |
| # there is actually not so much policy but a *necessity* to get things
 | |
| # working given the calling conventions for the __import__ hook: whether
 | |
| # to return the head or tail of a dotted name, or when to do the "finish
 | |
| # fromlist" stuff.
 | |
| #
 |