Skip to content

Commit 824f5ed

Browse files
committed
Merge branch 'main' into once-cell-ext
2 parents bde8b75 + b788b9b commit 824f5ed

File tree

178 files changed

+767
-619
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

178 files changed

+767
-619
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,11 @@ jobs:
415415
- uses: Swatinem/rust-cache@v2
416416
with:
417417
save-if: ${{ github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'CI-save-pr-cache') }}
418-
- uses: dtolnay/rust-toolchain@nightly
418+
- uses: dtolnay/rust-toolchain@master
419419
with:
420420
components: rust-src
421+
# FIXME: unpin once https://github.com/rust-lang/rust/issues/145437 is resolved
422+
toolchain: nightly-2025-08-14
421423
- uses: taiki-e/install-action@cargo-careful
422424
- run: python -m pip install --upgrade pip && pip install nox
423425
- run: nox -s test-rust -- careful skip-full
@@ -437,9 +439,11 @@ jobs:
437439
- uses: Swatinem/rust-cache@v2
438440
with:
439441
save-if: ${{ github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'CI-save-pr-cache') }}
440-
- uses: dtolnay/rust-toolchain@nightly
442+
- uses: dtolnay/rust-toolchain@master
441443
with:
442444
components: rust-src
445+
# FIXME: unpin once https://github.com/rust-lang/rust/issues/145437 is resolved
446+
toolchain: nightly-2025-08-14
443447
- run: cargo rustdoc --lib --no-default-features --features full,jiff-02 -Zunstable-options --config "build.rustdocflags=[\"--cfg\", \"docsrs\"]"
444448

445449
emscripten:

.github/workflows/gh-pages.yml

Lines changed: 0 additions & 66 deletions
This file was deleted.

.github/workflows/netlify-build.yml

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ jobs:
2828

2929
- uses: dtolnay/rust-toolchain@nightly
3030

31-
- name: Use nightly
32-
run: |
33-
rustup update nightly
34-
rustup default nightly
35-
3631
- name: Setup mdBook
3732
uses: taiki-e/install-action@v2
3833
with:
@@ -46,19 +41,39 @@ jobs:
4641
args: --version
4742
lycheeVersion: nightly
4843

49-
- name: Get current PyO3 version
50-
run: |
51-
PYO3_VERSION=$(cargo search pyo3 --limit 1 | head -1 | tr -s ' ' | cut -d ' ' -f 3 | tr -d '"')
52-
echo "PYO3_VERSION=${PYO3_VERSION}" >> $GITHUB_ENV
53-
5444
- name: Prepare tag
5545
id: prepare_tag
5646
run: |
5747
TAG_NAME="${GITHUB_REF##*/}"
5848
echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT
5949
60-
# Build the site
61-
- name: Prepare the versioned guide entries
50+
# This builds the book in target/guide/.
51+
- name: Build the guide
52+
run: |
53+
python -m pip install --upgrade pip && pip install nox
54+
nox -s ${{ github.event_name == 'release' && 'build-guide' || 'check-guide' }}
55+
env:
56+
PYO3_VERSION_TAG: ${{ steps.prepare_tag.outputs.tag_name }}
57+
# allows lychee to get better rate limits from github
58+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59+
60+
# We store the versioned guides on GitHub's gh-pages branch for convenience
61+
# (the full gh-pages branch is pulled in the build-netlify-site step)
62+
- name: Deploy the guide
63+
if: ${{ github.event_name == 'release' }}
64+
uses: peaceiris/actions-gh-pages@v4
65+
with:
66+
github_token: ${{ secrets.GITHUB_TOKEN }}
67+
publish_dir: ./target/guide/
68+
destination_dir: ${{ steps.prepare_tag.outputs.tag_name }}
69+
full_commit_message: "Upload documentation for ${{ steps.prepare_tag.outputs.tag_name }}"
70+
71+
- name: Get current PyO3 version
72+
run: |
73+
PYO3_VERSION=$(cargo search pyo3 --limit 1 | head -1 | tr -s ' ' | cut -d ' ' -f 3 | tr -d '"')
74+
echo "PYO3_VERSION=${PYO3_VERSION}" >> $GITHUB_ENV
75+
76+
- name: Build the site
6277
run: |
6378
python -m pip install --upgrade pip && pip install nox towncrier requests
6479
nox -s build-netlify-site -- ${{ (github.ref != 'refs/heads/main' && '--preview') || '' }}

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,12 @@ about this topic.
236236

237237
## Articles and other media
238238

