hgdemandimport/demandimportpy2.py
author Yuya Nishihara <yuya@tcha.org>
Mon, 01 May 2017 13:43:31 +0900
changeset 32445 847233374434
parent 32422 f37f9499fea8
child 32446 63365e9621d6
permissions -rw-r--r--
demandimport: strictly compare identity of proxy object This looks better, and __eq__() may be overridden in an undesired way.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# demandimport.py - global demand-loading of modules for Mercurial
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4631
diff changeset
     3
# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7861
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10242
diff changeset
     6
# GNU General Public License version 2 or any later version.
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
'''
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     9
demandimport - automatic demandloading of modules
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
To enable this module, do:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
  import demandimport; demandimport.enable()
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
Imports of the following forms will be demand-loaded:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
  import a, b.c
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
  import a.b as c
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
  from a import b,c # a will be loaded immediately
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
These imports will not be delayed:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
  from a import *
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
  b = __import__(a)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
'''
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
25943
3beed01daff9 demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25937
diff changeset
    27
from __future__ import absolute_import
3beed01daff9 demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25937
diff changeset
    28
3beed01daff9 demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25937
diff changeset
    29
import contextlib
3beed01daff9 demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25937
diff changeset
    30
import os
3beed01daff9 demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25937
diff changeset
    31
import sys
25674
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
    32
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
    33
# __builtin__ in Python 2, builtins in Python 3.
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
    34
try:
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
    35
    import __builtin__ as builtins
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
    36
except ImportError:
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
    37
    import builtins
25327
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
    38
25943
3beed01daff9 demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25937
diff changeset
    39
contextmanager = contextlib.contextmanager
3beed01daff9 demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25937
diff changeset
    40
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
_origimport = __import__
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
14977
1dbd42a02153 demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14976
diff changeset
    43
nothing = object()
1dbd42a02153 demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14976
diff changeset
    44
25933
1fc6c02782ab demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25674
diff changeset
    45
# Python 3 doesn't have relative imports nor level -1.
1fc6c02782ab demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25674
diff changeset
    46
level = -1
1fc6c02782ab demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25674
diff changeset
    47
if sys.version_info[0] >= 3:
1fc6c02782ab demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25674
diff changeset
    48
    level = 0
1fc6c02782ab demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25674
diff changeset
    49
_import = _origimport
15096
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
    50
25936
f90bb2002bcf demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25935
diff changeset
    51
def _hgextimport(importfunc, name, globals, *args, **kwargs):
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    52
    try:
25936
f90bb2002bcf demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25935
diff changeset
    53
        return importfunc(name, globals, *args, **kwargs)
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    54
    except ImportError:
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    55
        if not globals:
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    56
            raise
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    57
        # extensions are loaded with "hgext_" prefix
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    58
        hgextname = 'hgext_%s' % name
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    59
        nameroot = hgextname.split('.', 1)[0]
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    60
        contextroot = globals.get('__name__', '').split('.', 1)[0]
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    61
        if nameroot != contextroot:
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    62
            raise
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    63
        # retry to import with "hgext_" prefix
25936
f90bb2002bcf demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25935
diff changeset
    64
        return importfunc(hgextname, globals, *args, **kwargs)
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
    65
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
class _demandmod(object):
29737
ae9a4d6a8d51 demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29736
diff changeset
    67
    """module demand-loader and proxy
ae9a4d6a8d51 demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29736
diff changeset
    68
ae9a4d6a8d51 demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29736
diff changeset
    69
    Specify 1 as 'level' argument at construction, to import module
ae9a4d6a8d51 demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29736
diff changeset
    70
    relatively.
ae9a4d6a8d51 demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29736
diff changeset
    71
    """
ae9a4d6a8d51 demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29736
diff changeset
    72
    def __init__(self, name, globals, locals, level):
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
        if '.' in name:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
            head, rest = name.split('.', 1)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
            after = [rest]
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
        else:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
            head = name
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
            after = []
31644
f80d9ddc40f3 py3: abuse r'' to preserve str-ness of literals passed to __setattr__()
Yuya Nishihara <yuya@tcha.org>
parents: 30647
diff changeset
    79
        object.__setattr__(self, r"_data",
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    80
                           (head, globals, locals, after, level, set()))
31644
f80d9ddc40f3 py3: abuse r'' to preserve str-ness of literals passed to __setattr__()
Yuya Nishihara <yuya@tcha.org>
parents: 30647
diff changeset
    81
        object.__setattr__(self, r"_module", None)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
    def _extend(self, name):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
        """add to the list of submodules to load"""
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
        self._data[3].append(name)
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    85
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    86
    def _addref(self, name):
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    87
        """Record that the named module ``name`` imports this module.
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    88
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    89
        References to this proxy class having the name of this module will be
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    90
        replaced at module load time. We assume the symbol inside the importing
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    91
        module is identical to the "head" name of this module. We don't
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    92
        actually know if "as X" syntax is being used to change the symbol name
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    93
        because this information isn't exposed to __import__.
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    94
        """
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    95
        self._data[5].add(name)
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    96
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
    def _load(self):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
        if not self._module:
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
    99
            head, globals, locals, after, level, modrefs = self._data
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
   100
            mod = _hgextimport(_import, head, globals, locals, None, level)
