Skip to content

Commit cce15dd

Browse files
authored
Merge pull request #277 from messense/simplify-install_rust_extension
Simplify `install_rust_extension` and `bdist_wheel_rust_extension`
2 parents 95412f4 + 6ad758b commit cce15dd

File tree

10 files changed

+89
-65
lines changed

10 files changed

+89
-65
lines changed

examples/hello-world-script/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "hello-world-script"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
10+
[profile.release-lto]
11+
inherits = "release"
12+
lto = true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include Cargo.toml
2+
recursive-include src *

examples/hello-world-script/hello_world/__init__.py

Whitespace-only changes.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from os.path import dirname
2+
3+
import nox
4+
5+
SETUPTOOLS_RUST = dirname(dirname(dirname(__file__)))
6+
7+
8+
@nox.session()
9+
def test(session: nox.Session):
10+
session.install(SETUPTOOLS_RUST)
11+
session.install("--no-build-isolation", ".")
12+
session.run("hello-world-script", *session.posargs)
13+
14+
15+
@nox.session()
16+
def setuptools_install(session: nox.Session):
17+
session.install("setuptools")
18+
with session.chdir(SETUPTOOLS_RUST):
19+
session.run("python", "setup.py", "install")
20+
session.run("python", "setup.py", "install")
21+
session.run("hello-world-script", *session.posargs)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build-system]
2+
requires = ["setuptools", "wheel", "setuptools-rust"]

examples/hello-world-script/pytest.ini

Whitespace-only changes.

examples/hello-world-script/setup.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from setuptools import setup
2+
3+
from setuptools_rust import RustExtension, Binding
4+
5+
setup(
6+
name="hello-world-script",
7+
version="1.0",
8+
rust_extensions=[
9+
RustExtension(
10+
{"hello-world-script": "hello_world.hello-world-script"},
11+
binding=Binding.Exec,
12+
script=True,
13+
args=["--profile", "release-lto"],
14+
)
15+
],
16+
# rust extensions are not zip safe, just like C-extensions.
17+
zip_safe=False,
18+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("Hello, world!");
3+
}

setuptools_rust/setuptools_ext.py

Lines changed: 24 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,25 @@ def add_rust_extension(dist: Distribution) -> None:
3939
sdist_boolean_options.append("vendor-crates")
4040
sdist_negative_opt["no-vendor-crates"] = "vendor-crates"
4141

42+
# Patch dist to include console_scripts for Exec binding
43+
console_scripts = []
44+
for ext in dist.rust_extensions: # type: ignore[attr-defined]
45+
console_scripts.extend(ext.entry_points())
46+
47+
if console_scripts:
48+
if not dist.entry_points: # type: ignore[attr-defined]
49+
dist.entry_points = {"console_scripts": console_scripts} # type: ignore[attr-defined]
50+
else:
51+
ep_scripts = dist.entry_points.get("console_scripts") # type: ignore[attr-defined]
52+
if ep_scripts:
53+
for script in console_scripts:
54+
if script not in ep_scripts:
55+
ep_scripts.append(console_scripts)
56+
else:
57+
ep_scripts = console_scripts
58+
59+
dist.entry_points["console_scripts"] = ep_scripts # type: ignore[attr-defined]
60+
4261
class sdist_rust_extension(sdist_base_class): # type: ignore[misc,valid-type]
4362
user_options = sdist_options
4463
boolean_options = sdist_boolean_options
@@ -152,53 +171,16 @@ def run(self) -> None:
152171

153172
install_base_class = cast(Type[install], dist.cmdclass.get("install", install))
154173

155-
# this is required because, install directly access distribution's
156-
# ext_modules attr to check if dist has ext modules
174+
# this is required to make install_scripts compatible with RustBin
157175
class install_rust_extension(install_base_class): # type: ignore[misc,valid-type]
158-
def finalize_options(self) -> None:
159-
ext_modules = self.distribution.ext_modules
160-
161-
# all ext modules
162-
mods = []
163-
if self.distribution.ext_modules:
164-
mods.extend(self.distribution.ext_modules)
165-
if self.distribution.rust_extensions:
166-
mods.extend(self.distribution.rust_extensions)
167-
168-
scripts = []
169-
for ext in self.distribution.rust_extensions:
170-
scripts.extend(ext.entry_points())
171-
172-
if scripts:
173-
if not self.distribution.entry_points:
174-
self.distribution.entry_points = {"console_scripts": scripts}
175-
else:
176-
ep_scripts = self.distribution.entry_points.get(
177-
"console_scripts"
178-
)
179-
if ep_scripts:
180-
for script in scripts:
181-
if script not in ep_scripts:
182-
ep_scripts.append(scripts)
183-
else:
184-
ep_scripts = scripts
185-
186-
self.distribution.entry_points["console_scripts"] = ep_scripts
187-
188-
self.distribution.ext_modules = mods
189-
190-
install_base_class.finalize_options(self)
191-
192-
# restore ext_modules
193-
self.distribution.ext_modules = ext_modules
194-
195176
def run(self) -> None:
196177
install_base_class.run(self)
197178
install_rustbin = False
198179
if self.distribution.rust_extensions:
199-
for ext in self.distribution.rust_extensions:
200-
if isinstance(ext, RustBin):
201-
install_rustbin = True
180+
install_rustbin = any(
181+
isinstance(ext, RustBin)
182+
for ext in self.distribution.rust_extensions
183+
)
202184
if install_rustbin:
203185
self.run_command("install_scripts")
204186

@@ -265,29 +247,6 @@ def initialize_options(self) -> None:
265247
super().initialize_options()
266248
self.target = os.getenv("CARGO_BUILD_TARGET")
267249

268-
def finalize_options(self) -> None:
269-
scripts = []
270-
for ext in self.distribution.rust_extensions:
271-
scripts.extend(ext.entry_points())
272-
273-
if scripts:
274-
if not self.distribution.entry_points:
275-
self.distribution.entry_points = {"console_scripts": scripts}
276-
else:
277-
ep_scripts = self.distribution.entry_points.get(
278-
"console_scripts"
279-
)
280-
if ep_scripts:
281-
for script in scripts:
282-
if script not in ep_scripts:
283-
ep_scripts.append(scripts)
284-
else:
285-
ep_scripts = scripts
286-
287-
self.distribution.entry_points["console_scripts"] = ep_scripts
288-
289-
bdist_wheel_base_class.finalize_options(self)
290-
291250
def get_tag(self) -> Tuple[str, str, str]:
292251
python, abi, plat = super().get_tag()
293252
arch_flags = os.getenv("ARCHFLAGS")

0 commit comments

Comments
 (0)