239+
- [(Video) Using Rust in Free-Threaded vs Regular Python 3.13](https://www.youtube.com/watch?v=J7phN_M4GLM) - Jun 4, 2025
240+
- [(Video) Techniques learned from five years finding the way for Rust in Python](https://www.youtube.com/watch?v=KTQn_PTHNCw) - Feb 26, 2025
241+
- [(Podcast) Bridging Python and Rust: An Interview with PyO3 Maintainer David Hewitt](https://www.youtube.com/watch?v=P47JUMSQagU) - Aug 30, 2024
239242
- [(Video) PyO3: From Python to Rust and Back Again](https://www.youtube.com/watch?v=UmL_CA-v3O8) - Jul 3, 2024
240243
- [Parsing Python ASTs 20x Faster with Rust](https://www.gauge.sh/blog/parsing-python-asts-20x-faster-with-rust) - Jun 17, 2024
241-
- [(Video) How Python Harnesses Rust through PyO3](https://www.youtube.com/watch?v=UkZ_m3Wj2hA) - May 18, 2024
244+
- [(Video) How Python Harnesses Rust through PyO3](https://www.youtube.com/watch?v=UilujdubqVU) - May 18, 2024
242245
- [(Video) Combining Rust and Python: The Best of Both Worlds?](https://www.youtube.com/watch?v=lyG6AKzu4ew) - Mar 1, 2024
243246
- [(Video) Extending Python with Rust using PyO3](https://www.youtube.com/watch?v=T45ZEmSR1-s) - Dec 16, 2023
244247
- [A Week of PyO3 + rust-numpy (How to Speed Up Your Data Pipeline X Times)](https://terencezl.github.io/blog/2023/06/06/a-week-of-pyo3-rust-numpy/) - Jun 6, 2023
@@ -250,7 +253,7 @@ about this topic.
250253
- [Calling Rust from Python using PyO3](https://saidvandeklundert.net/learn/2021-11-18-calling-rust-from-python-using-pyo3/) - Nov 18, 2021
251254
- [davidhewitt's 2021 talk at Rust Manchester meetup](https://www.youtube.com/watch?v=-XyWG_klSAw&t=320s) - Aug 19, 2021
252255
- [Incrementally porting a small Python project to Rust](https://blog.waleedkhan.name/port-python-to-rust/) - Apr 29, 2021
253-
- [Vortexa - Integrating Rust into Python](https://www.vortexa.com/insight/integrating-rust-into-python) - Apr 12, 2021
256+
- [Vortexa - Integrating Rust into Python](https://www.vortexa.com/blog/integrating-rust-into-python) - Apr 12, 2021
254257
- [Writing and publishing a Python module in Rust](https://blog.yossarian.net/2020/08/02/Writing-and-publishing-a-python-module-in-rust) - Aug 2, 2020
255258

256259
## Contributing

guide/src/async-await.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use pyo3::prelude::*;
1313
1414
#[pyfunction]
1515
#[pyo3(signature=(seconds, result=None))]
16-
async fn sleep(seconds: f64, result: Option<PyObject>) -> Option<PyObject> {
16+
async fn sleep(seconds: f64, result: Option<Py<PyAny>>) -> Option<Py<PyAny>> {
1717
let (tx, rx) = oneshot::channel();
1818
thread::spawn(move || {
1919
thread::sleep(Duration::from_secs_f64(seconds));

guide/src/class.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ impl SubSubClass {
413413
}
414414

415415
#[staticmethod]
416-
fn factory_method(py: Python<'_>, val: usize) -> PyResult<PyObject> {
416+
fn factory_method(py: Python<'_>, val: usize) -> PyResult<Py<PyAny>> {
417417
let base = PyClassInitializer::from(BaseClass::new());
418418
let sub = base.add_subclass(SubClass { val2: val });
419419
if val % 2 == 0 {
@@ -748,7 +748,7 @@ To create a constructor which takes a positional class argument, you can combine
748748
# use pyo3::prelude::*;
749749
# use pyo3::types::PyType;
750750
# #[pyclass]
751-
# struct BaseClass(PyObject);
751+
# struct BaseClass(Py<PyAny>);
752752
#
753753
#[pymethods]
754754
impl BaseClass {
@@ -1385,7 +1385,12 @@ unsafe impl pyo3::type_object::PyTypeInfo for MyClass {
13851385
#[inline]
13861386
fn type_object_raw(py: pyo3::Python<'_>) -> *mut pyo3::ffi::PyTypeObject {
13871387
<Self as pyo3::impl_::pyclass::PyClassImpl>::lazy_type_object()
1388-
.get_or_init(py)
1388+
.get_or_try_init(py)
1389+
.unwrap_or_else(|e| pyo3::impl_::pyclass::type_object_init_failed(
1390+
py,
1391+
e,
1392+
<Self as pyo3::type_object::PyTypeInfo>::NAME
1393+
))
13891394
.as_type_ptr()
13901395
}
13911396
}

guide/src/class/numeric.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ Let's create that helper function. The signature has to be `fn(&Bound<'_, PyAny>
417417
418418
```rust,no_run
419419
# #![allow(dead_code)]
420-
use std::os::raw::c_ulong;
420+
use std::ffi::c_ulong;
421421
use pyo3::prelude::*;
422422
use pyo3::ffi;
423423

guide/src/class/protocols.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ given signatures should be interpreted as follows:
5959
#[pymethods]
6060
impl NotHashable {
6161
#[classattr]
62-
const __hash__: Option<PyObject> = None;
62+
const __hash__: Option<Py<PyAny>> = None;
6363
}
6464
```
6565
</details>
@@ -162,15 +162,15 @@ use std::sync::Mutex;
162162
163163
#[pyclass]
164164
struct MyIterator {
165-
iter: Mutex<Box<dyn Iterator<Item = PyObject> + Send>>,
165+
iter: Mutex<Box<dyn Iterator<Item = Py<PyAny>> + Send>>,
166166
}
167167
168168
#[pymethods]
169169
impl MyIterator {
170170
fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
171171
slf
172172
}
173-
fn __next__(slf: PyRefMut<'_, Self>) -> Option<PyObject> {
173+
fn __next__(slf: PyRefMut<'_, Self>) -> Option<Py<PyAny>> {
174174
slf.iter.lock().unwrap().next()
175175
}
176176
}
@@ -283,7 +283,7 @@ Use the `#[pyclass(sequence)]` annotation to instruct PyO3 to fill the `sq_lengt
283283
#[pymethods]
284284
impl NoContains {
285285
#[classattr]
286-
const __contains__: Option<PyObject> = None;
286+
const __contains__: Option<Py<PyAny>> = None;
287287
}
288288
```
289289
</details>
@@ -439,7 +439,7 @@ use pyo3::gc::PyVisit;
439439
440440
#[pyclass]
441441
struct ClassWithGCSupport {
442-
obj: Option<PyObject>,
442+
obj: Option<Py<PyAny>>,
443443
}
444444
445445
#[pymethods]

guide/src/conversions/tables.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Mapping of Rust types to Python types
22

3-
When writing functions callable from Python (such as a `#[pyfunction]` or in a `#[pymethods]` block), the trait `FromPyObject` is required for function arguments, and `IntoPy<PyObject>` is required for function return values.
3+
When writing functions callable from Python (such as a `#[pyfunction]` or in a `#[pymethods]` block), the trait `FromPyObject` is required for function arguments, and `IntoPyObject` is required for function return values.
44

55
Consult the tables in the following section to find the Rust types provided by PyO3 which implement these traits.
66

@@ -54,7 +54,6 @@ It is also worth remembering the following special types:
5454
| `Python<'py>` | A GIL token, used to pass to PyO3 constructors to prove ownership of the GIL. |
5555
| `Bound<'py, T>` | A Python object connected to the GIL lifetime. This provides access to most of PyO3's APIs. |
5656
| `Py<T>` | A Python object isolated from the GIL lifetime. This can be sent to other threads. |
57-
| `PyObject` | An alias for `Py<PyAny>` |
5857
| `PyRef<T>` | A `#[pyclass]` borrowed immutably. |
5958
| `PyRefMut<T>` | A `#[pyclass]` borrowed mutably. |
6059

guide/src/conversions/traits.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ forward the implementation to the inner type.
580580
581581
// newtype tuple structs are implicitly `transparent`
582582
#[derive(IntoPyObject)]
583-
struct TransparentTuple(PyObject);
583+
struct TransparentTuple(Py<PyAny>);
584584
585585
#[derive(IntoPyObject)]
586586
#[pyo3(transparent)]
@@ -599,7 +599,7 @@ For `enum`s each variant is converted according to the rules for `struct`s above
599599
600600
#[derive(IntoPyObject)]
601601
enum Enum<'a, 'py, K: Hash + Eq, V> { // enums are supported and convert using the same
602-
TransparentTuple(PyObject), // rules on the variants as the structs above
602+
TransparentTuple(Py<PyAny>), // rules on the variants as the structs above
603603
#[pyo3(transparent)]
604604
TransparentStruct { inner: Bound<'py, PyAny> },
605605
Tuple(&'a str, HashMap<K, V>),
@@ -645,7 +645,7 @@ demonstrated below.
645645
```rust,no_run
646646
# use pyo3::prelude::*;
647647
# #[allow(dead_code)]
648-
struct MyPyObjectWrapper(PyObject);
648+
struct MyPyObjectWrapper(Py<PyAny>);
649649
650650
impl<'py> IntoPyObject<'py> for MyPyObjectWrapper {
651651
type Target = PyAny; // the Python type
@@ -741,7 +741,6 @@ In the example above we used `BoundObject::into_any` and `BoundObject::unbind` t
741741
[`FromPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.FromPyObject.html
742742
[`IntoPyObject`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.IntoPyObject.html
743743
[`IntoPyObjectExt`]: {{#PYO3_DOCS_URL}}/pyo3/conversion/trait.IntoPyObjectExt.html
744-
[`PyObject`]: {{#PYO3_DOCS_URL}}/pyo3/type.PyObject.html
745744

746745
[`PyRef`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRef.html
747746
[`PyRefMut`]: {{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyRefMut.html

0 commit comments

Comments
 (0)