annotate mercurial/policy.py @ 29375:fcaf20175b1b

demandimport: delay loading for "from a import b" with absolute_import Before this patch, "from a import b" doesn't delay loading module "b", if absolute_import is enabled, even though "from . import b" does. For example: - it is assumed that extension X has "from P import M" for module M under package P with absolute_import feature - if importing module M is already delayed before loading extension X, loading module M in extension X is delayed until actually referring util, cmdutil, scmutil or so of Mercurial itself should be imported by "from . import M" style before loading extension X - otherwise, module M is loaded immediately at loading extension X, even if extension X itself isn't used at that "hg" command invocation Some minor modules (e.g. filemerge or so) of Mercurial itself aren't imported by "from . import M" style before loading extension X. And of course, external libraries aren't, too. This might cause startup performance problem of hg command, because many bundled extensions already enable absolute_import feature. To delay loading module for "from a import b" with absolute_import feature, this patch does below in "from a (or .a) import b" with absolute_import case: 1. import root module of "name" by system built-in __import__ (referred as _origimport) 2. recurse down the module chain for hierarchical "name" This logic can be shared with non absolute_import case. Therefore, this patch also centralizes it into chainmodules(). 3. and fall through to process elements in "fromlist" for the leaf module of "name" Processing elements in "fromlist" is executed in the code path after "if _pypy: .... else: ..." clause. Therefore, this patch replaces "if _pypy:" with "elif _pypy:" to share it. At 4f1144c3c72b introducing original "work around" for "from a import b" case, elements in "fromlist" were imported with "level=level". But "level" might be grater than 1 (e.g. level=2 in "from .. import b" case) at demandimport() invocation, and importing direct sub-module in "fromlist" with level grater than 1 causes unexpected result. IMHO, this seems main reason of "errors for unknown reason" described in 4f1144c3c72b, and we don't have to worry about it, because this issue was already fixed by 78d05778907b. This is reason why this patch removes "errors for unknown reasons" comment.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Sun, 19 Jun 2016 02:17:33 +0900
parents b3a677c82a35
children b4d117cee636
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29266
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
1 # policy.py - module policy logic for Mercurial.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
2 #
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
3 # Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
4 #
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
7
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
8 from __future__ import absolute_import
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
9
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
10 import os
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
11 import sys
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
12
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
13 # Rules for how modules can be loaded. Values are:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
14 #
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
15 # c - require C extensions
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
16 # allow - allow pure Python implementation when C loading fails
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
17 # py - only load pure Python modules
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
18 #
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
19 # By default, require the C extensions for performance reasons.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
20 policy = 'c'
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
21 try:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
22 from . import __modulepolicy__
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
23 policy = __modulepolicy__.modulepolicy
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
24 except ImportError:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
25 pass
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
26
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
27 # PyPy doesn't load C extensions.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
28 #
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
29 # The canonical way to do this is to test platform.python_implementation().
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
30 # But we don't import platform and don't bloat for it here.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
31 if '__pypy__' in sys.builtin_module_names:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
32 policy = 'py'
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
33
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
34 # Our C extensions aren't yet compatible with Python 3. So use pure Python
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
35 # on Python 3 for now.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
36 if sys.version_info[0] >= 3:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
37 policy = 'py'
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
38
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
39 # Environment variable can always force settings.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
40 policy = os.environ.get('HGMODULEPOLICY', policy)