Skip to content

Commit d741712

Browse files
committed
separate monkey patches; added extenstion features support
1 parent 49953a1 commit d741712

File tree

5 files changed

+94
-65
lines changed

5 files changed

+94
-65
lines changed

CHANGES.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CHANGES
22
=======
33

4-
0.3 (2017-xx-xx)
4+
0.3 (2017-04-09)
55
----------------
66

77
- Use distutils exceptions for errors.

README.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,11 @@ You can use same commands as for c-extensions. For example::
4646

4747
Or you can use commands like `bdist_wheel` or `bdist_egg`
4848

49+
50+
RustExtension
51+
-------------
52+
53+
54+
55+
4956
This package is based on https://github.com/novocaine/rust-python-ext

example/extensions/Cargo.toml

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
[package]
2-
32
name = "hello-world"
4-
version = "0.0.1"
5-
authors = ["James Salter <[email protected]>"]
6-
7-
[features]
8-
python27-sys = ["cpython/python27-sys"]
9-
python3-sys = ["cpython/python3-sys"]
3+
version = "0.1.0"
4+
authors = ["Nikolay Kim <[email protected]>"]
105

116
[dependencies.cpython]
127
git = "https://github.com/dgrunwald/rust-cpython.git"
13-
rev = "e644f24"
148
default-features = false
159

1610
[lib]
1711
name = "helloworld"
18-
crate-type = ["cdylib"]
12+
crate-type = ["dylib"]

setuptools_rust/__init__.py

Lines changed: 29 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,19 @@
1-
from __future__ import print_function
1+
from __future__ import print_function, absolute_import
22
import glob
33
import os
44
import shutil
55
import sys
66
import subprocess
77
from distutils.cmd import Command
8-
from distutils.dist import Distribution
9-
from distutils.command.build import build as Build
108
from distutils.errors import (
9+
CompileError,
1110
DistutilsExecError, DistutilsFileError, DistutilsPlatformError)
12-
from setuptools.command import develop
1311

1412
import semver
1513

16-
__all__ = ('RustExtension', 'build_rust')
17-
18-
19-
# allow to use 'rust_extensions' parameter for setup() call
20-
Distribution.rust_extensions = ()
21-
22-
23-
def has_ext_modules(self):
24-
return (self.ext_modules and len(self.ext_modules) > 0 or
25-
self.rust_extensions and len(self.rust_extensions) > 0)
26-
27-
28-
Distribution.has_ext_modules = has_ext_modules
29-
30-
31-
# add support for build_rust sub-command
32-
def has_rust_extensions(self):
33-
exts = [ext for ext in self.distribution.rust_extensions
34-
if isinstance(ext, RustExtension)]
35-
return bool(exts)
36-
37-
38-
Build.has_rust_extensions = has_rust_extensions
39-
Build.sub_commands.append(('build_rust', Build.has_rust_extensions))
14+
from . import patch # noqa
4015

41-
# monkey patch "develop" command
42-
orig_run_command = develop.develop.run_command
43-
44-
45-
def monkey_run_command(self, cmd):
46-
orig_run_command(self, cmd)
47-
48-
if cmd == 'build_ext':
49-
self.reinitialize_command('build_rust', inplace=1)
50-
orig_run_command(self, 'build_rust')
51-
52-
53-
develop.develop.run_command = monkey_run_command
16+
__all__ = ('RustExtension', 'build_rust')
5417

5518

