From ded83027fa8768529cf15163f3db745ee041c8ba Mon Sep 17 00:00:00 2001 From: kngwyu Date: Sat, 7 Mar 2020 18:13:15 +0900 Subject: [PATCH 1/7] Write migration guide for 0.9 --- guide/src/SUMMARY.md | 3 +- guide/src/migration.md | 183 ++++++++++++++++++++++++++++++++++++++ guide/src/rust_cpython.md | 2 +- src/lib.rs | 1 + 4 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 guide/src/migration.md diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index dc0c843dfbb..68fa8c158bb 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -12,4 +12,5 @@ - [Advanced Topics](advanced.md) - [Building and Distribution](building_and_distribution.md) - [PyPy support](pypy.md) -- [Appendix: PyO3 and rust-cpython](rust_cpython.md) +- [Appendix A: PyO3 and rust-cpython](rust_cpython.md) +- [Appendix B: Migration Guide](migration.md) diff --git a/guide/src/migration.md b/guide/src/migration.md new file mode 100644 index 00000000000..0f851788618 --- /dev/null +++ b/guide/src/migration.md @@ -0,0 +1,183 @@ +# Appendix B: Migration Guides for major version changes + +## from 0.8.* to 0.9 + +### `#[new]` interface +[`PyRawObject`](https://docs.rs/pyo3/0.8.5/pyo3/type_object/struct.PyRawObject.html) +is now removed and our syntax for constructor changed. + +Before: +```compile_fail +#[pyclass] +struct MyClass {} + +#[pymethods] +impl MyClass { + #[new] + fn new(obj: &PyRawObject) { + obj.init(MyClass { }) + } +} +``` + +After: +``` +# use pyo3::prelude::*; +#[pyclass] +struct MyClass {} + +#[pymethods] +impl MyClass { + #[new] + fn new() -> Self { + MyClass {} + } +} +``` + +Basically you can return `Self` or `Result` directly. +For more, see [the constructor section](https://pyo3.rs/master/class.html#constructor) of this guide. + +### PyCell +PyO3 0.9 introduces [`PyCell`](https://pyo3.rs/master/doc/pyo3/pycell/struct.PyCell.html), which is +a [`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html) like object wrapper +for dynamically ensuring +[Rust's rule of Reference](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references). + +For `#[pymethods]` or `#[pyfunction]`s, `PyCell` works without any change. +Just throw errors when there happens invalid borrowing. + +Here is an example. +``` +# use pyo3::prelude::*; +#[pyclass] +struct Names { + names: Vec +} + +#[pymethods] +impl Names { + #[new] + fn new() -> Self { + Names { names: vec![] } + } + fn merge(&mut self, other: &mut Names) { + self.names.append(&mut other.names) + } +} +# let gil = Python::acquire_gil(); +# let py = gil.python(); +# let names = PyCell::new(py, Names::new()).unwrap(); +# let borrow_mut_err = py.get_type::(); +# pyo3::py_run!(py, names borrow_mut_err, r" +# try: +# names.merge(names) +# assert False, 'Unreachable' +# except Exception as e: +# isinstance(e, borrow_mut_err) +# "); +``` +`Names` has `merge` method, which takes `&mut self` and `&mut Self`. +Given this `#[pyclass]`, calling `names.merge(names)` in Python raises `PyBorrowMutError` exception, +since it requires two mutable borrows of `names`, + +However, for `#[pyproto]` and some functions, you need to manually fix codes. + +#### Object creation +We could use the older `PyRef` and `PyRefMut` for object creation, but now they are just +reference wrappers for `PyCell`. +Use `PyCell::new` instead. + +Before: +```compile_fail +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass {} +let gil = Python::acquire_gil(); +let py = gil.python(); +let obj_ref = PyRef::new(py, MyClass {}).unwrap(); +``` + +After: +``` +# use pyo3::prelude::*; +# #[pyclass] +# struct MyClass {} +let gil = Python::acquire_gil(); +let py = gil.python(); +let obj = PyCell::new(py, MyClass {}).unwrap(); +let obj_ref = obj.borrow(); +``` + +#### Object extraction +Now for `T: PyClass`, `&T` and `&mut T` don't have `FromPyObject` implementation. +Instead, you can use `&PyCell`, `PyRef`, and `PyRefMut` for object extraction. + +Before: +```ignore +let obj: &PyAny = create_obj(); +let obj_ref: &MyClass = obj.extract().unwrap(); +let obj_ref_mut: &mut MyClass = obj.extract().unwrap(); +``` + +After: +``` +# use pyo3::prelude::*; +# use pyo3::types::{PyAny, IntoPyDict}; +# #[pyclass] struct MyClass {} +# #[pymethods] impl MyClass { #[new]fn new() -> Self { MyClass {} }} +# let gil = Python::acquire_gil(); +# let py = gil.python(); +# let typeobj = py.get_type::(); +# let d = [("c", typeobj)].into_py_dict(py); +# let create_obj = || py.eval("c()", None, Some(d)).unwrap(); +let obj: &PyAny = create_obj(); +let obj_cell: &PyCell = obj.extract().unwrap(); +{ + let obj_ref: PyRef = obj.extract().unwrap(); + // we need to drop obj_ref before taking RefMut +} +let obj_ref_mut: PyRefMut = obj.extract().unwrap(); +``` + + +#### `#[pyproto]` +Most of `#[pyproto]` arguments requires [`FromPyObject`] implementation. +So if your protocol methods take `&T` or `&mut T`(where `T: PyClass`), +please use `PyRef` or `PyRefMut` instead. + +Before: +```compile_fail +# use pyo3::prelude::*; +# use pyo3::class::PySequenceProtocol; +#[pyclass] +struct ByteSequence { + elements: Vec, +} +#[pyproto] +impl PySequenceProtocol for ByteSequence { + fn __concat__(&self, other: &Self) -> PyResult { + let mut elements = self.elements.clone(); + elements.extend_from_slice(&other.elements); + Ok(Self { elements }) + } +} +``` + +After: +``` +# use pyo3::prelude::*; +# use pyo3::class::PySequenceProtocol; +#[pyclass] +struct ByteSequence { + elements: Vec, +} +#[pyproto] +impl PySequenceProtocol for ByteSequence { + fn __concat__(&self, other: PyRef<'p, Self>) -> PyResult { + let mut elements = self.elements.clone(); + elements.extend_from_slice(&other.elements); + Ok(Self { elements }) + } +} +``` diff --git a/guide/src/rust_cpython.md b/guide/src/rust_cpython.md index ebb3fdaf604..d086e9e450c 100644 --- a/guide/src/rust_cpython.md +++ b/guide/src/rust_cpython.md @@ -1,4 +1,4 @@ -# Appendix: PyO3 and rust-cpython +# Appendix A: PyO3 and rust-cpython PyO3 began as fork of [rust-cpython](https://github.com/dgrunwald/rust-cpython) when rust-cpython wasn't maintained. Over the time PyO3 has become fundamentally different from rust-cpython. diff --git a/src/lib.rs b/src/lib.rs index 6f1f342e138..cbf06e95a37 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -328,4 +328,5 @@ pub mod doc_test { doctest!("../guide/src/parallelism.md", guide_parallelism_md); doctest!("../guide/src/pypy.md", guide_pypy_md); doctest!("../guide/src/rust_cpython.md", guide_rust_cpython_md); + doctest!("../guide/src/migration.md", guide_migration_md); } From 8eb0065e3802450b76dead5240fc0ca40150edec Mon Sep 17 00:00:00 2001 From: Yuji Kanagawa Date: Sun, 8 Mar 2020 21:43:06 +0900 Subject: [PATCH 2/7] Apply suggestions from code review Co-Authored-By: David Hewitt <1939362+davidhewitt@users.noreply.github.com> --- guide/src/migration.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/guide/src/migration.md b/guide/src/migration.md index 0f851788618..34ea84e7f8e 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -1,10 +1,10 @@ -# Appendix B: Migration Guides for major version changes - +# Appendix B: Migrating from older PyO3 versions +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.8.* to 0.9 ### `#[new]` interface [`PyRawObject`](https://docs.rs/pyo3/0.8.5/pyo3/type_object/struct.PyRawObject.html) -is now removed and our syntax for constructor changed. +is now removed and our syntax for constructors has changed. Before: ```compile_fail @@ -42,10 +42,11 @@ For more, see [the constructor section](https://pyo3.rs/master/class.html#constr PyO3 0.9 introduces [`PyCell`](https://pyo3.rs/master/doc/pyo3/pycell/struct.PyCell.html), which is a [`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html) like object wrapper for dynamically ensuring -[Rust's rule of Reference](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references). +[Rust's rules of references](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references). -For `#[pymethods]` or `#[pyfunction]`s, `PyCell` works without any change. -Just throw errors when there happens invalid borrowing. +For `#[pymethods]` or `#[pyfunction]`s, your existing code should continue to work without any change. +Python exceptions will automatically be raised when your functions are used in a way which breaks Rust's +rules of references. Here is an example. ``` @@ -78,8 +79,8 @@ impl Names { # "); ``` `Names` has `merge` method, which takes `&mut self` and `&mut Self`. -Given this `#[pyclass]`, calling `names.merge(names)` in Python raises `PyBorrowMutError` exception, -since it requires two mutable borrows of `names`, +Given this `#[pyclass]`, calling `names.merge(names)` in Python raises a `PyBorrowMutError` exception, +since it requires two mutable borrows of `names`. However, for `#[pyproto]` and some functions, you need to manually fix codes. @@ -110,8 +111,8 @@ let obj_ref = obj.borrow(); ``` #### Object extraction -Now for `T: PyClass`, `&T` and `&mut T` don't have `FromPyObject` implementation. -Instead, you can use `&PyCell`, `PyRef`, and `PyRefMut` for object extraction. +`T: PyClass`, `&T` and `&mut T` no longer have `FromPyObject` implementations. +Instead you should extract `&PyCell`, `PyRef`, and `PyRefMut` respectively. Before: ```ignore @@ -135,7 +136,7 @@ let obj: &PyAny = create_obj(); let obj_cell: &PyCell = obj.extract().unwrap(); { let obj_ref: PyRef = obj.extract().unwrap(); - // we need to drop obj_ref before taking RefMut + // we need to drop obj_ref before we can extract a PyRefMut due to Rust's rules of references } let obj_ref_mut: PyRefMut = obj.extract().unwrap(); ``` From 3a0cd8e4051ef6da829b071254aa9fcd7cd28f26 Mon Sep 17 00:00:00 2001 From: Yuji Kanagawa Date: Mon, 9 Mar 2020 13:58:52 +0900 Subject: [PATCH 3/7] Apply suggestions from georg's review to migration.md Co-Authored-By: Georg Brandl --- guide/src/migration.md | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/guide/src/migration.md b/guide/src/migration.md index 34ea84e7f8e..f64f5c1bd6f 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -42,7 +42,7 @@ For more, see [the constructor section](https://pyo3.rs/master/class.html#constr PyO3 0.9 introduces [`PyCell`](https://pyo3.rs/master/doc/pyo3/pycell/struct.PyCell.html), which is a [`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html) like object wrapper for dynamically ensuring -[Rust's rules of references](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references). +[The Rules of References](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references). For `#[pymethods]` or `#[pyfunction]`s, your existing code should continue to work without any change. Python exceptions will automatically be raised when your functions are used in a way which breaks Rust's @@ -58,13 +58,13 @@ struct Names { #[pymethods] impl Names { - #[new] - fn new() -> Self { - Names { names: vec![] } - } - fn merge(&mut self, other: &mut Names) { - self.names.append(&mut other.names) - } + #[new] + fn new() -> Self { + Names { names: vec![] } + } + fn merge(&mut self, other: &mut Names) { + self.names.append(&mut other.names) + } } # let gil = Python::acquire_gil(); # let py = gil.python(); @@ -78,16 +78,18 @@ impl Names { # isinstance(e, borrow_mut_err) # "); ``` -`Names` has `merge` method, which takes `&mut self` and `&mut Self`. +`Names` has a `merge` method, which takes `&mut self` and another argument of type `&mut Self`. Given this `#[pyclass]`, calling `names.merge(names)` in Python raises a `PyBorrowMutError` exception, since it requires two mutable borrows of `names`. -However, for `#[pyproto]` and some functions, you need to manually fix codes. +However, for `#[pyproto]` and some functions, you need to manually fix the code. #### Object creation -We could use the older `PyRef` and `PyRefMut` for object creation, but now they are just -reference wrappers for `PyCell`. -Use `PyCell::new` instead. +In 0.8 object creation was done with `PyRef::new` and `PyRefMut::new`. +In 0.9 these have both been removed. +To upgrade code, please use `PyCell::new` instead. +If a `PyRef` or `PyRefMut` is needed, just call `.borrow()` or `.borrow_mut()` +on the newly-created `PyCell`. Before: ```compile_fail @@ -111,8 +113,8 @@ let obj_ref = obj.borrow(); ``` #### Object extraction -`T: PyClass`, `&T` and `&mut T` no longer have `FromPyObject` implementations. -Instead you should extract `&PyCell`, `PyRef`, and `PyRefMut` respectively. +For `PyClass` types `T`, `&T` and `&mut T` no longer have `FromPyObject` implementations. +Instead you should extract `PyRef` or `PyRefMut`, respectively. You can also extract `&PyCell`. Before: ```ignore @@ -125,7 +127,7 @@ After: ``` # use pyo3::prelude::*; # use pyo3::types::{PyAny, IntoPyDict}; -# #[pyclass] struct MyClass {} +# #[pyclass] #[derive(Clone)] struct MyClass {} # #[pymethods] impl MyClass { #[new]fn new() -> Self { MyClass {} }} # let gil = Python::acquire_gil(); # let py = gil.python(); @@ -134,6 +136,7 @@ After: # let create_obj = || py.eval("c()", None, Some(d)).unwrap(); let obj: &PyAny = create_obj(); let obj_cell: &PyCell = obj.extract().unwrap(); +let obj_cloned: MyClass = obj.extract().unwrap(); // extracted via Clone { let obj_ref: PyRef = obj.extract().unwrap(); // we need to drop obj_ref before we can extract a PyRefMut due to Rust's rules of references @@ -143,8 +146,8 @@ let obj_ref_mut: PyRefMut = obj.extract().unwrap(); #### `#[pyproto]` -Most of `#[pyproto]` arguments requires [`FromPyObject`] implementation. -So if your protocol methods take `&T` or `&mut T`(where `T: PyClass`), +Most of the arguments to methods in `#[pyproto]` impls require a [`FromPyObject`] implementation. +So if your protocol methods take `&T` or `&mut T` (where `T: PyClass`), please use `PyRef` or `PyRefMut` instead. Before: From 084b3621be65874ec32ce56ea1d334b4f231c56d Mon Sep 17 00:00:00 2001 From: kngwyu Date: Mon, 9 Mar 2020 14:32:49 +0900 Subject: [PATCH 4/7] Relax version requirements for dependencies --- Cargo.toml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2fc035c6fc0..df373fe1fcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,20 +19,20 @@ travis-ci = { repository = "PyO3/pyo3", branch = "master" } appveyor = { repository = "fafhrd91/pyo3" } [dependencies] -indoc = "0.3.4" -inventory = "0.1.4" -libc = "0.2.62" -num-bigint = { version = ">= 0.2", optional = true } -num-complex = { version = ">= 0.2", optional = true } -num-traits = "0.2.8" +indoc = "^0.3.4" +inventory = "^0.1.4" +libc = "^0.2.62" +num-bigint = { version = "0.2", optional = true } +num-complex = { version = "0.2", optional = true } +num-traits = "^0.2.8" parking_lot = { version = "0.10", features = ["nightly"] } -paste = "0.1.6" +paste = "^0.1.6" pyo3cls = { path = "pyo3cls", version = "=0.9.0-alpha.1" } -unindent = "0.1.4" +unindent = "^0.1.4" [dev-dependencies] assert_approx_eq = "1.1.0" -trybuild = "1.0.14" +trybuild = "1.0.23" [build-dependencies] regex = "1" From a6765e3888319ac5c341ec5de2ab8a96f8e267ac Mon Sep 17 00:00:00 2001 From: kngwyu Date: Mon, 9 Mar 2020 16:02:42 +0900 Subject: [PATCH 5/7] Mention `let obj: T = obj.extract()?;` in migration.md --- guide/src/migration.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/guide/src/migration.md b/guide/src/migration.md index f64f5c1bd6f..d6fd1adc852 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -114,7 +114,9 @@ let obj_ref = obj.borrow(); #### Object extraction For `PyClass` types `T`, `&T` and `&mut T` no longer have `FromPyObject` implementations. -Instead you should extract `PyRef` or `PyRefMut`, respectively. You can also extract `&PyCell`. +Instead you should extract `PyRef` or `PyRefMut`, respectively. +If `T` implements `Clone`, you can extract `T` itself. +In addition, you can also extract `&PyCell`, though you rarely need it. Before: ```ignore @@ -136,7 +138,7 @@ After: # let create_obj = || py.eval("c()", None, Some(d)).unwrap(); let obj: &PyAny = create_obj(); let obj_cell: &PyCell = obj.extract().unwrap(); -let obj_cloned: MyClass = obj.extract().unwrap(); // extracted via Clone +let obj_cloned: MyClass = obj.extract().unwrap(); // extracted by cloning the object { let obj_ref: PyRef = obj.extract().unwrap(); // we need to drop obj_ref before we can extract a PyRefMut due to Rust's rules of references From 107c0cf1ba1b56d72f57565360609f3070f7a107 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Mon, 9 Mar 2020 18:31:43 +0900 Subject: [PATCH 6/7] Unify AsPyRef for Py to make rust-numpy work --- guide/src/class.md | 1 + pyo3-derive-backend/src/pyclass.rs | 4 +++- src/instance.rs | 11 +++++++---- src/pycell.rs | 16 ++++++++++++++-- src/type_object.rs | 3 +++ src/types/mod.rs | 9 +-------- 6 files changed, 29 insertions(+), 15 deletions(-) diff --git a/guide/src/class.md b/guide/src/class.md index b346aaebaff..013523d770e 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -38,6 +38,7 @@ unsafe impl pyo3::PyTypeInfo for MyClass { type BaseLayout = pyo3::pycell::PyCellBase; type Layout = PyCell; type Initializer = PyClassInitializer; + type AsRefTarget = PyCell; const NAME: &'static str = "MyClass"; const MODULE: Option<&'static str> = None; diff --git a/pyo3-derive-backend/src/pyclass.rs b/pyo3-derive-backend/src/pyclass.rs index daf1894601d..d22fce560ff 100644 --- a/pyo3-derive-backend/src/pyclass.rs +++ b/pyo3-derive-backend/src/pyclass.rs @@ -389,9 +389,10 @@ fn impl_class( unsafe impl pyo3::type_object::PyTypeInfo for #cls { type Type = #cls; type BaseType = #base; - type Layout = pyo3::pycell::PyCell; + type Layout = pyo3::PyCell; type BaseLayout = #base_layout; type Initializer = pyo3::pyclass_init::PyClassInitializer; + type AsRefTarget = pyo3::PyCell; const NAME: &'static str = #cls_name; const MODULE: Option<&'static str> = #module; @@ -416,6 +417,7 @@ fn impl_class( { type Target = pyo3::PyRef<'a, #cls>; } + impl<'a> pyo3::derive_utils::ExtractExt<'a> for &'a mut #cls { type Target = pyo3::PyRefMut<'a, #cls>; diff --git a/src/instance.rs b/src/instance.rs index 3c7db293019..1d5c1e8d5a0 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -7,7 +7,7 @@ use crate::type_object::{PyBorrowFlagLayout, PyDowncastImpl}; use crate::types::PyAny; use crate::{ ffi, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, PyCell, PyClass, PyClassInitializer, - PyRef, PyRefMut, Python, ToPyObject, + PyRef, PyRefMut, PyTypeInfo, Python, ToPyObject, }; use std::marker::PhantomData; use std::mem; @@ -158,9 +158,12 @@ pub trait AsPyRef: Sized { fn as_ref(&self, py: Python<'_>) -> &Self::Target; } -impl<'p, T: PyClass> AsPyRef for Py { - type Target = PyCell; - fn as_ref(&self, _py: Python) -> &PyCell { +impl AsPyRef for Py +where + T: PyTypeInfo, +{ + type Target = T::AsRefTarget; + fn as_ref(&self, _py: Python) -> &Self::Target { let any = self as *const Py as *const PyAny; unsafe { PyDowncastImpl::unchecked_downcast(&*any) } } diff --git a/src/pycell.rs b/src/pycell.rs index e94a22c171e..de4497f3dd2 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -440,7 +440,13 @@ pub struct PyRef<'p, T: PyClass> { inner: &'p PyCellInner, } -unsafe impl<'p, T: PyClass> crate::PyNativeType for PyRef<'p, T> {} +impl<'p, T: PyClass> PyRef<'p, T> { + /// Returns `Python` token. + /// This function is safe since PyRef has the same lifetime as a `GILGuard`. + pub fn py(&self) -> Python { + unsafe { Python::assume_gil_acquired() } + } +} impl<'p, T, U> AsRef for PyRef<'p, T> where @@ -551,7 +557,13 @@ pub struct PyRefMut<'p, T: PyClass> { inner: &'p PyCellInner, } -unsafe impl<'p, T: PyClass> crate::PyNativeType for PyRefMut<'p, T> {} +impl<'p, T: PyClass> PyRefMut<'p, T> { + /// Returns `Python` token. + /// This function is safe since PyRefMut has the same lifetime as a `GILGuard`. + pub fn py(&self) -> Python { + unsafe { Python::assume_gil_acquired() } + } +} impl<'p, T, U> AsRef for PyRefMut<'p, T> where diff --git a/src/type_object.rs b/src/type_object.rs index 14509ffcb2a..c554a03f70d 100644 --- a/src/type_object.rs +++ b/src/type_object.rs @@ -123,6 +123,9 @@ pub unsafe trait PyTypeInfo: Sized { /// Initializer for layout type Initializer: PyObjectInit; + /// Utility type to make AsPyRef work + type AsRefTarget: PyDowncastImpl; + /// PyTypeObject instance for this type. fn type_object() -> &'static ffi::PyTypeObject; diff --git a/src/types/mod.rs b/src/types/mod.rs index 79a1bcf7bfa..830ae59fbb1 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -128,6 +128,7 @@ macro_rules! pyobject_native_type_convert( type Layout = $layout; type BaseLayout = ffi::PyObject; type Initializer = $crate::pyclass_init::PyNativeTypeInitializer; + type AsRefTarget = Self; const NAME: &'static str = stringify!($name); const MODULE: Option<&'static str> = $module; @@ -153,14 +154,6 @@ macro_rules! pyobject_native_type_convert( } } - impl $crate::AsPyRef for $crate::Py<$name> { - type Target = $name; - fn as_ref(&self, _py: $crate::Python) -> &$name { - let any = self as *const $crate::Py<$name> as *const $crate::types::PyAny; - unsafe { $crate::type_object::PyDowncastImpl::unchecked_downcast(&*any) } - } - } - impl<$($type_param,)*> ::std::fmt::Debug for $name { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> From 433b812a682deaf297b2bce86205e71524e024f8 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Fri, 13 Mar 2020 18:40:25 +0900 Subject: [PATCH 7/7] Remove ^ from Cargo.toml + small improvements for migration.md --- Cargo.toml | 12 ++++++------ guide/src/migration.md | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index df373fe1fcd..e7c4e54acac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,16 +19,16 @@ travis-ci = { repository = "PyO3/pyo3", branch = "master" } appveyor = { repository = "fafhrd91/pyo3" } [dependencies] -indoc = "^0.3.4" -inventory = "^0.1.4" -libc = "^0.2.62" +indoc = "0.3.4" +inventory = "0.1.4" +libc = "0.2.62" num-bigint = { version = "0.2", optional = true } num-complex = { version = "0.2", optional = true } -num-traits = "^0.2.8" +num-traits = "0.2.8" parking_lot = { version = "0.10", features = ["nightly"] } -paste = "^0.1.6" +paste = "0.1.6" pyo3cls = { path = "pyo3cls", version = "=0.9.0-alpha.1" } -unindent = "^0.1.4" +unindent = "0.1.4" [dev-dependencies] assert_approx_eq = "1.1.0" diff --git a/guide/src/migration.md b/guide/src/migration.md index d6fd1adc852..5f7eeb1d054 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -40,9 +40,10 @@ For more, see [the constructor section](https://pyo3.rs/master/class.html#constr ### PyCell PyO3 0.9 introduces [`PyCell`](https://pyo3.rs/master/doc/pyo3/pycell/struct.PyCell.html), which is -a [`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html) like object wrapper -for dynamically ensuring -[The Rules of References](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references). +a [`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html)-like object wrapper +for ensuring Rust's rules regarding aliasing of references are upheld. +For more detail, see the +[Rust Book's section on Rust's rules of references](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references) For `#[pymethods]` or `#[pyfunction]`s, your existing code should continue to work without any change. Python exceptions will automatically be raised when your functions are used in a way which breaks Rust's