# HG changeset patch
# User Georges Racinet <gracinet@anybox.fr>
# Date 1545055552 -3600
#      Mon Dec 17 15:05:52 2018 +0100
# Node ID 4277e20cfec410dc1a4943c5f9a73813076dc804
# Parent  6a372f943e490dd14a8ec4e2b4e8b1716104ac6a
rust-cpython: build and support for Python3

Defined Cargo features for Python3, making them overall simpler to
use, hooked them in build and made mercurial.rustext importable.

This is tested with Python 3.6.7.

Differential Revision: https://phab.mercurial-scm.org/D5446

diff --git a/mercurial/__init__.py b/mercurial/__init__.py
--- a/mercurial/__init__.py
+++ b/mercurial/__init__.py
@@ -40,6 +40,10 @@
             # zstd is already dual-version clean, don't try and mangle it
             if fullname.startswith('mercurial.zstd'):
                 return None
+            # rustext is built for the right python version,
+            # don't try and mangle it
+            if fullname.startswith('mercurial.rustext'):
+                return None
             # pywatchman is already dual-version clean, don't try and mangle it
             if fullname.startswith('hgext.fsmonitor.pywatchman'):
                 return None
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -19,6 +19,7 @@
  "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "python27-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "python3-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
diff --git a/rust/hg-cpython/Cargo.toml b/rust/hg-cpython/Cargo.toml
--- a/rust/hg-cpython/Cargo.toml
+++ b/rust/hg-cpython/Cargo.toml
@@ -8,9 +8,14 @@
 crate-type = ["cdylib"]
 
 [features]
-default = ["python27", "python27-sys"]
+default = ["python27"]
 
-python27 = ["cpython/python27-sys", "cpython/extension-module-2-7"]
+python27 = ["cpython/python27-sys",
+            "cpython/extension-module-2-7",
+            "python27-sys",
+            ]
+
+python3 = ["python3-sys", "cpython/python3-sys", "cpython/extension-module"]
 
 [dependencies]
 hg-core = { path = "../hg-core" }
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -922,11 +922,13 @@
 
     rusttargetdir = os.path.join('rust', 'target', 'release')
 
-    def __init__(self, mpath, sources, rustlibname, subcrate, **kw):
+    def __init__(self, mpath, sources, rustlibname, subcrate,
+                 py3_features=None, **kw):
         Extension.__init__(self, mpath, sources, **kw)
         if hgrustext is None:
             return
         srcdir = self.rustsrcdir = os.path.join('rust', subcrate)
+        self.py3_features = py3_features
 
         # adding Rust source and control files to depends so that the extension
         # gets rebuilt if they've changed
@@ -957,6 +959,9 @@
             env['HOME'] = pwd.getpwuid(os.getuid()).pw_dir
 
         cargocmd = ['cargo', 'build', '-vv', '--release']
+        if sys.version_info[0] == 3 and self.py3_features is not None:
+            cargocmd.extend(('--features', self.py3_features,
+                             '--no-default-features'))
         try:
             subprocess.check_call(cargocmd, env=env, cwd=self.rustsrcdir)
         except OSError as exc:
@@ -1047,7 +1052,8 @@
 
 if hgrustext == 'cpython':
     extmodules.append(
-        RustStandaloneExtension('mercurial.rustext', 'hg-cpython', 'librusthg')
+        RustStandaloneExtension('mercurial.rustext', 'hg-cpython', 'librusthg',
+                                py3_features='python3')
     )