hgdemandimport/demandimportpy3.py
author Gregory Szorc <gregory.szorc@gmail.com>
Thu, 03 Mar 2022 17:34:00 +0100
changeset 48875 6000f5b25c9b
parent 45755 8ed69bd42f10
child 48946 642e31cb55f0
permissions -rw-r--r--
py2: remove simple from __future__ statements These were needed for Python 2 support. Now that our linter no longer mandates these, we can start deleting them. Differential Revision: https://phab.mercurial-scm.org/D12254
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     1
# demandimportpy3 - global demand-loading of modules for Mercurial
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     2
#
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     3
# Copyright 2017 Facebook Inc.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     4
#
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     7
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     8
"""Lazy loading for Python 3.6 and above.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
     9
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    10
This uses the new importlib finder/loader functionality available in Python 3.5
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    11
and up. The code reuses most of the mechanics implemented inside importlib.util,
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    12
but with a few additions:
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    13
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    14
* Allow excluding certain modules from lazy imports.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    15
* Expose an interface that's substantially the same as demandimport for
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    16
  Python 2.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    17
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    18
This also has some limitations compared to the Python 2 implementation:
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    19
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    20
* Much of the logic is per-package, not per-module, so any packages loaded
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    21
  before demandimport is enabled will not be lazily imported in the future. In
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    22
  practice, we only expect builtins to be loaded before demandimport is
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    23
  enabled.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    24
"""
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    25
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    26
# This line is unnecessary, but it satisfies test-check-py3-compat.t.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    27
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    28
import contextlib
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    29
import importlib.util
33898
3595e4e0ae57 demandimportpy3: update to pass import checker
Augie Fackler <raf@durin42.com>
parents: 33859
diff changeset
    30
import sys
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    31
42474
adb636392b3f demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents: 37843
diff changeset
    32
from . import tracing
adb636392b3f demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents: 37843
diff changeset
    33
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    34
_deactivated = False
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    35
44117
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
    36
# Python 3.5's LazyLoader doesn't work for some reason.
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
    37
# https://bugs.python.org/issue26186 is a known issue with extension
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
    38
# importing. But it appears to not have a meaningful effect with
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
    39
# Mercurial.
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
    40