29642
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   101
            if mod is self:
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   102
                # In this case, _hgextimport() above should imply
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   103
                # _demandimport(). Otherwise, _hgextimport() never
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   104
                # returns _demandmod. This isn't intentional behavior,
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   105
                # in fact. (see also issue5304 for detail)
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   106
                #
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   107
                # If self._module is already bound at this point, self
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   108
                # should be already _load()-ed while _hgextimport().
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   109
                # Otherwise, there is no way to import actual module
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   110
                # as expected, because (re-)invoking _hgextimport()
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   111
                # should cause same result.
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   112
                # This is reason why _load() returns without any more
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   113
                # setup but assumes self to be already bound.
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   114
                mod = self._module
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   115
                assert mod and mod is not self, "%s, %s" % (self, mod)
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   116
                return
8960fcb76ca4 demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29375
diff changeset
   117
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   118
            # load submodules
3921
6d0d025e125a demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents: 3903
diff changeset
   119
            def subload(mod, p):
6d0d025e125a demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents: 3903
diff changeset
   120
                h, t = p, None
6d0d025e125a demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents: 3903
diff changeset
   121
                if '.' in p:
6d0d025e125a demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents: 3903
diff changeset
   122
                    h, t = p.split('.', 1)
14977
1dbd42a02153 demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14976
diff changeset
   123
                if getattr(mod, h, nothing) is nothing:
29736
14f077f7519a demandimport: import sub-module relatively as expected (issue5208)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29642
diff changeset
   124
                    setattr(mod, h, _demandmod(p, mod.__dict__, mod.__dict__,
14f077f7519a demandimport: import sub-module relatively as expected (issue5208)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29642
diff changeset
   125
                                               level=1))
3926
de6ae8f016af demandimport: handle already-loaded nested modules in subload
Brendan Cully <brendan@kublai.com>
parents: 3921
diff changeset
   126
                elif t:
3921
6d0d025e125a demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents: 3903
diff changeset
   127
                    subload(getattr(mod, h), t)
6d0d025e125a demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents: 3903
diff changeset
   128
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   129
            for x in after:
3921
6d0d025e125a demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents: 3903
diff changeset
   130
                subload(mod, x)
6d0d025e125a demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents: 3903
diff changeset
   131
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   132
            # Replace references to this proxy instance with the actual module.
32445
847233374434 demandimport: strictly compare identity of proxy object
Yuya Nishihara <yuya@tcha.org>
parents: 32422
diff changeset
   133
            if locals and locals.get(head) is self:
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   134
                locals[head] = mod
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   135
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   136
            for modname in modrefs:
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   137
                modref = sys.modules.get(modname, None)
32445
847233374434 demandimport: strictly compare identity of proxy object
Yuya Nishihara <yuya@tcha.org>
parents: 32422
diff changeset
   138
                if modref and getattr(modref, head, None) is self:
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   139
                    setattr(modref, head, mod)
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   140
31644
f80d9ddc40f3 py3: abuse r'' to preserve str-ness of literals passed to __setattr__()
Yuya Nishihara <yuya@tcha.org>
parents: 30647
diff changeset
   141
            object.__setattr__(self, r"_module", mod)
4631
e3afa670e484 demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents: 4626
diff changeset
   142
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   143
    def __repr__(self):
4631
e3afa670e484 demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents: 4626
diff changeset
   144
        if self._module:
e3afa670e484 demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents: 4626
diff changeset
   145
            return "<proxied module '%s'>" % self._data[0]
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   146
        return "<unloaded module '%s'>" % self._data[0]
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   147
    def __call__(self, *args, **kwargs):
5639
7dd5cf9d1e09 demandload: give better diagnostic for call of an unloaded module
Matt Mackall <mpm@selenic.com>
parents: 5098
diff changeset
   148
        raise TypeError("%s object is not callable" % repr(self))
3903
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
   149
    def __getattribute__(self, attr):
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   150
        if attr in ('_data', '_extend', '_load', '_module', '_addref'):
3903
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
   151
            return object.__getattribute__(self, attr)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   152
        self._load()
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   153
        return getattr(self._module, attr)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   154
    def __setattr__(self, attr, val):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   155
        self._load()
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   156
        setattr(self._module, attr, val)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   157
