Skip to content

Commit 1a3e53f

Browse files
davidhewittIcxolu
andauthored
docs: use one sentence per line in guide (#5534)
* docs: use one sentence per line in guide * formatting corrections * disable MD013 for paragraphs, tables, headings, and code blocks * remove unneeded comment --------- Co-authored-by: Icxolu <10486322+Icxolu@users.noreply.github.com>
1 parent d15a14a commit 1a3e53f

37 files changed

+1073
-823
lines changed

guide/src/advanced.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44

55
PyO3 exposes much of Python's C API through the `ffi` module.
66

7-
The C API is naturally unsafe and requires you to manage reference counts, errors and specific invariants yourself. Please refer to the [C API Reference Manual](https://docs.python.org/3/c-api/) and [The Rustonomicon](https://doc.rust-lang.org/nightly/nomicon/ffi.html) before using any function from that API.
7+
The C API is naturally unsafe and requires you to manage reference counts, errors and specific invariants yourself.
8+
Please refer to the [C API Reference Manual](https://docs.python.org/3/c-api/) and [The Rustonomicon](https://doc.rust-lang.org/nightly/nomicon/ffi.html) before using any function from that API.

guide/src/async-await.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,19 @@ async fn sleep(seconds: f64, result: Option<Py<PyAny>>) -> Option<Py<PyAny>> {
2525
# }
2626
```
2727

28-
*Python awaitables instantiated with this method can only be awaited in *asyncio* context. Other Python async runtime may be supported in the future.*
28+
*Python awaitables instantiated with this method can only be awaited in `asyncio` context. Other Python async runtime may be supported in the future.*
2929

3030
## `Send + 'static` constraint
3131

3232
Resulting future of an `async fn` decorated by `#[pyfunction]` must be `Send + 'static` to be embedded in a Python object.
3333

3434
As a consequence, `async fn` parameters and return types must also be `Send + 'static`, so it is not possible to have a signature like `async fn does_not_compile<'py>(arg: Bound<'py, PyAny>) -> Bound<'py, PyAny>`.
3535

36-
However, there is an exception for method receivers, so async methods can accept `&self`/`&mut self`. Note that this means that the class instance is borrowed for as long as the returned future is not completed, even across yield points and while waiting for I/O operations to complete. Hence, other methods cannot obtain exclusive borrows while the future is still being polled. This is the same as how async methods in Rust generally work but it is more problematic for Rust code interfacing with Python code due to pervasive shared mutability. This strongly suggests to prefer shared borrows `&self` over exclusive ones `&mut self` to avoid racy borrow check failures at runtime.
36+
However, there is an exception for method receivers, so async methods can accept `&self`/ `&mut self`.
37+
Note that this means that the class instance is borrowed for as long as the returned future is not completed, even across yield points and while waiting for I/O operations to complete.
38+
Hence, other methods cannot obtain exclusive borrows while the future is still being polled.
39+
This is the same as how async methods in Rust generally work but it is more problematic for Rust code interfacing with Python code due to pervasive shared mutability.
40+
This strongly suggests to prefer shared borrows `&self` over exclusive ones `&mut self` to avoid racy borrow check failures at runtime.
3741

3842
## Implicitly attached to the interpreter
3943

@@ -98,6 +102,7 @@ async fn cancellable(#[pyo3(cancel_handle)] mut cancel: CancelHandle) {
98102

99103
To make a Rust future awaitable in Python, PyO3 defines a [`Coroutine`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.Coroutine.html) type, which implements the Python [coroutine protocol](https://docs.python.org/3/library/collections.abc.html#collections.abc.Coroutine).
100104

101-
Each `coroutine.send` call is translated to a `Future::poll` call. If a [`CancelHandle`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.CancelHandle.html) parameter is declared, the exception passed to `coroutine.throw` call is stored in it and can be retrieved with [`CancelHandle::cancelled`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.CancelHandle.html#method.cancelled); otherwise, it cancels the Rust future, and the exception is reraised;
105+
Each `coroutine.send` call is translated to a `Future::poll` call.
106+
If a [`CancelHandle`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.CancelHandle.html) parameter is declared, the exception passed to `coroutine.throw` call is stored in it and can be retrieved with [`CancelHandle::cancelled`]({{#PYO3_DOCS_URL}}/pyo3/coroutine/struct.CancelHandle.html#method.cancelled); otherwise, it cancels the Rust future, and the exception is reraised;
102107

103108
*The type does not yet have a public constructor until the design is finalized.*

guide/src/building-and-distribution.md

Lines changed: 103 additions & 52 deletions
Large diffs are not rendered by default.

guide/src/building-and-distribution/multiple-python-versions.md

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
# Supporting multiple Python versions
22

3-
PyO3 supports all actively-supported Python 3 and PyPy versions. As much as possible, this is done internally to PyO3 so that your crate's code does not need to adapt to the differences between each version. However, as Python features grow and change between versions, PyO3 cannot offer a completely identical API for every Python version. This may require you to add conditional compilation to your crate or runtime checks for the Python version.
3+
PyO3 supports all actively-supported Python 3 and PyPy versions.
4+
As much as possible, this is done internally to PyO3 so that your crate's code does not need to adapt to the differences between each version.
5+
However, as Python features grow and change between versions, PyO3 cannot offer a completely identical API for every Python version.
6+
This may require you to add conditional compilation to your crate or runtime checks for the Python version.
47

58
This section of the guide first introduces the `pyo3-build-config` crate, which you can use as a `build-dependency` to add additional `#[cfg]` flags which allow you to support multiple Python versions at compile-time.
69

7-
Second, we'll show how to check the Python version at runtime. This can be useful when building for multiple versions with the `abi3` feature, where the Python API compiled against is not always the same as the one in use.
10+
Second, we'll show how to check the Python version at runtime.
11+
This can be useful when building for multiple versions with the `abi3` feature, where the Python API compiled against is not always the same as the one in use.
812

913
## Conditional compilation for different Python versions
1014

11-
The `pyo3-build-config` exposes multiple [`#[cfg]` flags](https://doc.rust-lang.org/rust-by-example/attribute/cfg.html) which can be used to conditionally compile code for a given Python version. PyO3 itself depends on this crate, so by using it you can be sure that you are configured correctly for the Python version PyO3 is building against.
15+
The `pyo3-build-config` exposes multiple [`#[cfg]` flags](https://doc.rust-lang.org/rust-by-example/attribute/cfg.html) which can be used to conditionally compile code for a given Python version.
16+
PyO3 itself depends on this crate, so by using it you can be sure that you are configured correctly for the Python version PyO3 is building against.
1217

1318
This allows us to write code like the following
1419

@@ -51,13 +56,15 @@ After these steps you are ready to annotate your code!
5156

5257
### Common usages of `pyo3-build-cfg` flags
5358

54-
The `#[cfg]` flags added by `pyo3-build-cfg` can be combined with all of Rust's logic in the `#[cfg]` attribute to create very precise conditional code generation. The following are some common patterns implemented using these flags:
59+
The `#[cfg]` flags added by `pyo3-build-cfg` can be combined with all of Rust's logic in the `#[cfg]` attribute to create very precise conditional code generation.
60+
The following are some common patterns implemented using these flags:
5561

5662
```text
5763
#[cfg(Py_3_7)]
5864
```
5965

60-
This `#[cfg]` marks code that will only be present on Python 3.7 and upwards. There are similar options `Py_3_8`, `Py_3_9`, `Py_3_10` and so on for each minor version.
66+
This `#[cfg]` marks code that will only be present on Python 3.7 and upwards.
67+
There are similar options `Py_3_8`, `Py_3_9`, `Py_3_10` and so on for each minor version.
6168

6269
```text
6370
#[cfg(not(Py_3_7))]
@@ -69,13 +76,15 @@ This `#[cfg]` marks code that will only be present on Python versions before (bu
6976
#[cfg(not(Py_LIMITED_API))]
7077
```
7178

72-
This `#[cfg]` marks code that is only available when building for the unlimited Python API (i.e. PyO3's `abi3` feature is not enabled). This might be useful if you want to ship your extension module as an `abi3` wheel and also allow users to compile it from source to make use of optimizations only possible with the unlimited API.
79+
This `#[cfg]` marks code that is only available when building for the unlimited Python API (i.e. PyO3's `abi3` feature is not enabled).
80+
This might be useful if you want to ship your extension module as an `abi3` wheel and also allow users to compile it from source to make use of optimizations only possible with the unlimited API.
7381

7482
```text
7583
#[cfg(any(Py_3_9, not(Py_LIMITED_API)))]
7684
```
7785

78-
This `#[cfg]` marks code which is available when running Python 3.9 or newer, or when using the unlimited API with an older Python version. Patterns like this are commonly seen on Python APIs which were added to the limited Python API in a specific minor version.
86+
This `#[cfg]` marks code which is available when running Python 3.9 or newer, or when using the unlimited API with an older Python version.
87+
Patterns like this are commonly seen on Python APIs which were added to the limited Python API in a specific minor version.
7988

8089
```text
8190
#[cfg(PyPy)]
@@ -87,11 +96,14 @@ This `#[cfg]` marks code which is running on PyPy.
8796

8897
When building with PyO3's `abi3` feature, your extension module will be compiled against a specific [minimum version](../building-and-distribution.md#minimum-python-version-for-abi3) of Python, but may be running on newer Python versions.
8998

90-
For example with PyO3's `abi3-py38` feature, your extension will be compiled as if it were for Python 3.8. If you were using `pyo3-build-config`, `#[cfg(Py_3_8)]` would be present. Your user could freely install and run your abi3 extension on Python 3.9.
99+
For example with PyO3's `abi3-py38` feature, your extension will be compiled as if it were for Python 3.8.
100+
If you were using `pyo3-build-config`, `#[cfg(Py_3_8)]` would be present.
101+
Your user could freely install and run your abi3 extension on Python 3.9.
91102

92103
There's no way to detect your user doing that at compile time, so instead you need to fall back to runtime checks.
93104

94-
PyO3 provides the APIs [`Python::version()`] and [`Python::version_info()`] to query the running Python version. This allows you to do the following, for example:
105+
PyO3 provides the APIs [`Python::version()`] and [`Python::version_info()`] to query the running Python version.
106+
This allows you to do the following, for example:
95107

96108
```rust
97109
use pyo3::Python;

0 commit comments

Comments
 (0)