_supported = sys.version_info[0:2] >= (3, 6)
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
    41
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
    42
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    43
class _lazyloaderex(importlib.util.LazyLoader):
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    44
    """This is a LazyLoader except it also follows the _deactivated global and
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    45
    the ignore list.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    46
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
    47
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    48
    def exec_module(self, module):
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    49
        """Make the module load lazily."""
42474
adb636392b3f demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents: 37843
diff changeset
    50
        with tracing.log('demandimport %s', module):
adb636392b3f demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents: 37843
diff changeset
    51
            if _deactivated or module.__name__ in ignores:
adb636392b3f demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents: 37843
diff changeset
    52
                self.loader.exec_module(module)
adb636392b3f demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents: 37843
diff changeset
    53
            else:
adb636392b3f demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents: 37843
diff changeset
    54
                super().exec_module(module)
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    55
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
    56
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    57
class LazyFinder(object):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    58
    """A wrapper around a ``MetaPathFinder`` that makes loaders lazy.
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    59
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    60
    ``sys.meta_path`` finders have their ``find_spec()`` called to locate a
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    61
    module. This returns a ``ModuleSpec`` if found or ``None``. The
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    62
    ``ModuleSpec`` has a ``loader`` attribute, which is called to actually
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    63
    load a module.
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    64
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    65
    Our class wraps an existing finder and overloads its ``find_spec()`` to
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    66
    replace the ``loader`` with our lazy loader proxy.
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
    67
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    68
    We have to use __getattribute__ to proxy the instance because some meta
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    69
    path finders don't support monkeypatching.
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    70
    """
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    71
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    72
    __slots__ = ("_finder",)
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    73
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    74
    def __init__(self, finder):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    75
        object.__setattr__(self, "_finder", finder)
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    76
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    77
    def __repr__(self):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    78
        return "<LazyFinder for %r>" % object.__getattribute__(self, "_finder")
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    79
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    80
    # __bool__ is canonical Python 3. But check-code insists on __nonzero__ being
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    81
    # defined via `def`.
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    82
    def __nonzero__(self):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    83
        return bool(object.__getattribute__(self, "_finder"))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
    84
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    85
    __bool__ = __nonzero__
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    86
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    87
    def __getattribute__(self, name):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    88
        if name in ("_finder", "find_spec"):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    89
            return object.__getattribute__(self, name)
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    90
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    91
        return getattr(object.__getattribute__(self, "_finder"), name)
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    92
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    93
    def __delattr__(self, name):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    94
        return delattr(object.__getattribute__(self, "_finder"))
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    95
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    96
    def __setattr__(self, name, value):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    97
        return setattr(object.__getattribute__(self, "_finder"), name, value)
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
    98
44819
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
    99
    def find_spec(self, fullname, path, target=None):
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   100
        finder = object.__getattribute__(self, "_finder")
44819
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   101
        try:
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   102
            find_spec = finder.find_spec
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   103
        except AttributeError:
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   104
            loader = finder.find_module(fullname, path)
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   105
            if loader is None:
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   106
                spec = None
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   107
            else:
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   108
                spec = importlib.util.spec_from_loader(fullname, loader)
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   109
        else:
a6e12d477595 demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents: 44118
diff changeset
   110
            spec = find_spec(fullname, path, target)
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   111
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   112
        # Lazy loader requires exec_module().
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   113
        if (
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   114
            spec is not None
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   115
            and spec.loader is not None
45755
8ed69bd42f10 demandimport: don't raise AttributeError if `exec_module` is missing
Matt Harbison <matt_harbison@yahoo.com>
parents: 44819
diff changeset
   116
            and getattr(spec.loader, "exec_module", None)
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   117
        ):
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   118
            spec.loader = _lazyloaderex(spec.loader)
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   119
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   120
        return spec
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   121
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
   122
37843
670eb4fa1b86 demandimport: make module ignores a set (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35524
diff changeset
   123
ignores = set()
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   124
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
   125
37843
670eb4fa1b86 demandimport: make module ignores a set (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35524
diff changeset
   126
def init(ignoreset):
670eb4fa1b86 demandimport: make module ignores a set (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35524
diff changeset
   127
    global ignores
670eb4fa1b86 demandimport: make module ignores a set (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35524
diff changeset
   128
    ignores = ignoreset
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   129
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
   130
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   131
def isenabled():
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   132
    return not _deactivated and any(
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   133
        isinstance(finder, LazyFinder) for finder in sys.meta_path
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   134
    )
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   135
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
   136
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   137
def disable():
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   138
    new_finders = []
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   139
    for finder in sys.meta_path:
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   140
        new_finders.append(
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   141
            finder._finder if isinstance(finder, LazyFinder) else finder
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   142
        )
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   143
    sys.meta_path[:] = new_finders
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   144
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
   145
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   146
def enable():
44117
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
   147
    if not _supported:
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
   148
        return
c5e0a9b97b8a hgdemandimport: disable on Python 3.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43378
diff changeset
   149
44118
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   150
    new_finders = []
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   151
    for finder in sys.meta_path:
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   152
        new_finders.append(
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   153
            LazyFinder(finder) if not isinstance(finder, LazyFinder) else finder
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   154
        )
f81c17ec303c hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44117
diff changeset
   155
    sys.meta_path[:] = new_finders
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   156
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42474
diff changeset
   157
32423
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   158
@contextlib.contextmanager
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   159
def deactivated():
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   160
    # This implementation is a bit different from Python 2's. Python 3
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   161
    # maintains a per-package finder cache in sys.path_importer_cache (see
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   162
    # PEP 302). This means that we can't just call disable + enable.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   163
    # If we do that, in situations like:
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   164
    #
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   165
    #   demandimport.enable()
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   166
    #   ...
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   167
    #   from foo.bar import mod1
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   168
    #   with demandimport.deactivated():
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   169
    #       from foo.bar import mod2
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   170
    #
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   171
    # mod2 will be imported lazily. (The converse also holds -- whatever finder
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   172
    # first gets cached will be used.)
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   173
    #
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   174
    # Instead, have a global flag the LazyLoader can use.
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   175
    global _deactivated
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   176
    demandenabled = isenabled()
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   177
    if demandenabled:
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   178
        _deactivated = True
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   179
    try:
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   180
        yield
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   181
    finally:
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   182
        if demandenabled:
859496bb6db3 demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
   183
            _deactivated = False