view hgdemandimport/demandimportpy3.py @ 44092:833210fbd900

graftcopies: remove `skip` and `repo` arguments The `skip` argument was added in 2ba6c9b4e0eb (rebase: fix bug that caused transitive copy records to disappear (issue4192), 2014-06-07) in order to fix https://bz.mercurial-scm.org/show_bug.cgi?id=4192. I ran tests at that commit without the `skiprev` argument and the only difference I noticed was that `test-rebase-collapse.t` failed differently, in the call that is now on line 501. Without the `skiprev` argument, that call would end up creating another commit because it tried to record an invalid copy. With the previous patch in this series, such invalid copies are no longer recorded, so it seems we don't need the `skip` argument anymore. I also removed the `repo` argument since that also becomes unused with the removal of the `skip` argument. Differential Revision: https://phab.mercurial-scm.org/D7860
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 27 Dec 2019 13:47:59 -0800
parents 2d31ef3fb494
children c5e0a9b97b8a
line wrap: on
line source

# demandimportpy3 - global demand-loading of modules for Mercurial
#
# Copyright 2017 Facebook Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

"""Lazy loading for Python 3.6 and above.

This uses the new importlib finder/loader functionality available in Python 3.5
and up. The code reuses most of the mechanics implemented inside importlib.util,
but with a few additions:

* Allow excluding certain modules from lazy imports.
* Expose an interface that's substantially the same as demandimport for
  Python 2.

This also has some limitations compared to the Python 2 implementation:

* Much of the logic is per-package, not per-module, so any packages loaded
  before demandimport is enabled will not be lazily imported in the future. In
  practice, we only expect builtins to be loaded before demandimport is
  enabled.
"""

# This line is unnecessary, but it satisfies test-check-py3-compat.t.
from __future__ import absolute_import

import contextlib
import importlib.abc
import importlib.machinery
import importlib.util
import sys

from . import tracing

_deactivated = False


class _lazyloaderex(importlib.util.LazyLoader):
    """This is a LazyLoader except it also follows the _deactivated global and
    the ignore list.
    """

    def exec_module(self, module):
        """Make the module load lazily."""
        with tracing.log('demandimport %s', module):
            if _deactivated or module.__name__ in ignores:
                self.loader.exec_module(module)
            else:
                super().exec_module(module)


# This is 3.6+ because with Python 3.5 it isn't possible to lazily load
# extensions. See the discussion in https://bugs.python.org/issue26186 for more.
if sys.version_info[0:2] >= (3, 6):
    _extensions_loader = _lazyloaderex.factory(
        importlib.machinery.ExtensionFileLoader
    )
else:
    _extensions_loader = importlib.machinery.ExtensionFileLoader

_bytecode_loader = _lazyloaderex.factory(
    importlib.machinery.SourcelessFileLoader
)
_source_loader = _lazyloaderex.factory(importlib.machinery.SourceFileLoader)


def _makefinder(path):
    return importlib.machinery.FileFinder(
        path,
        # This is the order in which loaders are passed in in core Python.
        (_extensions_loader, importlib.machinery.EXTENSION_SUFFIXES),
        (_source_loader, importlib.machinery.SOURCE_SUFFIXES),
        (_bytecode_loader, importlib.machinery.BYTECODE_SUFFIXES),
    )


ignores = set()


def init(ignoreset):
    global ignores
    ignores = ignoreset


def isenabled():
    return _makefinder in sys.path_hooks and not _deactivated


def disable():
    try:
        while True:
            sys.path_hooks.remove(_makefinder)
    except ValueError:
        pass


def enable():
    sys.path_hooks.insert(0, _makefinder)


@contextlib.contextmanager
def deactivated():
    # This implementation is a bit different from Python 2's. Python 3
    # maintains a per-package finder cache in sys.path_importer_cache (see
    # PEP 302). This means that we can't just call disable + enable.
    # If we do that, in situations like:
    #
    #   demandimport.enable()
    #   ...
    #   from foo.bar import mod1
    #   with demandimport.deactivated():
    #       from foo.bar import mod2
    #
    # mod2 will be imported lazily. (The converse also holds -- whatever finder
    # first gets cached will be used.)
    #
    # Instead, have a global flag the LazyLoader can use.
    global _deactivated
    demandenabled = isenabled()
    if demandenabled:
        _deactivated = True
    try:
        yield
    finally:
        if demandenabled:
            _deactivated = False