Skip to content

Commit

Permalink
Merge pull request #1839 from PyO3/release-0.14.4
Browse files Browse the repository at this point in the history
release: 0.14.4
  • Loading branch information
davidhewitt authored Aug 29, 2021
2 parents 13eb897 + d544c07 commit 72e8356
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 68 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ jobs:
cargo update -p indexmap --precise 1.6.2
cargo update -p hashbrown:0.11.2 --precise 0.9.1
cargo update -p bitflags --precise 1.2.1
cargo update -p parking_lot --precise 0.11.1
cargo update -p parking_lot_core --precise 0.8.3
- name: Build docs
run: cargo doc --no-deps --no-default-features --features "${{ steps.settings.outputs.all_additive_features }}"
Expand Down
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ PyO3 versions, please see the [migration guide](https://pyo3.rs/latest/migration
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).

## [0.14.4] - 2021-08-29

### Changed

- Mark `PyString::data` as `unsafe` and disable it and some supporting PyUnicode FFI APIs (which depend on a C bitfield) on big-endian targets. [#1834](https://github.com/PyO3/pyo3/pull/1834)

## [0.14.3] - 2021-08-22

### Added
Expand Down Expand Up @@ -896,7 +902,8 @@ Yanked

- Initial release

[unreleased]: https://github.com/pyo3/pyo3/compare/v0.14.3...HEAD
[unreleased]: https://github.com/pyo3/pyo3/compare/v0.14.4...HEAD
[0.14.4]: https://github.com/pyo3/pyo3/compare/v0.14.3...v0.14.4
[0.14.3]: https://github.com/pyo3/pyo3/compare/v0.14.2...v0.14.3
[0.14.2]: https://github.com/pyo3/pyo3/compare/v0.14.1...v0.14.2
[0.14.1]: https://github.com/pyo3/pyo3/compare/v0.14.0...v0.14.1
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyo3"
version = "0.14.3"
version = "0.14.4"
description = "Bindings to Python interpreter"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
readme = "README.md"
Expand All @@ -24,7 +24,7 @@ num-bigint = { version = "0.4", optional = true }
num-complex = { version = ">= 0.2, < 0.5", optional = true }
# must stay at 0.1.x for Rust 1.41 compatibility
paste = { version = "0.1.18", optional = true }
pyo3-macros = { path = "pyo3-macros", version = "=0.14.3", optional = true }
pyo3-macros = { path = "pyo3-macros", version = "=0.14.4", optional = true }
unindent = { version = "0.1.4", optional = true }
hashbrown = { version = ">= 0.9, < 0.12", optional = true }
indexmap = { version = ">= 1.6, < 1.8", optional = true }
Expand All @@ -42,7 +42,7 @@ pyo3 = { path = ".", default-features = false, features = ["macros", "auto-initi
serde_json = "1.0.61"

[build-dependencies]
pyo3-build-config = { path = "pyo3-build-config", version = "0.14.3" }
pyo3-build-config = { path = "pyo3-build-config", version = "0.14.4" }

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

[dependencies.pyo3]
version = "0.14.3"
version = "0.14.4"
features = ["extension-module"]
```

Expand Down Expand Up @@ -108,7 +108,7 @@ Start a new project with `cargo new` and add `pyo3` to the `Cargo.toml` like th

```toml
[dependencies.pyo3]
version = "0.14.3"
version = "0.14.4"
features = ["auto-initialize"]
```

Expand Down
2 changes: 1 addition & 1 deletion pyo3-build-config/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyo3-build-config"
version = "0.14.3"
version = "0.14.4"
description = "Build configuration for the PyO3 ecosystem"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"]
Expand Down
4 changes: 2 additions & 2 deletions pyo3-macros-backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyo3-macros-backend"
version = "0.14.3"
version = "0.14.4"
description = "Code generation for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"]
Expand All @@ -16,7 +16,7 @@ edition = "2018"
[dependencies]
quote = { version = "1", default-features = false }
proc-macro2 = { version = "1", default-features = false }
pyo3-build-config = { path = "../pyo3-build-config", version = "0.14.3" }
pyo3-build-config = { path = "../pyo3-build-config", version = "0.14.4" }

[dependencies.syn]
version = "1"
Expand Down
4 changes: 2 additions & 2 deletions pyo3-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyo3-macros"
version = "0.14.3"
version = "0.14.4"
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-macros-backend = { path = "../pyo3-macros-backend", version = "=0.14.3" }
pyo3-macros-backend = { path = "../pyo3-macros-backend", version = "=0.14.4" }
68 changes: 44 additions & 24 deletions src/ffi/cpython/unicodeobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,34 @@ pub struct PyASCIIObject {
pub wstr: *mut wchar_t,
}

/// Interacting with the bitfield is not actually well-defined, so we mark these APIs unsafe.
///
/// In addition, they are disabled on big-endian architectures to restrict this to most "common"
/// platforms, which are at least tested on CI and appear to be sound.
#[cfg(not(target_endian = "big"))]
impl PyASCIIObject {
#[inline]
pub fn interned(&self) -> c_uint {
pub unsafe fn interned(&self) -> c_uint {
self.state & 3
}

#[inline]
pub fn kind(&self) -> c_uint {
pub unsafe fn kind(&self) -> c_uint {
(self.state >> 2) & 7
}

#[inline]
pub fn compact(&self) -> c_uint {
pub unsafe fn compact(&self) -> c_uint {
(self.state >> 5) & 1
}

#[inline]
pub fn ascii(&self) -> c_uint {
pub unsafe fn ascii(&self) -> c_uint {
(self.state >> 6) & 1
}

#[inline]
pub fn ready(&self) -> c_uint {
pub unsafe fn ready(&self) -> c_uint {
(self.state >> 7) & 1
}
}
Expand Down Expand Up @@ -114,6 +119,7 @@ pub const SSTATE_INTERNED_MORTAL: c_uint = 1;
pub const SSTATE_INTERNED_IMMORTAL: c_uint = 2;

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_IS_ASCII(op: *mut PyObject) -> c_uint {
debug_assert!(PyUnicode_Check(op) != 0);
debug_assert!(PyUnicode_IS_READY(op) != 0);
Expand All @@ -122,11 +128,13 @@ pub unsafe fn PyUnicode_IS_ASCII(op: *mut PyObject) -> c_uint {
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_IS_COMPACT(op: *mut PyObject) -> c_uint {
(*(op as *mut PyASCIIObject)).compact()
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_IS_COMPACT_ASCII(op: *mut PyObject) -> c_uint {
if (*(op as *mut PyASCIIObject)).ascii() != 0 && PyUnicode_IS_COMPACT(op) != 0 {
1
Expand All @@ -144,21 +152,25 @@ pub const PyUnicode_2BYTE_KIND: c_uint = 2;
pub const PyUnicode_4BYTE_KIND: c_uint = 4;

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_1BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS1 {
PyUnicode_DATA(op) as *mut Py_UCS1
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_2BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS2 {
PyUnicode_DATA(op) as *mut Py_UCS2
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_4BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS4 {
PyUnicode_DATA(op) as *mut Py_UCS4
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_KIND(op: *mut PyObject) -> c_uint {
debug_assert!(PyUnicode_Check(op) != 0);
debug_assert!(PyUnicode_IS_READY(op) != 0);
Expand All @@ -167,6 +179,7 @@ pub unsafe fn PyUnicode_KIND(op: *mut PyObject) -> c_uint {
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn _PyUnicode_COMPACT_DATA(op: *mut PyObject) -> *mut c_void {
if PyUnicode_IS_ASCII(op) != 0 {
(op as *mut PyASCIIObject).offset(1) as *mut c_void
Expand All @@ -176,13 +189,15 @@ pub unsafe fn _PyUnicode_COMPACT_DATA(op: *mut PyObject) -> *mut c_void {
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn _PyUnicode_NONCOMPACT_DATA(op: *mut PyObject) -> *mut c_void {
debug_assert!(!(*(op as *mut PyUnicodeObject)).data.any.is_null());

(*(op as *mut PyUnicodeObject)).data.any
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void {
debug_assert!(PyUnicode_Check(op) != 0);

Expand All @@ -206,13 +221,15 @@ pub unsafe fn PyUnicode_GET_LENGTH(op: *mut PyObject) -> Py_ssize_t {
}

#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_IS_READY(op: *mut PyObject) -> c_uint {
(*(op as *mut PyASCIIObject)).ready()
}

#[cfg(not(Py_3_12))]
#[cfg_attr(Py_3_10, deprecated(note = "Python 3.10"))]
#[inline]
#[cfg(not(target_endian = "big"))]
pub unsafe fn PyUnicode_READY(op: *mut PyObject) -> c_int {
debug_assert!(PyUnicode_Check(op) != 0);

Expand Down Expand Up @@ -481,6 +498,7 @@ extern "C" {
// skipped _PyUnicode_ScanIdentifier

#[cfg(test)]
#[cfg(not(target_endian = "big"))]
mod tests {
use super::*;
use crate::types::PyString;
Expand All @@ -498,30 +516,32 @@ mod tests {
wstr: std::ptr::null_mut() as *mut wchar_t,
};

assert_eq!(o.interned(), 0);
assert_eq!(o.kind(), 0);
assert_eq!(o.compact(), 0);
assert_eq!(o.ascii(), 0);
assert_eq!(o.ready(), 0);
unsafe {
assert_eq!(o.interned(), 0);
assert_eq!(o.kind(), 0);
assert_eq!(o.compact(), 0);
assert_eq!(o.ascii(), 0);
assert_eq!(o.ready(), 0);

for i in 0..4 {
o.state = i;
assert_eq!(o.interned(), i);
}
for i in 0..4 {
o.state = i;
assert_eq!(o.interned(), i);
}

for i in 0..8 {
o.state = i << 2;
assert_eq!(o.kind(), i);
}
for i in 0..8 {
o.state = i << 2;
assert_eq!(o.kind(), i);
}

o.state = 1 << 5;
assert_eq!(o.compact(), 1);
o.state = 1 << 5;
assert_eq!(o.compact(), 1);

o.state = 1 << 6;
assert_eq!(o.ascii(), 1);
o.state = 1 << 6;
assert_eq!(o.ascii(), 1);

o.state = 1 << 7;
assert_eq!(o.ready(), 1);
o.state = 1 << 7;
assert_eq!(o.ready(), 1);
}
}

#[test]
Expand Down
Loading

0 comments on commit 72e8356

Please sign in to comment.