Skip to content

Commit

Permalink
Merge pull request #1245 from alex/abi3-merge-master
Browse files Browse the repository at this point in the history
Merge master into abi3 branch, resolving conflicts
  • Loading branch information
davidhewitt authored Oct 19, 2020
2 parents 4298435 + 90a825d commit f74b649
Show file tree
Hide file tree
Showing 47 changed files with 223 additions and 207 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
fail-fast: false # If one platform fails, allow the rest to keep testing.
matrix:
rust: [stable]
python-version: [3.5, 3.6, 3.7, 3.8, 3.9, pypy3]
python-version: [3.6, 3.7, 3.8, 3.9, pypy3]
platform: [
{ os: "macOS-latest", python-architecture: "x64", rust-target: "x86_64-apple-darwin" },
{ os: "ubuntu-latest", python-architecture: "x64", rust-target: "x86_64-unknown-linux-gnu" },
Expand Down
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@ 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]
### Packaging
- Drop support for Python 3.5 (as it is now end-of-life). [#1250](https://github.com/PyO3/pyo3/pull/1250)

### Added
- Add support for building for CPython limited API. This required a few minor changes to runtime behaviour of of pyo3 `#[pyclass]` types. See the migration guide for full details. [#1152](https://github.com/PyO3/pyo3/pull/1152)
- Add argument names to `TypeError` messages generated by pymethod wrappers. [#1212](https://github.com/PyO3/pyo3/pull/1212)

### Changed
- Change return type `PyType::name()` from `Cow<str>` to `PyResult<&str>`. [#1152](https://github.com/PyO3/pyo3/pull/1152)
- `#[pyclass(subclass)]` is now required for subclassing from Rust (was previously just required for subclassing from Python). [#1152](https://github.com/PyO3/pyo3/pull/1152)
- Change `PyIterator` to be consistent with other native types: it is now used as `&PyIterator` instead of `PyIterator<'a>`. [#1176](https://github.com/PyO3/pyo3/pull/1176)
- Change formatting of `PyDowncastError` messages to be closer to Python's builtin error messages. [#1212](https://github.com/PyO3/pyo3/pull/1212)

## [Unreleased]
### Removed
- Remove deprecated ffi definitions `PyUnicode_AsUnicodeCopy`, `PyUnicode_GetMax`, `_Py_CheckRecursionLimit`, `PyObject_AsCharBuffer`, `PyObject_AsReadBuffer`, `PyObject_CheckReadBuffer` and `PyObject_AsWriteBuffer`, which will be removed in Python 3.10. [#1217](https://github.com/PyO3/pyo3/pull/1217)
- Remove unused `python3` feature. [#1235](https://github.com/PyO3/pyo3/pull/1235)

## [0.12.3] - 2020-10-12
### Fixed
- Fix support for Rust versions 1.39 to 1.44, broken by an incorrect internal update to paste 1.0 which was done in PyO3 0.12.2. [#1234](https://github.com/PyO3/pyo3/pull/1234)

Expand Down Expand Up @@ -523,7 +533,8 @@ Yanked
### Added
- Initial release

[Unreleased]: https://github.com/pyo3/pyo3/compare/v0.12.2...HEAD
[Unreleased]: https://github.com/pyo3/pyo3/compare/v0.12.3...HEAD
[0.12.3]: https://github.com/pyo3/pyo3/compare/v0.12.2...v0.12.3
[0.12.2]: https://github.com/pyo3/pyo3/compare/v0.12.1...v0.12.2
[0.12.1]: https://github.com/pyo3/pyo3/compare/v0.12.0...v0.12.1
[0.12.0]: https://github.com/pyo3/pyo3/compare/v0.11.1...v0.12.0
Expand Down
7 changes: 2 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyo3"
version = "0.12.2"
version = "0.12.3"
description = "Bindings to Python interpreter"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
readme = "README.md"
Expand All @@ -23,7 +23,7 @@ parking_lot = "0.11.0"
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.12.2", optional = true }
pyo3cls = { path = "pyo3cls", version = "=0.12.3", optional = true }
unindent = { version = "0.1.4", optional = true }
hashbrown = { version = "0.9", optional = true }

Expand All @@ -42,9 +42,6 @@ abi3 = []
# Optimizes PyObject to Vec conversion and so on.
nightly = []

# this is no longer needed internally, but setuptools-rust assumes this feature
python3 = []

# Use this feature when building an extension module.
# It tells the linker to keep the python symbols unresolved,
# so that the module can also be used with statically linked python interpreters.
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ lint: fmt clippy

publish: test
cargo publish --manifest-path pyo3-derive-backend/Cargo.toml
sleep 10 # wait for crates.io to update
cargo publish --manifest-path pyo3cls/Cargo.toml
sleep 10 # wait for crates.io to update
cargo publish
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste

## Usage

PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.39.0.
PyO3 supports Python 3.6 and up. The minimum required Rust version is 1.39.0.

Building with PyPy is also possible (via cpyext) for Python 3.6, targeted PyPy version is 7.3+.
Please refer to the [pypy section in the guide](https://pyo3.rs/master/pypy.html).
Expand Down Expand Up @@ -48,7 +48,7 @@ name = "string_sum"
crate-type = ["cdylib"]

[dependencies.pyo3]
version = "0.12.2"
version = "0.12.3"
features = ["extension-module"]
```

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

```toml
[dependencies]
pyo3 = "0.12.2"
pyo3 = "0.12.3"
```

Example program displaying the value of `sys.version` and the current user name:
Expand Down Expand Up @@ -155,6 +155,7 @@ about this topic.
* [wasmer-python](https://github.com/wasmerio/wasmer-python) _Python library to run WebAssembly binaries_
* [mocpy](https://github.com/cds-astro/mocpy) _Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere_
* [tokenizers](https://github.com/huggingface/tokenizers/tree/master/bindings/python) _Python bindings to the Hugging Face tokenizers (NLP) written in Rust_
* [pyre](https://github.com/Project-Dream-Weaver/Pyre) _Fast Python HTTP server written in Rust_

## License

Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
}

if let Some(minor) = interpreter_config.version.minor {
for i in 5..(minor + 1) {
for i in 6..(minor + 1) {
println!("cargo:rustc-cfg=Py_3_{}", i);
flags += format!("CFG_Py_3_{},", i).as_ref();
}
Expand Down
2 changes: 1 addition & 1 deletion examples/rustapi_module/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def make_release_tree(self, base_dir, files):
def get_py_version_cfgs():
# For now each Cfg Py_3_X flag is interpreted as "at least 3.X"
version = sys.version_info[0:2]
py3_min = 5
py3_min = 6
out_cfg = []
for minor in range(py3_min, version[1] + 1):
out_cfg.append("--cfg=Py_3_%d" % minor)
Expand Down
17 changes: 7 additions & 10 deletions examples/rustapi_module/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn make_time<'p>(
)
}

#[cfg(Py_3_6)]
#[cfg(not(PyPy))]
#[pyfunction]
fn time_with_fold<'p>(
py: Python<'p>,
Expand Down Expand Up @@ -77,7 +77,7 @@ fn get_time_tuple<'p>(py: Python<'p>, dt: &PyTime) -> &'p PyTuple {
)
}

#[cfg(all(Py_3_6, not(PyPy)))]
#[cfg(not(PyPy))]
#[pyfunction]
fn get_time_tuple_fold<'p>(py: Python<'p>, dt: &PyTime) -> &'p PyTuple {
PyTuple::new(
Expand Down Expand Up @@ -156,7 +156,7 @@ fn get_datetime_tuple<'p>(py: Python<'p>, dt: &PyDateTime) -> &'p PyTuple {
)
}

#[cfg(all(Py_3_6, not(PyPy)))]
#[cfg(not(PyPy))]
#[pyfunction]
fn get_datetime_tuple_fold<'p>(py: Python<'p>, dt: &PyDateTime) -> &'p PyTuple {
PyTuple::new(
Expand Down Expand Up @@ -226,15 +226,12 @@ fn datetime(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(get_datetime_tuple, m)?)?;
m.add_function(wrap_pyfunction!(datetime_from_timestamp, m)?)?;

// Python 3.6+ functions
#[cfg(Py_3_6)]
// Functions not supported by PyPy
#[cfg(not(PyPy))]
{
m.add_function(wrap_pyfunction!(time_with_fold, m)?)?;
#[cfg(not(PyPy))]
{
m.add_function(wrap_pyfunction!(get_time_tuple_fold, m)?)?;
m.add_function(wrap_pyfunction!(get_datetime_tuple_fold, m)?)?;
}
m.add_function(wrap_pyfunction!(get_time_tuple_fold, m)?)?;
m.add_function(wrap_pyfunction!(get_datetime_tuple_fold, m)?)?;
}

m.add_function(wrap_pyfunction!(issue_219, m)?)?;
Expand Down
23 changes: 3 additions & 20 deletions examples/rustapi_module/tests/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,6 @@ def tzname(self, dt):
MAX_DATETIME = pdt.datetime(9999, 12, 31, 18, 59, 59)

PYPY = platform.python_implementation() == "PyPy"
HAS_FOLD = getattr(pdt.datetime, "fold", False) and not PYPY


xfail_date_bounds = pytest.mark.xfail(
sys.version_info < (3, 6),
reason="Date bounds were not checked in the C constructor prior to version 3.6",
)

xfail_macos_datetime_bounds = pytest.mark.xfail(
sys.version_info < (3, 6) and platform.system() == "Darwin",
reason="Unclearly failing. See https://github.com/PyO3/pyo3/pull/830 for more.",
)


# Tests
Expand All @@ -97,13 +85,11 @@ def test_date_accessors(d):
assert act == exp


@xfail_date_bounds
def test_invalid_date_fails():
with pytest.raises(ValueError):
rdt.make_date(2017, 2, 30)


@xfail_macos_datetime_bounds
@given(d=st.dates(MIN_DATETIME.date(), MAX_DATETIME.date()))
def test_date_from_timestamp(d):
if PYPY and d < pdt.date(1900, 1, 1):
Expand Down Expand Up @@ -137,7 +123,7 @@ def test_time(t):
assert act == exp


@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6")
@pytest.mark.xfail(PYPY, reason="Feature not available on PyPy")
@given(t=st.times())
def test_time_fold(t):
t_nofold = t.replace(fold=0)
Expand All @@ -150,7 +136,7 @@ def test_time_fold(t):
assert act == exp


@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6")
@pytest.mark.xfail(PYPY, reason="Feature not available on PyPy")
@pytest.mark.parametrize("fold", [False, True])
def test_time_fold(fold):
t = rdt.time_with_fold(0, 0, 0, 0, None, fold)
Expand All @@ -166,7 +152,6 @@ def test_invalid_time_fails_xfail(args):
rdt.make_time(*args)


@xfail_date_bounds
@pytest.mark.parametrize(
"args",
[
Expand Down Expand Up @@ -219,7 +204,7 @@ def test_datetime_tuple(dt):
assert act == exp


@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6")
@pytest.mark.xfail(PYPY, reason="Feature not available on PyPy")
@given(dt=st.datetimes())
def test_datetime_tuple_fold(dt):
dt_fold = dt.replace(fold=1)
Expand All @@ -232,7 +217,6 @@ def test_datetime_tuple_fold(dt):
assert act == exp


@xfail_date_bounds
def test_invalid_datetime_fails():
with pytest.raises(ValueError):
rdt.make_datetime(2011, 1, 42, 0, 0, 0, 0)
Expand All @@ -243,7 +227,6 @@ def test_datetime_typeerror():
rdt.make_datetime("2011", 1, 1, 0, 0, 0, 0)


@xfail_macos_datetime_bounds
@given(dt=st.datetimes(MIN_DATETIME, MAX_DATETIME))
@example(dt=pdt.datetime(1970, 1, 2, 0, 0))
def test_datetime_from_timestamp(dt):
Expand Down
6 changes: 3 additions & 3 deletions examples/word-count/tox.ini
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[tox]
envlist = py35,
py36,
envlist = py36,
py37,
py38,
py39,
pypy3
minversion = 3.4.0
minversion = 3.6.0
skip_missing_interpreters = true
isolated_build = true

Expand Down
2 changes: 1 addition & 1 deletion guide/src/conversions/tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ There are also a few special types related to the GIL and Rust-defined `#[pyclas
| `PyRef<T>` | A `#[pyclass]` borrowed immutably. |
| `PyRefMut<T>` | A `#[pyclass]` borrowed mutably. |

For more detail on accepting `#[pyclass]` values as function arguments, see [the section of this guide on Python Classes](class.md).
For more detail on accepting `#[pyclass]` values as function arguments, see [the section of this guide on Python Classes](../class.md).

#### Using Rust library types vs Python-native types

Expand Down
3 changes: 1 addition & 2 deletions guide/src/conversions/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ enum RustyEnum {
```

If the input is neither a string nor an integer, the error message will be:
`"Can't convert <INPUT> to Union[str, int]"`, where `<INPUT>` is replaced by the type name and
`repr()` of the input object.
`"'<INPUT_TYPE>' cannot be converted to 'Union[str, int]'"`.

#### `#[derive(FromPyObject)]` Container Attributes
- `pyo3(transparent)`
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.12.2"
version = "0.12.3"
description = "Code generation for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"]
Expand Down
6 changes: 1 addition & 5 deletions pyo3-derive-backend/src/from_pyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,7 @@ impl<'a> Enum<'a> {
quote!(
#(#var_extracts)*
let type_name = obj.get_type().name()?;
let from = obj
.repr()
.map(|s| format!("{} ({})", s.to_string_lossy(), type_name))
.unwrap_or_else(|_| type_name.to_string());
let err_msg = format!("Can't convert {} to {}", from, #error_names);
let err_msg = format!("'{}' object cannot be converted to '{}'", type_name, #error_names);
Err(::pyo3::exceptions::PyTypeError::new_err(err_msg))
)
}
Expand Down
2 changes: 1 addition & 1 deletion pyo3-derive-backend/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ fn impl_class(
quote! {
impl pyo3::freelist::PyClassWithFreeList for #cls {
#[inline]
fn get_free_list() -> &'static mut pyo3::freelist::FreeList<*mut pyo3::ffi::PyObject> {
fn get_free_list(_py: pyo3::Python) -> &mut pyo3::freelist::FreeList<*mut pyo3::ffi::PyObject> {
static mut FREELIST: *mut pyo3::freelist::FreeList<*mut pyo3::ffi::PyObject> = 0 as *mut _;
unsafe {
if FREELIST.is_null() {
Expand Down
10 changes: 7 additions & 3 deletions pyo3-derive-backend/src/pymethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,10 +475,14 @@ fn impl_arg_param(

let ty = arg.ty;
let name = arg.name;
let transform_error = quote! {
|e| pyo3::derive_utils::argument_extraction_error(_py, stringify!(#name), e)
};

if spec.is_args(&name) {
return quote! {
let #arg_name = <#ty as pyo3::FromPyObject>::extract(_args.as_ref())?;
let #arg_name = <#ty as pyo3::FromPyObject>::extract(_args.as_ref())
.map_err(#transform_error)?;
};
} else if spec.is_kwargs(&name) {
return quote! {
Expand Down Expand Up @@ -518,15 +522,15 @@ fn impl_arg_param(

quote! {
let #mut_ _tmp: #target_ty = match #arg_value {
Some(_obj) => _obj.extract()?,
Some(_obj) => _obj.extract().map_err(#transform_error)?,
None => #default,
};
let #arg_name = #borrow_tmp;
}
} else {
quote! {
let #arg_name = match #arg_value {
Some(_obj) => _obj.extract()?,
Some(_obj) => _obj.extract().map_err(#transform_error)?,
None => #default,
};
}
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.12.2"
version = "0.12.3"
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.12.2" }
pyo3-derive-backend = { path = "../pyo3-derive-backend", version = "=0.12.3" }
Loading

0 comments on commit f74b649

Please sign in to comment.