Patchwork [6,of,6] mercurial: support loading C extensions on Python 3

login
register
mail settings
Submitter Gregory Szorc
Date Oct. 13, 2016, 7:44 p.m.
Message ID <1bc4e41ca8a00b42316c.1476387858@gps-mbp.local>
Download mbox | patch
Permalink /patch/17064/
State Accepted
Headers show

Comments

Gregory Szorc - Oct. 13, 2016, 7:44 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1476359054 -7200
#      Thu Oct 13 13:44:14 2016 +0200
# Node ID 1bc4e41ca8a00b42316c1ef64c2687df24cfb81b
# Parent  8501cbf27b0ae7402f6c6df6cea68b757a939bb9
mercurial: support loading C extensions on Python 3

Previously, the module policy and custom importer forced dual Python
and C modules to use the pure Python version on Python 3. Now that the
C extensions compile and load properly on Python 3, this restriction
can be removed.

This patch changes the module policy to not force the policy to "py" on
Python 3. It also changes the path finder to not rewrite paths to
"mercurial.pure.*" for dual use modules and to not use our source
transformer for C extensions.

Patch

diff --git a/mercurial/__init__.py b/mercurial/__init__.py
--- a/mercurial/__init__.py
+++ b/mercurial/__init__.py
@@ -137,10 +137,9 @@  if sys.version_info[0] >= 3:
             # Only handle Mercurial-related modules.
             if not fullname.startswith(('mercurial.', 'hgext.', 'hgext3rd.')):
                 return None
 
-            # This assumes Python 3 doesn't support loading C modules.
-            if fullname in _dualmodules:
+            if fullname in _dualmodules and modulepolicy in policy.policynoc:
                 stem = fullname.split('.')[-1]
                 fullname = 'mercurial.pure.%s' % stem
                 target = pure
                 assert len(path) == 1
@@ -164,11 +163,12 @@  if sys.version_info[0] >= 3:
 
             if fullname.startswith('mercurial.pure.'):
                 spec.name = spec.name.replace('.pure.', '.')
 
-            # TODO need to support loaders from alternate specs, like zip
-            # loaders.
-            spec.loader = hgloader(spec.name, spec.origin)
+            if fullname not in _dualmodules:
+                # TODO need to support loaders from alternate specs, like zip
+                # loaders.
+                spec.loader = hgloader(spec.name, spec.origin)
             return spec
 
     def replacetokens(tokens, fullname):
         """Transform a stream of tokens from raw to Python 3.
diff --git a/mercurial/policy.py b/mercurial/policy.py
--- a/mercurial/policy.py
+++ b/mercurial/policy.py
@@ -35,11 +35,6 @@  except ImportError:
 # But we don't import platform and don't bloat for it here.
 if '__pypy__' in sys.builtin_module_names:
     policy = 'cffi'
 
-# Our C extensions aren't yet compatible with Python 3. So use pure Python
-# on Python 3 for now.
-if sys.version_info[0] >= 3:
-    policy = 'py'
-
 # Environment variable can always force settings.
 policy = os.environ.get('HGMODULEPOLICY', policy)