27536
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   158
_pypy = '__pypy__' in sys.builtin_module_names
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   159
21290
74be3fb1e3b8 demandimport: pass proper level to __import__ in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21025
diff changeset
   160
def _demandimport(name, globals=None, locals=None, fromlist=None, level=level):
32365
b2b5605285ec demandimport: strictly check missing locals argument
Yuya Nishihara <yuya@tcha.org>
parents: 32173
diff changeset
   161
    if locals is None or name in ignore or fromlist == ('*',):
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   162
        # these cases we can't really delay
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
   163
        return _hgextimport(_import, name, globals, locals, fromlist, level)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   164
    elif not fromlist:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   165
        # import a [as b]
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   166
        if '.' in name: # a.b
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   167
            base, rest = name.split('.', 1)
3903
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
   168
            # email.__init__ loading email.mime
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
   169
            if globals and globals.get('__name__', None) == base:
15096
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
   170
                return _import(name, globals, locals, fromlist, level)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   171
            # if a is already demand-loaded, add b to its submodule list
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   172
            if base in locals:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   173
                if isinstance(locals[base], _demandmod):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   174
                    locals[base]._extend(rest)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   175
                return locals[base]
19932
e3a5922e18c3 demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15096
diff changeset
   176
        return _demandmod(name, globals, locals, level)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   177
    else:
25935
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   178
        # There is a fromlist.
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   179
        # from a import b,c,d
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   180
        # from . import b,c,d
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   181
        # from .a import b,c,d
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   182
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   183
        # level == -1: relative and absolute attempted (Python 2 only).
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   184
        # level >= 0: absolute only (Python 2 w/ absolute_import and Python 3).
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   185
        # The modern Mercurial convention is to use absolute_import everywhere,
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   186
        # so modern Mercurial code will have level >= 0.
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   187
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   188
        # The name of the module the import statement is located in.
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   189
        globalname = globals.get('__name__')
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   190
26873
78d05778907b demandimport: fix level passed to loader of sub-modules
Yuya Nishihara <yuya@tcha.org>
parents: 26830
diff changeset
   191
        def processfromitem(mod, attr):
26455
f2bf76d3d567 demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25943
diff changeset
   192
            """Process an imported symbol in the import statement.
f2bf76d3d567 demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25943
diff changeset
   193
30022
26a4e46af2bc demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents: 30021
diff changeset
   194
            If the symbol doesn't exist in the parent module, and if the
26a4e46af2bc demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents: 30021
diff changeset
   195
            parent module is a package, it must be a module. We set missing
26a4e46af2bc demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents: 30021
diff changeset
   196
            modules up as _demandmod instances.
26455
f2bf76d3d567 demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25943
diff changeset
   197
            """
26456
86fc4a2863ff demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26455
diff changeset
   198
            symbol = getattr(mod, attr, nothing)
30022
26a4e46af2bc demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents: 30021
diff changeset
   199
            nonpkg = getattr(mod, '__path__', nothing) is nothing
26456
86fc4a2863ff demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26455
diff changeset
   200
            if symbol is nothing:
30022
26a4e46af2bc demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents: 30021
diff changeset
   201
                if nonpkg:
30647
1914db1b7d9e demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 30156
diff changeset
   202
                    # do not try relative import, which would raise ValueError,
1914db1b7d9e demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 30156
diff changeset
   203
                    # and leave unknown attribute as the default __import__()
1914db1b7d9e demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 30156
diff changeset
   204
                    # would do. the missing attribute will be detected later
1914db1b7d9e demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 30156
diff changeset
   205
                    # while processing the import statement.
1914db1b7d9e demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 30156
diff changeset
   206
                    return
28175
c25e3fd38ff1 demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 27537
diff changeset
   207
                mn = '%s.%s' % (mod.__name__, attr)
c25e3fd38ff1 demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 27537
diff changeset
   208
                if mn in ignore:
c25e3fd38ff1 demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 27537
diff changeset
   209
                    importfunc = _origimport
c25e3fd38ff1 demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 27537
diff changeset
   210
                else:
c25e3fd38ff1 demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 27537
diff changeset
   211
                    importfunc = _demandmod
c25e3fd38ff1 demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents: 27537
diff changeset
   212
                symbol = importfunc(attr, mod.__dict__, locals, level=1)
26456
86fc4a2863ff demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26455
diff changeset
   213
                setattr(mod, attr, symbol)
26455
f2bf76d3d567 demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25943
diff changeset
   214
26457
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   215
            # Record the importing module references this symbol so we can
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   216
            # replace the symbol with the actual module instance at load
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   217
            # time.
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   218
            if globalname and isinstance(symbol, _demandmod):
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   219
                symbol._addref(globalname)
7e81305092a0 demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26456
diff changeset
   220
