[PATCH 2 of 5 import-refactor] hg: support different module load policies
Gregory Szorc
gregory.szorc at gmail.com
Sun Nov 22 00:14:04 CST 2015
# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1448167251 28800
# Sat Nov 21 20:40:51 2015 -0800
# Node ID 594a8931ee9b1eb82f754a3a4eab3cfc7b3811b1
# Parent 3d32b988b6d49f95d507e456b3e627f27e816ba8
hg: support different module load policies
This patch adds a mechanism to control how we handle the loading of
modules with both Python and C implementations. We call the loading
behavior the "module load policy." There are 3 settings:
* Only load C extensions
* Only load pure Python
* Try to load C and fall back to Python
The default mode is to only load C extensions.
An environment variable allows overriding the policy at run time.
diff --git a/hg b/hg
--- a/hg
+++ b/hg
@@ -13,16 +13,29 @@ import sys
if os.environ.get('HGUNICODEPEDANTRY', False):
reload(sys)
sys.setdefaultencoding("undefined")
libdir = '@LIBDIR@'
+# Rules for how modules can be loaded. Values are:
+# c - require C extensions
+# allow - allow pure Python implementation when C loading fails
+# py - only load pure Python modules
+modulepolicy = '@MODULELOADPOLICY@'
+
+# By default, require the C extensions for performance reasons.
+if modulepolicy == '@' 'MODULELOADPOLICY' '@':
+ modulepolicy = 'c'
+
+# Environment variable can always force settings.
+modulepolicy = os.environ.get('HGMODULEPOLICY', modulepolicy)
+
if libdir != '@' 'LIBDIR' '@':
if not os.path.isabs(libdir):
libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
libdir)
libdir = os.path.abspath(libdir)
sys.path.insert(0, libdir)
# enable importing on demand to reduce startup time
@@ -66,17 +79,31 @@ class hgimporter(object):
# imp.find_module doesn't support submodules (modules with ".").
# Instead you have to pass the parent package's __path__ attribute
# as the path argument.
stem = name.split('.')[-1]
# C extensions are available under mercurial.*.
# Pure Python available under mercurial.* if they are installed there
# or mercurial.pure.* if they aren't installed.
- modinfo = imp.find_module(stem, mercurial.__path__)
+ try:
+ if modulepolicy == 'py':
+ raise ImportError()
+
+ modinfo = imp.find_module(stem, mercurial.__path__)
+ except ImportError:
+ if modulepolicy == 'c':
+ raise
+
+ # Could not load the C extension and pure Python is allowed. So try to
+ # load them.
+ import mercurial.pure as puremod
+ modinfo = imp.find_module(stem, puremod.__path__)
+ if not modinfo:
+ raise ImportError('could not find mercurial module %s' % name)
mod = imp.load_module(name, *modinfo)
sys.modules[name] = mod
return mod
sys.meta_path.insert(0, hgimporter())
import mercurial.util
More information about the Mercurial-devel
mailing list