Ignore:
Timestamp:
Mar 19, 2014, 11:11:30 AM (11 years ago)
Author:
dmik
Message:

python: Update vendor to 2.7.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/vendor/current/Lib/runpy.py

    r2 r388  
    1212import sys
    1313import imp
     14from pkgutil import read_code
    1415try:
    1516    from imp import get_loader
     
    1819
    1920__all__ = [
    20     "run_module",
     21    "run_module", "run_path",
    2122]
    2223
     24class _TempModule(object):
     25    """Temporarily replace a module in sys.modules with an empty namespace"""
     26    def __init__(self, mod_name):
     27        self.mod_name = mod_name
     28        self.module = imp.new_module(mod_name)
     29        self._saved_module = []
     30
     31    def __enter__(self):
     32        mod_name = self.mod_name
     33        try:
     34            self._saved_module.append(sys.modules[mod_name])
     35        except KeyError:
     36            pass
     37        sys.modules[mod_name] = self.module
     38        return self
     39
     40    def __exit__(self, *args):
     41        if self._saved_module:
     42            sys.modules[self.mod_name] = self._saved_module[0]
     43        else:
     44            del sys.modules[self.mod_name]
     45        self._saved_module = []
     46
     47class _ModifiedArgv0(object):
     48    def __init__(self, value):
     49        self.value = value
     50        self._saved_value = self._sentinel = object()
     51
     52    def __enter__(self):
     53        if self._saved_value is not self._sentinel:
     54            raise RuntimeError("Already preserving saved value")
     55        self._saved_value = sys.argv[0]
     56        sys.argv[0] = self.value
     57
     58    def __exit__(self, *args):
     59        self.value = self._sentinel
     60        sys.argv[0] = self._saved_value
    2361
    2462def _run_code(code, run_globals, init_globals=None,
    2563              mod_name=None, mod_fname=None,
    2664              mod_loader=None, pkg_name=None):
    27     """Helper for _run_module_code"""
     65    """Helper to run code in nominated namespace"""
    2866    if init_globals is not None:
    2967        run_globals.update(init_globals)
     
    3876                    mod_name=None, mod_fname=None,
    3977                    mod_loader=None, pkg_name=None):
    40     """Helper for run_module"""
    41     # Set up the top level namespace dictionary
    42     temp_module = imp.new_module(mod_name)
    43     mod_globals = temp_module.__dict__
    44     # Modify sys.argv[0] and sys.module[mod_name]
    45     saved_argv0 = sys.argv[0]
    46     restore_module = mod_name in sys.modules
    47     if restore_module:
    48         saved_module = sys.modules[mod_name]
    49     sys.argv[0] = mod_fname
    50     sys.modules[mod_name] = temp_module
    51     try:
     78    """Helper to run code in new namespace with sys modified"""
     79    with _TempModule(mod_name) as temp_module, _ModifiedArgv0(mod_fname):
     80        mod_globals = temp_module.module.__dict__
    5281        _run_code(code, mod_globals, init_globals,
    53                     mod_name, mod_fname,
    54                     mod_loader, pkg_name)
    55     finally:
    56         sys.argv[0] = saved_argv0
    57         if restore_module:
    58             sys.modules[mod_name] = saved_module
    59         else:
    60             del sys.modules[mod_name]
     82                  mod_name, mod_fname, mod_loader, pkg_name)
    6183    # Copy the globals of the temporary module, as they
    6284    # may be cleared when the temporary module goes away
     
    81103        raise ImportError("No module named %s" % mod_name)
    82104    if loader.is_package(mod_name):
    83         raise ImportError(("%s is a package and cannot " +
    84                           "be directly executed") % mod_name)
     105        if mod_name == "__main__" or mod_name.endswith(".__main__"):
     106            raise ImportError("Cannot use package as __main__ module")
     107        try:
     108            pkg_main_name = mod_name + ".__main__"
     109            return _get_module_details(pkg_main_name)
     110        except ImportError, e:
     111            raise ImportError(("%s; %r is a package and cannot " +
     112                               "be directly executed") %(e, mod_name))
    85113    code = loader.get_code(mod_name)
    86114    if code is None:
    87115        raise ImportError("No code object available for %s" % mod_name)
    88116    filename = _get_filename(loader, mod_name)
    89     return loader, code, filename
    90 
    91 
    92 # XXX ncoghlan: Should this be documented and made public?
    93 # (Current thoughts: don't repeat the mistake that lead to its
    94 # creation when run_module() no longer met the needs of
    95 # mainmodule.c, but couldn't be changed because it was public)
    96 def _run_module_as_main(mod_name, set_argv0=True):
     117    return mod_name, loader, code, filename
     118
     119
     120def _get_main_module_details():
     121    # Helper that gives a nicer error message when attempting to
     122    # execute a zipfile or directory by invoking __main__.py
     123    main_name = "__main__"
     124    try:
     125        return _get_module_details(main_name)
     126    except ImportError as exc:
     127        if main_name in str(exc):
     128            raise ImportError("can't find %r module in %r" %
     129                              (main_name, sys.path[0]))
     130        raise
     131
     132# This function is the actual implementation of the -m switch and direct
     133# execution of zipfiles and directories and is deliberately kept private.
     134# This avoids a repeat of the situation where run_module() no longer met the
     135# needs of mainmodule.c, but couldn't be changed because it was public
     136def _run_module_as_main(mod_name, alter_argv=True):
    97137    """Runs the designated module in the __main__ namespace
    98138
    99        These __*__ magic variables will be overwritten:
     139       Note that the executed module will have full access to the
     140       __main__ namespace. If this is not desirable, the run_module()
     141       function should be used to run the module code in a fresh namespace.
     142
     143       At the very least, these variables in __main__ will be overwritten:
     144           __name__
    100145           __file__
    101146           __loader__
     147           __package__
    102148    """
    103149    try:
    104         loader, code, fname = _get_module_details(mod_name)
     150        if alter_argv or mod_name != "__main__": # i.e. -m switch
     151            mod_name, loader, code, fname = _get_module_details(mod_name)
     152        else:          # i.e. directory or zipfile execution
     153            mod_name, loader, code, fname = _get_main_module_details()
    105154    except ImportError as exc:
    106         # Try to provide a good error message
    107         # for directories, zip files and the -m switch
    108         if set_argv0:
    109             # For -m switch, just disply the exception
    110             info = str(exc)
    111         else:
    112             # For directories/zipfiles, let the user
    113             # know what the code was looking for
    114             info = "can't find '__main__.py' in %r" % sys.argv[0]
    115         msg = "%s: %s" % (sys.executable, info)
     155        msg = "%s: %s" % (sys.executable, str(exc))
    116156        sys.exit(msg)
    117157    pkg_name = mod_name.rpartition('.')[0]
    118158    main_globals = sys.modules["__main__"].__dict__
    119     if set_argv0:
     159    if alter_argv:
    120160        sys.argv[0] = fname
    121161    return _run_code(code, main_globals, None,
     
    128168       Returns the resulting top level namespace dictionary
    129169    """
    130     loader, code, fname = _get_module_details(mod_name)
     170    mod_name, loader, code, fname = _get_module_details(mod_name)
    131171    if run_name is None:
    132172        run_name = mod_name
     
    141181
    142182
     183# XXX (ncoghlan): Perhaps expose the C API function
     184# as imp.get_importer instead of reimplementing it in Python?
     185def _get_importer(path_name):
     186    """Python version of PyImport_GetImporter C API function"""
     187    cache = sys.path_importer_cache
     188    try:
     189        importer = cache[path_name]
     190    except KeyError:
     191        # Not yet cached. Flag as using the
     192        # standard machinery until we finish
     193        # checking the hooks
     194        cache[path_name] = None
     195        for hook in sys.path_hooks:
     196            try:
     197                importer = hook(path_name)
     198                break
     199            except ImportError:
     200                pass
     201        else:
     202            # The following check looks a bit odd. The trick is that
     203            # NullImporter raises ImportError if the supplied path is a
     204            # *valid* directory entry (and hence able to be handled
     205            # by the standard import machinery)
     206            try:
     207                importer = imp.NullImporter(path_name)
     208            except ImportError:
     209                return None
     210        cache[path_name] = importer
     211    return importer
     212
     213def _get_code_from_file(fname):
     214    # Check for a compiled file first
     215    with open(fname, "rb") as f:
     216        code = read_code(f)
     217    if code is None:
     218        # That didn't work, so try it as normal source code
     219        with open(fname, "rU") as f:
     220            code = compile(f.read(), fname, 'exec')
     221    return code
     222
     223def run_path(path_name, init_globals=None, run_name=None):
     224    """Execute code located at the specified filesystem location
     225
     226       Returns the resulting top level namespace dictionary
     227
     228       The file path may refer directly to a Python script (i.e.
     229       one that could be directly executed with execfile) or else
     230       it may refer to a zipfile or directory containing a top
     231       level __main__.py script.
     232    """
     233    if run_name is None:
     234        run_name = "<run_path>"
     235    importer = _get_importer(path_name)
     236    if isinstance(importer, imp.NullImporter):
     237        # Not a valid sys.path entry, so run the code directly
     238        # execfile() doesn't help as we want to allow compiled files
     239        code = _get_code_from_file(path_name)
     240        return _run_module_code(code, init_globals, run_name, path_name)
     241    else:
     242        # Importer is defined for path, so add it to
     243        # the start of sys.path
     244        sys.path.insert(0, path_name)
     245        try:
     246            # Here's where things are a little different from the run_module
     247            # case. There, we only had to replace the module in sys while the
     248            # code was running and doing so was somewhat optional. Here, we
     249            # have no choice and we have to remove it even while we read the
     250            # code. If we don't do this, a __loader__ attribute in the
     251            # existing __main__ module may prevent location of the new module.
     252            main_name = "__main__"
     253            saved_main = sys.modules[main_name]
     254            del sys.modules[main_name]
     255            try:
     256                mod_name, loader, code, fname = _get_main_module_details()
     257            finally:
     258                sys.modules[main_name] = saved_main
     259            pkg_name = ""
     260            with _TempModule(run_name) as temp_module, \
     261                 _ModifiedArgv0(path_name):
     262                mod_globals = temp_module.module.__dict__
     263                return _run_code(code, mod_globals, init_globals,
     264                                    run_name, fname, loader, pkg_name).copy()
     265        finally:
     266            try:
     267                sys.path.remove(path_name)
     268            except ValueError:
     269                pass
     270
     271
    143272if __name__ == "__main__":
    144273    # Run the module specified as the next command line argument
Note: See TracChangeset for help on using the changeset viewer.