29375
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   221
        def chainmodules(rootmod, modname):
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   222
            # recurse down the module chain, and return the leaf module
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   223
            mod = rootmod
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   224
            for comp in modname.split('.')[1:]:
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   225
                if getattr(mod, comp, nothing) is nothing:
29736
14f077f7519a demandimport: import sub-module relatively as expected (issue5208)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29642
diff changeset
   226
                    setattr(mod, comp, _demandmod(comp, mod.__dict__,
14f077f7519a demandimport: import sub-module relatively as expected (issue5208)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29642
diff changeset
   227
                                                  mod.__dict__, level=1))
29375
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   228
                mod = getattr(mod, comp)
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   229
            return mod
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   230
25935
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   231
        if level >= 0:
25937
4f1144c3c72b demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25936
diff changeset
   232
            if name:
29375
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   233
                # "from a import b" or "from .a import b" style
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   234
                rootmod = _hgextimport(_origimport, name, globals, locals,
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   235
                                       level=level)
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   236
                mod = chainmodules(rootmod, name)
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   237
            elif _pypy:
27536
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   238
                # PyPy's __import__ throws an exception if invoked
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   239
                # with an empty name and no fromlist.  Recreate the
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   240
                # desired behaviour by hand.
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   241
                mn = globalname
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   242
                mod = sys.modules[mn]
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   243
                if getattr(mod, '__path__', nothing) is nothing:
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   244
                    mn = mn.rsplit('.', 1)[0]
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   245
                    mod = sys.modules[mn]
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   246
                if level > 1:
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   247
                    mn = mn.rsplit('.', level - 1)[0]
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   248
                    mod = sys.modules[mn]
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   249
            else:
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   250
                mod = _hgextimport(_origimport, name, globals, locals,
f7d890bc5e01 demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents: 27069
diff changeset
   251
                                   level=level)
26455
f2bf76d3d567 demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25943
diff changeset
   252
25937
4f1144c3c72b demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25936
diff changeset
   253
            for x in fromlist:
26873
78d05778907b demandimport: fix level passed to loader of sub-modules
Yuya Nishihara <yuya@tcha.org>
parents: 26830
diff changeset
   254
                processfromitem(mod, x)
25937
4f1144c3c72b demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25936
diff changeset
   255
4f1144c3c72b demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25936
diff changeset
   256
            return mod
25935
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   257
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   258
        # But, we still need to support lazy loading of standard library and 3rd
49dd4fd3f283 demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25934
diff changeset
   259
        # party modules. So handle level == -1.
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
   260
        mod = _hgextimport(_origimport, name, globals, locals)
29375
fcaf20175b1b demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28286
diff changeset
   261
        mod = chainmodules(mod, name)
26455
f2bf76d3d567 demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25943
diff changeset
   262
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   263
        for x in fromlist:
26455
f2bf76d3d567 demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25943
diff changeset
   264
            processfromitem(mod, x)
f2bf76d3d567 demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25943
diff changeset
   265
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   266
        return mod
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   267
32422
f37f9499fea8 demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents: 32420
diff changeset
   268
ignore = []
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   269
32422
f37f9499fea8 demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents: 32420
diff changeset
   270
def init(ignorelist):
f37f9499fea8 demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents: 32420
diff changeset
   271
    global ignore
f37f9499fea8 demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents: 32420
diff changeset
   272
    ignore = ignorelist
30020
bf94fe556f16 demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents: 29980
diff changeset
   273
20422
aac87f70f38e hooks: only disable/re-enable demandimport when it's already enabled
Brodie Rao <brodie@sf.io>
parents: 19933
diff changeset
   274
def isenabled():
25673
fa1f04529775 demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25327
diff changeset
   275
    return builtins.__import__ == _demandimport
20422
aac87f70f38e hooks: only disable/re-enable demandimport when it's already enabled
Brodie Rao <brodie@sf.io>
parents: 19933
diff changeset
   276
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   277
def enable():
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   278
    "enable global demand-loading of modules"
21025
54af51c18c4c demandimport: make it possible to disable by setting HGDEMANDIMPORT=disable
Mads Kiilerich <madski@unity3d.com>
parents: 20422
diff changeset
   279
    if os.environ.get('HGDEMANDIMPORT') != 'disable':
25673
fa1f04529775 demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25327
diff changeset
   280
        builtins.__import__ = _demandimport
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   281
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   282
def disable():
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   283
    "disable global demand-loading of modules"
25673
fa1f04529775 demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25327
diff changeset
   284
    builtins.__import__ = _origimport
25327
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   285
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   286
@contextmanager
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   287
def deactivated():
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   288
    "context manager for disabling demandimport in 'with' blocks"
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   289
    demandenabled = isenabled()
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   290
    if demandenabled:
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   291
        disable()
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   292
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   293
    try:
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   294
        yield
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   295
    finally:
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   296
        if demandenabled:
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
   297
            enable()