-
Notifications
You must be signed in to change notification settings - Fork 104
Update README/docs to use pyproject.toml
+ separate setup.py
docs
#356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
6d94c40
Modify setup.py example to be easier to write a tutorial
abravalheri 0c92b8e
Add separated docs about setup.py usage
abravalheri 09e2862
Add 'docs' session to noxfile to facilitate development
abravalheri d3e1896
Update README to use pyproject.toml instead of setup.py
abravalheri 38d0322
Update building_wheels docs to avoid using setup.py
abravalheri 172fa35
Remove reference to setup.py in API docs
abravalheri b16c90f
Fix formating in example
abravalheri a0fdd84
Fix toml syntax error in README
abravalheri 1b90362
Apply suggestions from code review
abravalheri a4e5c72
Tweak README based on review
abravalheri File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
:hidden: | ||
|
||
README.md | ||
setuppy_tutorial | ||
building_wheels | ||
reference | ||
``` | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# Usage with `setup.py` | ||
|
||
While `pyproject.toml`-based configuration will be enough for most projects, | ||
sometimes you may need to use custom logic and imperative programming during the build. | ||
For those scenarios, `setuptools` also allows you to specify project configuration | ||
via `setup.py` in addition to `pyproject.toml`. | ||
|
||
The following is a very basic tutorial that shows how to use `setuptools-rust` in | ||
your `setup.py`. | ||
|
||
|
||
## Basic implementation files | ||
|
||
Let's start by assuming that you already have a bunch of Python and Rust files[^1] | ||
that you would like to package for distribution in PyPI inside of a project directory | ||
named `hello-world-setuppy`[^2][^3]: | ||
|
||
[^1]: To know more about how to write Rust to be integrated into Python packages, | ||
please have a look on the [PyO3 docs](https://pyo3.rs) | ||
[^2]: You can have a look on the | ||
[examples/hello-world-setuppy](https://github.com/PyO3/setuptools-rust/tree/main/examples/hello-world-setuppy) | ||
directory in the `setuptools-rust` repository. | ||
[^3]: If you are an experienced Python or Rust programmer, you may notice that we | ||
avoid using the `src` directory and explicitly instruct Setuptools and Cargo to | ||
look into the `python` and `rust` directories respectively. | ||
Since both Python and Rust ecosystem will try to claim the `src` directory as | ||
their default, we prefer to be explicit and avoid confusion. | ||
|
||
|
||
``` | ||
hello-world-setuppy | ||
├── Cargo.lock | ||
├── Cargo.toml | ||
├── python | ||
│ └── hello_world | ||
│ └── __init__.py | ||
└── rust | ||
└── lib.rs | ||
``` | ||
|
||
```{literalinclude} ../examples/hello-world-setuppy/python/hello_world/__init__.py | ||
:language: python | ||
``` | ||
|
||
```{literalinclude} ../examples/hello-world-setuppy/rust/lib.rs | ||
:language: rust | ||
``` | ||
|
||
```{literalinclude} ../examples/hello-world-setuppy/Cargo.toml | ||
:language: toml | ||
``` | ||
|
||
|
||
## Adding files to support packaging | ||
|
||
Now we start by adding a `pyproject.toml` which tells anyone that wants to use | ||
our project to use `setuptools` and `setuptools-rust` to build it: | ||
|
||
```{literalinclude} ../examples/hello-world-setuppy/pyproject.toml | ||
:language: toml | ||
``` | ||
|
||
… and a [`setup.py` configuration file](https://setuptools.pypa.io/en/latest/references/keywords.html) | ||
that tells Setuptools how to build the Rust extensions using our `Cargo.toml` and `setuptools-rust`: | ||
|
||
```{literalinclude} ../examples/hello-world-setuppy/setup.py | ||
:language: python | ||
``` | ||
|
||
For a complete reference of the options supported by the `RustExtension` class, see the | ||
[API reference](https://setuptools-rust.readthedocs.io/en/latest/reference.html). | ||
|
||
|
||
We also add a [`MANIFEST.in` file](https://setuptools.pypa.io/en/latest/userguide/miscellaneous.html) | ||
to control which files we want in the source distribution[^4]: | ||
|
||
```{literalinclude} ../examples/hello-world-setuppy/MANIFEST.in | ||
``` | ||
|
||
[^4]: Alternatively you can also use `setuptools-scm` to add all the files under revision control | ||
to the `sdist`, see the [docs](https://pypi.org/project/setuptools-scm/) for more information. | ||
|
||
|
||
## Testing the extension | ||
|
||
With these files in place, you can install the project in a virtual environment | ||
for testing and making sure everything is working correctly: | ||
|
||
|
||
```powershell | ||
# cd hello-world-setuppy | ||
python3 -m venv .venv | ||
source .venv/bin/activate # on Linux or macOS | ||
.venv\Scripts\activate # on Windows | ||
python -m pip install -e . | ||
python -c 'import hello_world; print(hello_world.sum_as_string(5, 7))' # => 12 | ||
# ... better write some tests with pytest ... | ||
``` | ||
|
||
|
||
## Next steps and final remarks | ||
|
||
- When you are ready to distribute your project, have a look on | ||
[the notes in the documentation about building wheels](https://setuptools-rust.readthedocs.io/en/latest/building_wheels.html). | ||
|
||
- You can also use a [`RustBin`](https://setuptools-rust.readthedocs.io/en/latest/reference.html) object | ||
(instead of a `RustExtension`), if you want to distribute a binary executable | ||
written in Rust (instead of a library that can be imported by the Python runtime). | ||
Note however that distributing both library and executable (or multiple executables), | ||
may significantly increase the size of the | ||
[wheel](https://packaging.python.org/en/latest/glossary/#term-Wheel) | ||
file distributed by the | ||
[package index](https://packaging.python.org/en/latest/glossary/#term-Package-Index) | ||
and therefore increase build, download and installation times. | ||
Another approach is to use a Python entry-point that calls the Rust | ||
implementation (exposed via PyO3 bindings). | ||
See the [hello-world](https://github.com/PyO3/setuptools-rust/tree/main/examples/hello-world) | ||
example for more insights. | ||
|
||
- If want to include both `RustBin` and `RustExtension` same macOS wheel, you might have | ||
to manually add an extra `build.rs` file, see [PyO3/setuptools-rust#351](https://github.com/PyO3/setuptools-rust/pull/351) | ||
for more information about the workaround. | ||
|
||
- Since the adoption of {pep}`517`, running `python setup.py ...` directly as a CLI tool is | ||
[considered deprecated](https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html). | ||
Nevertheless, `setup.py` can be safely used as a configuration file | ||
(the same way `conftest.py` is used by `pytest` or `noxfile.py` is used by `nox`). | ||
There is a different mindset that comes with this change, though: | ||
for example, it does not make sense to use `sys.exit(0)` in a `setup.py` file | ||
or use a overarching `try...except...` block to re-run a failed build with different parameters. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also mention
rust-cpython
here? Although I don't think there is any example usingrust-cpython
(or is there?)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine as-is;
rust-cpython
is relatively unmaintained recently and as you say we also lack any example of it here. I think if someone wanted to contribute an example and extend documentation to discussrust-cpython
I would accept it, just no need to block this PR on it.