Skip to content

Commit b00c776

Browse files
authored
Merge branch 'master' into maci-run-clippy-on-all-the-codebase
2 parents fa911e3 + be22d9e commit b00c776

27 files changed

+248
-75
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ matrix:
2121
- name: Minimum nightly
2222
python: "3.7"
2323
# Keep this synced up with build.rs
24-
env: TRAVIS_RUST_VERSION=nightly-2019-06-21
24+
env: TRAVIS_RUST_VERSION=nightly-2019-07-19
2525
# Tested via anaconda PyPy (since travis's PyPy version is too old)
2626
- name: PyPy3.5 7.0
2727
python: "3.7"

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1414
* Use existing fields and methods before calling custom __getattr__. [#505](https://github.com/PyO3/pyo3/pull/512)
1515
* `PyBytes` can now be indexed just like `Vec<u8>`
1616

17+
## Removed
18+
19+
* `#[pyclass(subclass)]` is hidden a `unsound-subclass` feature because it's causing segmentation faults.
20+
1721
### Fixed
1822

1923
* More readable error message for generics in pyclass [#503](https://github.com/PyO3/pyo3/pull/503)
@@ -22,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
2226

2327
* Implementing the Using the `gc` parameter for `pyclass` (e.g. `#[pyclass(gc)]`) without implementing the `class::PyGCProtocol` trait is now a compile-time error. Failing to implement this trait could lead to segfaults. [#532](https://github.com/PyO3/pyo3/pull/532)
2428
* `PyByteArray::data` has been replaced with `PyDataArray::to_vec` because returning a `&[u8]` is unsound. (See [this comment](https://github.com/PyO3/pyo3/issues/373#issuecomment-512332696) for a great write-up for why that was unsound)
29+
* Replace `mashup` with `paste`.
2530

2631
## [0.7.0] - 2018-05-26
2732

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ libc = "0.2.54"
2323
spin = "0.5.0"
2424
num-traits = "0.2.6"
2525
pyo3cls = { path = "pyo3cls", version = "=0.7.0" }
26-
mashup = "0.1.9"
2726
num-complex = { version = "0.2.1", optional = true }
2827
inventory = "0.1.3"
2928
indoc = "0.3.3"
3029
unindent = "0.1.3"
30+
paste = "0.1.5"
3131

3232
[dev-dependencies]
3333
assert_approx_eq = "1.1.0"
@@ -55,6 +55,9 @@ extension-module = []
5555
# are welcome.
5656
# abi3 = []
5757

58+
# Activate subclassing support
59+
unsound-subclass = ["pyo3cls/unsound-subclass"]
60+
5861
[workspace]
5962
members = [
6063
"pyo3cls",

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste
1616

1717
## Usage
1818

19-
PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.34.0-nightly 2019-02-06.
19+
PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.37.0-nightly 2019-07-19.
2020

2121
PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0.
2222
Please refer to the guide for installation instruction against PyPy.
@@ -129,6 +129,7 @@ fn main() -> PyResult<()> {
129129
* Contains an example of building wheels on Azure Pipelines
130130
* [fastuuid](https://github.com/thedrow/fastuuid/) _Python bindings to Rust's UUID library_
131131
* [python-ext-wasm](https://github.com/wasmerio/python-ext-wasm) _Python library to run WebAssembly binaries_
132+
* [dict-derive](https://github.com/gperinazzo/dict-derive) _Derive FromPyObject to automatically transform Python dicts into Rust structs_
132133

133134
## License
134135

build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use version_check::{Channel, Date, Version};
1616
/// Specifies the minimum nightly version needed to compile pyo3.
1717
/// Keep this synced up with the travis ci config,
1818
/// But note that this is the rustc version which can be lower than the nightly version
19-
const MIN_DATE: &'static str = "2019-06-21";
19+
const MIN_DATE: &'static str = "2019-07-18";
2020
const MIN_VERSION: &'static str = "1.37.0-nightly";
2121

2222
/// Information returned from python interpreter

ci/travis/setup.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ if [ ! -f "$HOME/.cargo/bin/kcov" ]; then
5151
make
5252
install src/kcov $HOME/.cargo/bin/kcov
5353
cd $TRAVIS_BUILD_DIR
54-
fi
54+
fi

codecov.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
comment: off
2+

examples/rustapi_module/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ edition = "2018"
99

1010
[dependencies.pyo3]
1111
path = "../../"
12-
features = ["extension-module"]
12+
features = ["extension-module", "unsound-subclass"]
1313

1414
[lib]
1515
name = "rustapi_module"

guide/src/class.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ so that they can benefit from a freelist. `XXX` is a number of items for the fre
102102
If a custom class contains references to other Python objects that can be collected, the `PyGCProtocol` trait has to be implemented.
103103
* `weakref` - Adds support for Python weak references.
104104
* `extends=BaseType` - Use a custom base class. The base `BaseType` must implement `PyTypeInfo`.
105-
* `subclass` - Allows Python classes to inherit from this class.
106105
* `dict` - Adds `__dict__` support, so that the instances of this type have a dictionary containing arbitrary instance variables.
107106
* `module="XXX"` - Set the name of the module the class will be shown as defined in. If not given, the class
108107
will be a virtual member of the `builtins` module.
108+
* `subclass` - Allows Python classes to inherit from this class. This feature is hidden behind a `unsound-subclass` feature because it is currently causing segmentation faults
109109

110110
## Constructor
111111

guide/src/exception.md

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,23 +128,39 @@ more complex arguments are required, the
128128
trait can be implemented. In that case, actual exception argument creation is delayed
129129
until a `Python` object is available.
130130

131-
```rust,ignore
132-
use std::net::TcpListener;
133-
use pyo3::{PyErr, PyResult, exc};
131+
```rust
132+
# use pyo3::{exceptions, PyErr, PyResult};
133+
# use std::error::Error;
134+
# use std::fmt;
135+
#
136+
# #[derive(Debug)]
137+
# struct CustomIOError;
138+
#
139+
# impl Error for CustomIOError {}
140+
#
141+
# impl fmt::Display for CustomIOError {
142+
# fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
143+
# write!(f, "Oh no!")
144+
# }
145+
# }
146+
#
147+
# fn bind(_addr: &str) -> Result<(), CustomIOError> {
148+
# Err(CustomIOError)
149+
# }
134150

135-
impl std::convert::From<std::io::Error> for PyErr {
136-
fn from(err: std::io::Error) -> PyErr {
137-
exceptions::OSError.into()
151+
impl std::convert::From<CustomIOError> for PyErr {
152+
fn from(err: CustomIOError) -> PyErr {
153+
exceptions::OSError::py_err(err.to_string())
138154
}
139155
}
140156

141157
fn connect(s: String) -> PyResult<bool> {
142-
TcpListener::bind("127.0.0.1:80")?;
158+
bind("127.0.0.1:80")?;
143159
Ok(true)
144160
}
145161
```
146162

147-
The code snippet above will raise an `OSError` in Python if `TcpListener::bind()` returns an error.
163+
The code snippet above will raise an `OSError` in Python if `bind()` returns a `CustomIOError`.
148164

149165
The `std::convert::From<T>` trait is implemented for most of the Rust standard library's error
150166
types so the `try!` macro or the `?` operator can be used.

guide/src/function.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ In order to make the function signature available to Python to be retrieved via
5353
formatted like in the example below. Please note that the newline after the
5454
`--` is mandatory. The `/` signifies the end of positional-only arguments. This
5555
is not a feature of this library in particular, but the general format used by
56-
CPython for annotating signatures of built-in functions. Function signatures for
57-
built-ins are new in Python 3 — in Python 2, they are simply considered to be a
58-
part of the docstring.
56+
CPython for annotating signatures of built-in functions.
5957

6058
```rust
6159
use pyo3::prelude::*;

guide/src/get_started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste
1010

1111
## Usage
1212

13-
PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.34.0-nightly 2019-02-06.
13+
PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.37.0-nightly 2019-07-19.
1414

1515
PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0.
1616
Please refer to the guide for installation instruction against PyPy.

pyo3-derive-backend/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ edition = "2018"
1414
quote = "0.6.12"
1515
proc-macro2 = "0.4.30"
1616
syn = { version = "0.15.34", features = ["full", "extra-traits"] }
17+
18+
[features]
19+
unsound-subclass = []

pyo3-derive-backend/src/pyclass.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ impl PyClassArgs {
132132
parse_quote! {pyo3::type_object::PY_TYPE_FLAG_WEAKREF}
133133
}
134134
"subclass" => {
135+
if cfg!(not(feature = "unsound-subclass")) {
136+
return Err(syn::Error::new_spanned(
137+
exp.path.clone(),
138+
"You need to activate the `unsound-subclass` feature if you want to use subclassing",
139+
));
140+
}
135141
parse_quote! {pyo3::type_object::PY_TYPE_FLAG_BASETYPE}
136142
}
137143
"dict" => {

pyo3cls/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ quote= "0.6.12"
1818
proc-macro2 = "0.4.30"
1919
syn = { version = "0.15.34", features = ["full", "extra-traits"] }
2020
pyo3-derive-backend = { path = "../pyo3-derive-backend", version = "=0.7.0" }
21+
22+
[features]
23+
unsound-subclass = ["pyo3-derive-backend/unsound-subclass"]

src/class/number.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,111 +1271,125 @@ where
12711271
}
12721272
}
12731273

1274-
trait PyNumberRAddProtocolImpl {
1274+
#[doc(hidden)]
1275+
pub trait PyNumberRAddProtocolImpl {
12751276
fn __radd__() -> Option<PyMethodDef> {
12761277
None
12771278
}
12781279
}
12791280

12801281
impl<'p, T> PyNumberRAddProtocolImpl for T where T: PyNumberProtocol<'p> {}
12811282

1282-
trait PyNumberRSubProtocolImpl {
1283+
#[doc(hidden)]
1284+
pub trait PyNumberRSubProtocolImpl {
12831285
fn __rsub__() -> Option<PyMethodDef> {
12841286
None
12851287
}
12861288
}
12871289

12881290
impl<'p, T> PyNumberRSubProtocolImpl for T where T: PyNumberProtocol<'p> {}
12891291

1290-
trait PyNumberRMulProtocolImpl {
1292+
#[doc(hidden)]
1293+
pub trait PyNumberRMulProtocolImpl {
12911294
fn __rmul__() -> Option<PyMethodDef> {
12921295
None
12931296
}
12941297
}
12951298

12961299
impl<'p, T> PyNumberRMulProtocolImpl for T where T: PyNumberProtocol<'p> {}
12971300

1298-
trait PyNumberRMatmulProtocolImpl {
1301+
#[doc(hidden)]
1302+
pub trait PyNumberRMatmulProtocolImpl {
12991303
fn __rmatmul__() -> Option<PyMethodDef> {
13001304
None
13011305
}
13021306
}
13031307

13041308
impl<'p, T> PyNumberRMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {}
13051309

1306-
trait PyNumberRTruedivProtocolImpl {
1310+
#[doc(hidden)]
1311+
pub trait PyNumberRTruedivProtocolImpl {
13071312
fn __rtruediv__() -> Option<PyMethodDef> {
13081313
None
13091314
}
13101315
}
13111316

13121317
impl<'p, T> PyNumberRTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {}
13131318

1314-
trait PyNumberRFloordivProtocolImpl {
1319+
#[doc(hidden)]
1320+
pub trait PyNumberRFloordivProtocolImpl {
13151321
fn __rfloordiv__() -> Option<PyMethodDef> {
13161322
None
13171323
}
13181324
}
13191325

13201326
impl<'p, T> PyNumberRFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {}
13211327

1322-
trait PyNumberRModProtocolImpl {
1328+
#[doc(hidden)]
1329+
pub trait PyNumberRModProtocolImpl {
13231330
fn __rmod__() -> Option<PyMethodDef> {
13241331
None
13251332
}
13261333
}
13271334

13281335
impl<'p, T> PyNumberRModProtocolImpl for T where T: PyNumberProtocol<'p> {}
13291336

1330-
trait PyNumberRDivmodProtocolImpl {
1337+
#[doc(hidden)]
1338+
pub trait PyNumberRDivmodProtocolImpl {
13311339
fn __rdivmod__() -> Option<PyMethodDef> {
13321340
None
13331341
}
13341342
}
13351343

13361344
impl<'p, T> PyNumberRDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {}
13371345

1338-
trait PyNumberRPowProtocolImpl {
1346+
#[doc(hidden)]
1347+
pub trait PyNumberRPowProtocolImpl {
13391348
fn __rpow__() -> Option<PyMethodDef> {
13401349
None
13411350
}
13421351
}
13431352

13441353
impl<'p, T> PyNumberRPowProtocolImpl for T where T: PyNumberProtocol<'p> {}
13451354

1346-
trait PyNumberRLShiftProtocolImpl {
1355+
#[doc(hidden)]
1356+
pub trait PyNumberRLShiftProtocolImpl {
13471357
fn __rlshift__() -> Option<PyMethodDef> {
13481358
None
13491359
}
13501360
}
13511361

13521362
impl<'p, T> PyNumberRLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
13531363

1354-
trait PyNumberRRShiftProtocolImpl {
1364+
#[doc(hidden)]
1365+
pub trait PyNumberRRShiftProtocolImpl {
13551366
fn __rrshift__() -> Option<PyMethodDef> {
13561367
None
13571368
}
13581369
}
13591370

13601371
impl<'p, T> PyNumberRRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {}
13611372

1362-
trait PyNumberRAndProtocolImpl {
1373+
#[doc(hidden)]
1374+
pub trait PyNumberRAndProtocolImpl {
13631375
fn __rand__() -> Option<PyMethodDef> {
13641376
None
13651377
}
13661378
}
13671379

13681380
impl<'p, T> PyNumberRAndProtocolImpl for T where T: PyNumberProtocol<'p> {}
13691381

1370-
trait PyNumberRXorProtocolImpl {
1382+
#[doc(hidden)]
1383+
pub trait PyNumberRXorProtocolImpl {
13711384
fn __rxor__() -> Option<PyMethodDef> {
13721385
None
13731386
}
13741387
}
13751388

13761389
impl<'p, T> PyNumberRXorProtocolImpl for T where T: PyNumberProtocol<'p> {}
13771390

1378-
trait PyNumberROrProtocolImpl {
1391+
#[doc(hidden)]
1392+
pub trait PyNumberROrProtocolImpl {
13791393
fn __ror__() -> Option<PyMethodDef> {
13801394
None
13811395
}

src/err.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::IntoPyPointer;
1111
use crate::Python;
1212
use crate::{IntoPyObject, ToBorrowedObject, ToPyObject};
1313
use libc::c_int;
14-
use std::error::Error;
1514
use std::ffi::CString;
1615
use std::io;
1716
use std::os::raw::c_char;
@@ -412,7 +411,7 @@ macro_rules! impl_to_pyerr {
412411
($err: ty, $pyexc: ty) => {
413412
impl PyErrArguments for $err {
414413
fn arguments(&self, py: Python) -> PyObject {
415-
self.description().to_object(py)
414+
self.to_string().to_object(py)
416415
}
417416
}
418417

@@ -459,10 +458,9 @@ impl std::convert::From<io::Error> for PyErr {
459458
}
460459
}
461460

462-
/// Extract `errno` and `errdesc` from from `io::Error`
463461
impl PyErrArguments for io::Error {
464462
fn arguments(&self, py: Python) -> PyObject {
465-
(self.raw_os_error().unwrap_or(0), self.description()).to_object(py)
463+
self.to_string().to_object(py)
466464
}
467465
}
468466

@@ -474,7 +472,7 @@ impl<W: 'static + Send + std::fmt::Debug> std::convert::From<std::io::IntoInnerE
474472

475473
impl<W: Send + std::fmt::Debug> PyErrArguments for std::io::IntoInnerError<W> {
476474
fn arguments(&self, py: Python) -> PyObject {
477-
self.description().to_object(py)
475+
self.to_string().to_object(py)
478476
}
479477
}
480478

0 commit comments

Comments
 (0)