5619
class RustExtension:
@@ -63,9 +26,11 @@ class RustExtension:
6326
*not* a filename or pathname, but Python dotted name
6427
path : string
6528
path to the cargo.toml manifest
66-
args : [stirng]
29+
args : [string]
6730
a list of extra argumenents to be passed to cargo.
68-
version : string
31+
features : [string]
32+
a list of features to also build
33+
rust_version : string
6934
rust compiler version
7035
quiet : bool
7136
If True, doesn't echo cargo's output.
@@ -74,16 +39,22 @@ class RustExtension:
7439
"""
7540

7641
def __init__(self, name, path,
77-
args=None, version=None, quiet=False, debug=False):
42+
args=None, features=None, rust_version=None,
43+
quiet=False, debug=False):
7844
self.name = name
7945
self.path = path
8046
self.args = args
81-
self.version = version
47+
self.rust_version = rust_version
8248
self.quiet = quiet
8349
self.debug = debug
8450

51+
if features is None:
52+
features = []
53+
54+
self.features = [s.strip() for s in features]
55+
8556
@staticmethod
86-
def get_version():
57+
def get_rust_version():
8758
env = os.environ.copy()
8859
try:
8960
output = subprocess.check_output(["rustc", "-V"], env=env)
@@ -117,12 +88,12 @@ def finalize_options(self):
11788
self.extensions = [ext for ext in self.distribution.rust_extensions
11889
if isinstance(ext, RustExtension)]
11990

120-
def features(self):
91+
def _cpython_feature(self):
12192
version = sys.version_info
12293
if (2, 7) < version < (2, 8):
123-
return "python27-sys"
94+
return "cpython/python27-sys"
12495
elif (3, 3) < version:
125-
return "python3-sys"
96+
return "cpython/python3-sys"
12697
else:
12798
raise DistutilsPlatformError(
12899
"Unsupported python version: %s" % sys.version)
@@ -145,17 +116,20 @@ def build_extension(self, ext):
145116
raise DistutilsFileError(
146117
"Can not file rust extension project file: %s" % ext.path)
147118

119+
features = set(ext.features)
120+
features.add(self._cpython_feature())
121+
148122
# Execute cargo.
149123
try:
150124
args = (["cargo", "build", "--manifest-path", ext.path,
151-
"--features", self.features()] + list(ext.args or []))
125+
"--features", " ".join(features)] + list(ext.args or []))
152126
if not ext.debug:
153127
args.append("--release")
154128
if not ext.quiet:
155129
print(" ".join(args), file=sys.stderr)
156130
output = subprocess.check_output(args, env=env)
157131
except subprocess.CalledProcessError as e:
158-
raise DistutilsExecError(
132+
raise CompileError(
159133
"cargo failed with code: %d\n%s" % (e.returncode, e.output))
160134
except OSError:
161135
raise DistutilsExecError(
@@ -205,15 +179,15 @@ def build_extension(self, ext):
205179
shutil.copyfile(dylib_path, ext_path)
206180

207181
def run(self):
208-
version = RustExtension.get_version()
182+
version = RustExtension.get_rust_version()
209183
if self.extensions and version is None:
210184
raise DistutilsPlatformError('Can not find Rust compiler')
211185

212186
for ext in self.extensions:
213-
if ext.version is not None:
214-
if not semver.match(version, ext.version):
187+
if ext.rust_version is not None:
188+
if not semver.match(version, ext.rust_version):
215189
raise DistutilsPlatformError(
216190
"Rust %s does not match extension requirenment %s" % (
217-
version, ext.version))
191+
version, ext.rust_version))
218192

219193
self.build_extension(ext)

setuptools_rust/patch.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from distutils.dist import Distribution
2+
from distutils.command.build import build as Build
3+
from setuptools.command import develop
4+
from setuptools.command.py36compat import sdist_add_defaults
5+
6+
7+
# allow to use 'rust_extensions' parameter for setup() call
8+
Distribution.rust_extensions = ()
9+
10+
11+
def has_ext_modules(self):
12+
return (self.ext_modules and len(self.ext_modules) > 0 or
13+
self.rust_extensions and len(self.rust_extensions) > 0)
14+
15+
16+
Distribution.has_ext_modules = has_ext_modules
17+
18+
19+
# add support for build_rust sub-command
20+
def has_rust_extensions(self):
21+
return (self.distribution.rust_extensions and
22+
len(self.distribution.rust_extensions) > 0)
23+
24+
25+
Build.has_rust_extensions = has_rust_extensions
26+
Build.sub_commands.append(('build_rust', Build.has_rust_extensions))
27+
28+
# monkey patch "develop" command
29+
orig_run_command = develop.develop.run_command
30+
31+
32+
def monkey_run_command(self, cmd):
33+
print(cmd)
34+
orig_run_command(self, cmd)
35+
36+
print(cmd)
37+
if cmd == 'build_ext':
38+
self.reinitialize_command('build_rust', inplace=1)
39+
orig_run_command(self, 'build_rust')
40+
41+
42+
develop.develop.run_command = monkey_run_command
43+
44+
45+
# monkey patch "sdist_add_defaults"
46+
47+
def _add_defaults_ext(self):
48+
if (self.distribution.ext_modules and
49+
len(self.distribution.ext_modules) > 0):
50+
build_ext = self.get_finalized_command('build_ext')
51+
self.filelist.extend(build_ext.get_source_files())
52+
53+
54+
sdist_add_defaults._add_defaults_ext = _add_defaults_ext

0 commit comments

Comments
 (0)