Skip to content
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

Bump version to 0.11.0 #989

Merged
merged 2 commits into from
Jun 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.11.0] - 2020-06-28
### Added
- Support stable versions of Rust (>=1.39). [#969](https://github.com/PyO3/pyo3/pull/969)
- Add FFI definition `PyObject_AsFileDescriptor`. [#938](https://github.com/PyO3/pyo3/pull/938)
Expand Down Expand Up @@ -426,7 +428,8 @@ Yanked
### Added
- Initial release

[Unreleased]: https://github.com/pyo3/pyo3/compare/v0.10.1...HEAD
[Unreleased]: https://github.com/pyo3/pyo3/compare/v0.11.0...HEAD
[0.11.0] https://github.com/pyo3/pyo3/compare/v0.10.1...v0.11.0
[0.10.1]: https://github.com/pyo3/pyo3/compare/v0.10.0...v0.10.1
[0.10.0]: https://github.com/pyo3/pyo3/compare/v0.9.2...v0.10.0
[0.9.2]: https://github.com/pyo3/pyo3/compare/v0.9.1...v0.9.2
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyo3"
version = "0.10.1"
version = "0.11.0"
description = "Bindings to Python interpreter"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
readme = "README.md"
Expand All @@ -27,7 +27,7 @@ parking_lot = "0.10.2"
num-bigint = { version = "0.3", optional = true }
num-complex = { version = "0.3", optional = true }
paste = { version = "0.1.6", optional = true }
pyo3cls = { path = "pyo3cls", version = "=0.10.1", optional = true }
pyo3cls = { path = "pyo3cls", version = "=0.11.0", optional = true }
unindent = { version = "0.1.4", optional = true }

[dev-dependencies]
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ name = "string_sum"
crate-type = ["cdylib"]

[dependencies.pyo3]
version = "0.10.1"
version = "0.11.0"
features = ["extension-module"]
```

Expand Down Expand Up @@ -98,7 +98,7 @@ use it to run Python code, add `pyo3` to your `Cargo.toml` like this:

```toml
[dependencies]
pyo3 = "0.10.1"
pyo3 = "0.11.0"
```

Example program displaying the value of `sys.version` and the current user name:
Expand Down
2 changes: 1 addition & 1 deletion guide/src/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Currently, [#341](https://github.com/PyO3/pyo3/issues/341) causes `cargo test` t

```toml
[dependencies.pyo3]
version = "0.8.1"
version = "0.11.0"

[features]
extension-module = ["pyo3/extension-module"]
Expand Down
68 changes: 68 additions & 0 deletions guide/src/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,74 @@
This guide can help you upgrade code through breaking changes from one PyO3 version to the next.
For a detailed list of all changes, see [CHANGELOG.md](https://github.com/PyO3/pyo3/blob/master/CHANGELOG.md)

## from 0.10.* to 0.11

### Stable Rust
PyO3 now supports the stable Rust toolchain. The minimum required version is 1.39.0.

### `#[pyclass]` structs must now be `Send`
Because `#[pyclass]` structs can be sent between threads by the Python interpreter, they must implement
`Send` to guarantee thread safety. This bound was added in PyO3 `0.11.0`.

This may "break" some code which previously was accepted, even though it was unsound. To resolve this,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should note that 'if you are sure that your class is not sent to another thread, you can use unsafe impl Send for YourClass {}' first. Actually it's rare to send pyclass to another thread, and I saw some #[pyclass]es that have a raw pointer internally and need unsafe impl Send when investigating the effect of this change.

This may "break" some code which previously was accepted, even though it was unsound.

Also, we have to note that it's theoretically unsound, but not problematic when the class is not actually sent to another thread by:

  • Python's threading module
  • py.allow_threads and Py

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should note that 'if you are sure that your class is not sent to another thread, you can use unsafe impl Send for YourClass {}' first.

I don't think that's good advice. It undermines protections on the Rust side, too.

Also, we have to note that it's theoretically unsound, but not problematic when the class is not actually sent to another thread by:

I don't know about your experience, but I use the threading module quite a lot in Python, and objects are accessed freely from any thread there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the feedback.

I don't know about your experience, but I use the threading module quite a lot in Python, and objects are accessed freely from any thread there.

Maybe it's because I use Python mainly for machine learning research, where CPU/GPU bound is dominant.
Then I would rather take back my words... but I still think we should note that unsafe impl Sync can be the easiest fix. Maybe it's also helpful to link std::marker::Send or nomicon.

Copy link
Member

@davidhewitt davidhewitt Jun 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not keen on suggesting unsafe impl Send or unsafe impl Sync - to me that feels like the kind of hack where "I know that I'm not using threads now, so I can skip writing safe code". Later on this hack is forgotten, the code gets edited to include threading and suddenly very strange bugs / crashes / undefined behaviour.

EDIT: changed my mind. I'm ok to suggest adding unsafe impl Send as long as we carefully explain that the responsibility is on the user to ensure the type is also thread-safe. But we have to explain this really clearly - because the undefined behaviour the user might see if they get this wrong could be pretty bad.

(My description of using unsafe impl Send as a hack still applies when the user uses it to skip making a type thread-safe.)

Adding in a link to docs / nomicon would be fine though.

consider using types like `Arc` instead of `Rc`, `Mutex` instead of `RefCell`, and add `Send` to any
boxed closures stored inside the `#[pyclass]`.

Before:
```rust,compile_fail
use pyo3::prelude::*;
use std::rc::Rc;
use std::cell::RefCell;

#[pyclass]
struct NotThreadSafe {
shared_bools: Rc<RefCell<Vec<bool>>>,
closure: Box<Fn()>
}
```

After:
```rust
use pyo3::prelude::*;
use std::sync::{Arc, Mutex};

#[pyclass]
struct ThreadSafe {
shared_bools: Arc<Mutex<Vec<bool>>>,
closure: Box<Fn() + Send>
}
```

Or in situations where you cannot change your `#[pyclass]` to automatically implement `Send`
(e.g., when it contains a raw pointer), you can use `unsafe impl Send`.
In such cases, care should be taken to ensure the struct is actually thread safe.
See [the Rustnomicon](ttps://doc.rust-lang.org/nomicon/send-and-sync.html) for more.

### All `PyObject` and `Py<T>` methods now take `Python` as an argument
Previously, a few methods such as `Object::get_refcnt` did not take `Python` as an argument (to
ensure that the Python GIL was held by the current thread). Technically, this was not sound.
To migrate, just pass a `py` argument to any calls to these methods.

Before:
```rust,compile_fail
use pyo3::prelude::*;

let gil = Python::acquire_gil();
let py = gil.python();

py.None().get_refcnt();
```

After:
```rust
use pyo3::prelude::*;

let gil = Python::acquire_gil();
let py = gil.python();

py.None().get_refcnt(py);
```

## from 0.9.* to 0.10

### `ObjectProtocol` is removed
Expand Down
2 changes: 1 addition & 1 deletion pyo3-derive-backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyo3-derive-backend"
version = "0.10.1"
version = "0.11.0"
description = "Code generation for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"]
Expand Down
4 changes: 2 additions & 2 deletions pyo3cls/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyo3cls"
version = "0.10.1"
version = "0.11.0"
description = "Proc macros for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"]
Expand All @@ -16,4 +16,4 @@ proc-macro = true
[dependencies]
quote = "1"
syn = { version = "1", features = ["full", "extra-traits"] }
pyo3-derive-backend = { path = "../pyo3-derive-backend", version = "=0.10.1" }
pyo3-derive-backend = { path = "../pyo3-derive-backend", version = "=0.11.0" }
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
//! crate-type = ["cdylib"]
//!
//! [dependencies.pyo3]
//! version = "0.10.1"
//! version = "0.11.0"
//! features = ["extension-module"]
//! ```
//!
Expand Down Expand Up @@ -109,7 +109,7 @@
//!
//! ```toml
//! [dependencies]
//! pyo3 = "0.10.1"
//! pyo3 = "0.11.0"
//! ```
//!
//! Example program displaying the value of `sys.version`:
Expand Down