Skip to content

Commit 1e37cc8

Browse files
authored
refactoring: tidy up library and reuse more logic (#116)
1 parent 1d7ee9f commit 1e37cc8

File tree

14 files changed

+193
-277
lines changed

14 files changed

+193
-277
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
# Changelog
22

33
## Unreleased
4+
### Packaging
5+
- Bump minimum Python version to Python 3.6.
46

7+
### Changed
58
- Respect `PYO3_PYTHON` and `PYTHON_SYS_EXECUTABLE` environment variables if set. [#96](https://github.com/PyO3/setuptools-rust/pull/96)
69
- Add runtime dependency on setuptools >= 46.1. [#102](https://github.com/PyO3/setuptools-rust/pull/102)
7-
- Append to, rather than replace, existing RUSTFLAGS when building. [#103](https://github.com/PyO3/setuptools-rust/pull/103)
10+
- Append to, rather than replace, existing `RUSTFLAGS` when building. [#103](https://github.com/PyO3/setuptools-rust/pull/103)
11+
12+
### Fixed
813
- Set executable bit on shared library. [#110](https://github.com/PyO3/setuptools-rust/pull/110)
9-
- Don't require optional wheel dependency. [#111](https://github.com/PyO3/setuptools-rust/pull/111)
14+
- Don't require optional `wheel` dependency. [#111](https://github.com/PyO3/setuptools-rust/pull/111)
1015

1116
## 0.11.6 (2020-12-13)
1217

examples/namespace_package/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

setup.cfg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = attr: setuptools_rust.__version__
44
author = Nikolay Kim
55
author_email = [email protected]
66
license = MIT
7-
description = Setuptools rust extension plugin
7+
description = Setuptools Rust extension plugin
88
keywords = distutils, setuptools, rust
99
url = https://github.com/PyO3/setuptools-rust
1010
long_description = file: README.md
@@ -29,6 +29,7 @@ packages = setuptools_rust
2929
zip_safe = True
3030
install_requires = setuptools>=46.1; semantic_version>=2.6.0; toml>=0.9.0
3131
setup_requires = setuptools>=46.1; setuptools_scm[toml]>=3.4.3
32+
python_requires = >=3.6
3233

3334
[options.entry_points]
3435
distutils.commands =

setup.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,4 @@
33
from setuptools import setup
44

55
if __name__ == "__main__":
6-
setup(
7-
python_requires='>=3.5'
8-
)
6+
setup()

setuptools_rust/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from __future__ import print_function, absolute_import
2-
31
from .build import build_rust
42
from .check import check_rust
53
from .clean import clean_rust

setuptools_rust/build.py

Lines changed: 21 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,25 @@
1-
from __future__ import print_function, absolute_import
21
import glob
32
import json
43
import os
54
import shutil
65
import sys
76
import subprocess
8-
from distutils.cmd import Command
97
from distutils.errors import (
108
CompileError,
119
DistutilsExecError,
1210
DistutilsFileError,
13-
DistutilsPlatformError,
14-
DistutilsSetupError,
1511
)
1612
from subprocess import check_output
1713

14+
from .command import RustCommand
1815
from .extension import RustExtension
1916
from .utils import (
20-
Binding, Strip, cpython_feature, get_rust_version, get_rust_target_info
17+
Binding, Strip, rust_features, get_rust_target_info
2118
)
2219

2320

24-
class build_rust(Command):
25-
""" Command for building rust crates via cargo. """
21+
class build_rust(RustCommand):
22+
""" Command for building Rust crates via cargo. """
2623

2724
description = "build Rust extensions (compile/link to build directory)"
2825

@@ -33,9 +30,9 @@ class build_rust(Command):
3330
"ignore build-lib and put compiled extensions into the source "
3431
+ "directory alongside your pure Python modules",
3532
),
36-
("debug", "d", "Force debug to true for all rust extensions "),
37-
("release", "r", "Force debug to false for all rust extensions "),
38-
("qbuild", None, "Force enable quiet option for all rust extensions "),
33+
("debug", "d", "Force debug to true for all Rust extensions "),
34+
("release", "r", "Force debug to false for all Rust extensions "),
35+
("qbuild", None, "Force enable quiet option for all Rust extensions "),
3936
(
4037
"build-temp",
4138
"t",
@@ -45,7 +42,7 @@ class build_rust(Command):
4542
boolean_options = ["inplace", "debug", "release", "qbuild"]
4643

4744
def initialize_options(self):
48-
self.extensions = ()
45+
super().initialize_options()
4946
self.inplace = None
5047
self.debug = None
5148
self.release = None
@@ -54,11 +51,7 @@ def initialize_options(self):
5451
self.plat_name = None
5552

5653
def finalize_options(self):
57-
self.extensions = [
58-
ext
59-
for ext in self.distribution.rust_extensions
60-
if isinstance(ext, RustExtension)
61-
]
54+
super().finalize_options()
6255

6356
# Inherit settings from the `build_ext` command
6457
self.set_undefined_options(
@@ -68,7 +61,7 @@ def finalize_options(self):
6861
("inplace", "inplace"),
6962
)
7063

71-
def build_extension(self, ext):
64+
def run_for_extension(self, ext: RustExtension):
7265
executable = ext.binding == Binding.Exec
7366

7467
rust_target_info = get_rust_target_info()
@@ -94,7 +87,6 @@ def build_extension(self, ext):
9487
# we'll target a 32-bit Rust build.
9588
# Automatic target detection can be overridden via the CARGO_BUILD_TARGET
9689
# environment variable.
97-
# TODO: include --target for all platforms so env vars can't break the build
9890
target_triple = None
9991
target_args = []
10092
if os.getenv("CARGO_BUILD_TARGET"):
@@ -116,17 +108,16 @@ def build_extension(self, ext):
116108
"--format-version",
117109
"1",
118110
]
119-
# The decoding is needed for python 3.5 compatibility
120-
metadata = json.loads(check_output(metadata_command).decode("utf-8"))
111+
metadata = json.loads(check_output(metadata_command))
121112
target_dir = metadata["target_directory"]
122113

123114
if not os.path.exists(ext.path):
124115
raise DistutilsFileError(
125-
"Can not find rust extension project file: %s" % ext.path
116+
f"can't find Rust extension project file: {ext.path}"
126117
)
127118

128119
features = set(ext.features)
129-
features.update(cpython_feature(binding=ext.binding))
120+
features.update(rust_features(binding=ext.binding))
130121

131122
debug_build = ext.debug if ext.debug is not None else self.inplace
132123
debug_build = self.debug if self.debug is not None else debug_build
@@ -190,24 +181,19 @@ def build_extension(self, ext):
190181

191182
# Execute cargo
192183
try:
193-
output = subprocess.check_output(args, env=env)
184+
output = subprocess.check_output(args, env=env, encoding="latin-1")
194185
except subprocess.CalledProcessError as e:
195-
output = e.output
196-
if isinstance(output, bytes):
197-
output = e.output.decode("latin-1").strip()
198186
raise CompileError(
199-
"cargo failed with code: %d\n%s" % (e.returncode, output)
187+
f"cargo failed with code: {e.returncode}\n{e.output}"
200188
)
201189

202190
except OSError:
203191
raise DistutilsExecError(
204192
"Unable to execute 'cargo' - this package "
205-
"requires rust to be installed and cargo to be on the PATH"
193+
"requires Rust to be installed and cargo to be on the PATH"
206194
)
207195

208196
if not quiet:
209-
if isinstance(output, bytes):
210-
output = output.decode("latin-1")
211197
if output:
212198
print(output, file=sys.stderr)
213199

@@ -231,8 +217,8 @@ def build_extension(self, ext):
231217
continue
232218
else:
233219
raise DistutilsExecError(
234-
"rust build failed; "
235-
'unable to find executable "%s" in %s' % (name, target_dir)
220+
"Rust build failed; "
221+
f"unable to find executable '{name}' in '{target_dir}'"
236222
)
237223
else:
238224
# search executable
@@ -247,7 +233,7 @@ def build_extension(self, ext):
247233

248234
if not dylib_paths:
249235
raise DistutilsExecError(
250-
"rust build failed; unable to find executable in %s" % target_dir
236+
f"Rust build failed; unable to find executable in {target_dir}"
251237
)
252238
else:
253239
if sys.platform == "win32" or sys.platform == "cygwin":
@@ -268,8 +254,7 @@ def build_extension(self, ext):
268254
)
269255
except StopIteration:
270256
raise DistutilsExecError(
271-
"rust build failed; unable to find any %s in %s"
272-
% (wildcard_so, artifactsdir)
257+
f"Rust build failed; unable to find any {wildcard_so} in {artifactsdir}"
273258
)
274259

275260
# Ask build_ext where the shared library would go if it had built it,
@@ -303,11 +288,7 @@ def build_extension(self, ext):
303288
finally:
304289
del build_ext.ext_map[modpath]
305290

306-
try:
307-
os.makedirs(os.path.dirname(ext_path))
308-
except OSError:
309-
pass
310-
291+
os.makedirs(os.path.dirname(ext_path), exist_ok=True)
311292
shutil.copyfile(dylib_path, ext_path)
312293

313294
if sys.platform != "win32" and not debug_build:
@@ -330,40 +311,3 @@ def build_extension(self, ext):
330311
mode = os.stat(ext_path).st_mode
331312
mode |= (mode & 0o444) >> 2 # copy R bits to X
332313
os.chmod(ext_path, mode)
333-
334-
def run(self):
335-
if not self.extensions:
336-
return
337-
338-
all_optional = all(ext.optional for ext in self.extensions)
339-
try:
340-
version = get_rust_version()
341-
except DistutilsPlatformError as e:
342-
if not all_optional:
343-
raise
344-
else:
345-
print(str(e))
346-
return
347-
348-
for ext in self.extensions:
349-
try:
350-
rust_version = ext.get_rust_version()
351-
if rust_version is not None and version not in rust_version:
352-
raise DistutilsPlatformError(
353-
"Rust %s does not match extension requirement %s"
354-
% (version, ext.rust_version)
355-
)
356-
357-
self.build_extension(ext)
358-
except (
359-
DistutilsSetupError,
360-
DistutilsFileError,
361-
DistutilsExecError,
362-
DistutilsPlatformError,
363-
CompileError,
364-
) as e:
365-
if not ext.optional:
366-
raise
367-
else:
368-
print("Build optional Rust extension %s failed." % ext.name)
369-
print(str(e))

0 commit comments

Comments
 (0)