Skip to content

Commit a8dd453

Browse files
ijldavidhewitt
authored andcommitted
PEP 623: wstr, wstr_length, state changes
https://peps.python.org/pep-0623/ Following members are removed from the Unicode structures: wstr wstr_length state.compact state.ready Note state.compact is still present as of v3.12.0a7. state.interned has changed width from 2 to 1 bits.
1 parent 9ebdcb7 commit a8dd453

File tree

2 files changed

+62
-12
lines changed

2 files changed

+62
-12
lines changed

pyo3-ffi/src/cpython/unicodeobject.rs

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#[cfg(not(PyPy))]
22
use crate::Py_hash_t;
33
use crate::{PyObject, Py_UCS1, Py_UCS2, Py_UCS4, Py_UNICODE, Py_ssize_t};
4+
#[cfg(not(Py_3_12))]
45
use libc::wchar_t;
56
use std::os::raw::{c_char, c_int, c_uint, c_void};
67

@@ -116,6 +117,28 @@ where
116117
}
117118
}
118119

120+
const STATE_INTERNED_INDEX: usize = 0;
121+
#[cfg(not(Py_3_12))]
122+
const STATE_INTERNED_WIDTH: u8 = 2;
123+
#[cfg(Py_3_12)]
124+
const STATE_INTERNED_WIDTH: u8 = 1;
125+
126+
const STATE_KIND_INDEX: usize = STATE_INTERNED_WIDTH as usize;
127+
const STATE_KIND_WIDTH: u8 = 3;
128+
129+
const STATE_COMPACT_INDEX: usize = (STATE_INTERNED_WIDTH + STATE_KIND_WIDTH) as usize;
130+
const STATE_COMPACT_WIDTH: u8 = 1;
131+
132+
const STATE_ASCII_INDEX: usize =
133+
(STATE_INTERNED_WIDTH + STATE_KIND_WIDTH + STATE_COMPACT_WIDTH) as usize;
134+
const STATE_ASCII_WIDTH: u8 = 1;
135+
136+
#[cfg(not(Py_3_12))]
137+
const STATE_READY_INDEX: usize =
138+
(STATE_INTERNED_WIDTH + STATE_KIND_WIDTH + STATE_COMPACT_WIDTH + STATE_ASCII_WIDTH) as usize;
139+
#[cfg(not(Py_3_12))]
140+
const STATE_READY_WIDTH: u8 = 1;
141+
119142
// generated by bindgen v0.63.0 (with small adaptations)
120143
// The same code is generated for Python 3.7, 3.8, 3.9, 3.10, and 3.11, but the "ready" field
121144
// has been removed from Python 3.12.
@@ -137,57 +160,67 @@ struct PyASCIIObjectState {
137160
impl PyASCIIObjectState {
138161
#[inline]
139162
unsafe fn interned(&self) -> c_uint {
140-
std::mem::transmute(self._bitfield.get(0usize, 2u8) as u32)
163+
std::mem::transmute(
164+
self._bitfield
165+
.get(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH) as u32,
166+
)
141167
}
142168

143169
#[inline]
144170
unsafe fn set_interned(&mut self, val: c_uint) {
145171
let val: u32 = std::mem::transmute(val);
146-
self._bitfield.set(0usize, 2u8, val as u64)
172+
self._bitfield
173+
.set(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH, val as u64)
147174
}
148175

149176
#[inline]
150177
unsafe fn kind(&self) -> c_uint {
151-
std::mem::transmute(self._bitfield.get(2usize, 3u8) as u32)
178+
std::mem::transmute(self._bitfield.get(STATE_KIND_INDEX, STATE_KIND_WIDTH) as u32)
152179
}
153180

154181
#[inline]
155182
unsafe fn set_kind(&mut self, val: c_uint) {
156183
let val: u32 = std::mem::transmute(val);
157-
self._bitfield.set(2usize, 3u8, val as u64)
184+
self._bitfield
185+
.set(STATE_KIND_INDEX, STATE_KIND_WIDTH, val as u64)
158186
}
159187

160188
#[inline]
161189
unsafe fn compact(&self) -> c_uint {
162-
std::mem::transmute(self._bitfield.get(5usize, 1u8) as u32)
190+
std::mem::transmute(self._bitfield.get(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH) as u32)
163191
}
164192

165193
#[inline]
166194
unsafe fn set_compact(&mut self, val: c_uint) {
167195
let val: u32 = std::mem::transmute(val);
168-
self._bitfield.set(5usize, 1u8, val as u64)
196+
self._bitfield
197+
.set(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH, val as u64)
169198
}
170199

171200
#[inline]
172201
unsafe fn ascii(&self) -> c_uint {
173-
std::mem::transmute(self._bitfield.get(6usize, 1u8) as u32)
202+
std::mem::transmute(self._bitfield.get(STATE_ASCII_INDEX, STATE_ASCII_WIDTH) as u32)
174203
}
175204

176205
#[inline]
177206
unsafe fn set_ascii(&mut self, val: c_uint) {
178207
let val: u32 = std::mem::transmute(val);
179-
self._bitfield.set(6usize, 1u8, val as u64)
208+
self._bitfield
209+
.set(STATE_ASCII_INDEX, STATE_ASCII_WIDTH, val as u64)
180210
}
181211

212+
#[cfg(not(Py_3_12))]
182213
#[inline]
183214
unsafe fn ready(&self) -> c_uint {
184-
std::mem::transmute(self._bitfield.get(7usize, 1u8) as u32)
215+
std::mem::transmute(self._bitfield.get(STATE_READY_INDEX, STATE_READY_WIDTH) as u32)
185216
}
186217

218+
#[cfg(not(Py_3_12))]
187219
#[inline]
188220
unsafe fn set_ready(&mut self, val: c_uint) {
189221
let val: u32 = std::mem::transmute(val);
190-
self._bitfield.set(7usize, 1u8, val as u64)
222+
self._bitfield
223+
.set(STATE_READY_INDEX, STATE_READY_WIDTH, val as u64)
191224
}
192225
}
193226

@@ -226,14 +259,16 @@ pub struct PyASCIIObject {
226259
/// unsigned int ready:1;
227260
/// unsigned int :24;
228261
pub state: u32,
262+
#[cfg(not(Py_3_12))]
229263
pub wstr: *mut wchar_t,
230264
}
231265

232266
/// Interacting with the bitfield is not actually well-defined, so we mark these APIs unsafe.
233267
impl PyASCIIObject {
234268
/// Get the `interned` field of the [`PyASCIIObject`] state bitfield.
235269
///
236-
/// Returns one of: [`SSTATE_NOT_INTERNED`], [`SSTATE_INTERNED_MORTAL`], [`SSTATE_INTERNED_IMMORTAL`]
270+
/// Returns one of: [`SSTATE_NOT_INTERNED`], [`SSTATE_INTERNED_MORTAL`],
271+
/// or on CPython earlier than 3.12, [`SSTATE_INTERNED_IMMORTAL`]
237272
#[inline]
238273
pub unsafe fn interned(&self) -> c_uint {
239274
PyASCIIObjectState::from(self.state).interned()
@@ -242,7 +277,8 @@ impl PyASCIIObject {
242277
/// Set the `interned` field of the [`PyASCIIObject`] state bitfield.
243278
///
244279
/// Calling this function with an argument that is not [`SSTATE_NOT_INTERNED`],
245-
/// [`SSTATE_INTERNED_MORTAL`], or [`SSTATE_INTERNED_IMMORTAL`] is invalid.
280+
/// [`SSTATE_INTERNED_MORTAL`], or on CPython earlier than 3.12,
281+
/// [`SSTATE_INTERNED_IMMORTAL`] is invalid.
246282
#[inline]
247283
pub unsafe fn set_interned(&mut self, val: c_uint) {
248284
let mut state = PyASCIIObjectState::from(self.state);
@@ -309,6 +345,7 @@ impl PyASCIIObject {
309345
/// Get the `ready` field of the [`PyASCIIObject`] state bitfield.
310346
///
311347
/// Returns either `0` or `1`.
348+
#[cfg(not(Py_3_12))]
312349
#[inline]
313350
pub unsafe fn ready(&self) -> c_uint {
314351
PyASCIIObjectState::from(self.state).ready()
@@ -317,6 +354,7 @@ impl PyASCIIObject {
317354
/// Set the `ready` flag of the [`PyASCIIObject`] state bitfield.
318355
///
319356
/// Calling this function with an argument that is neither `0` nor `1` is invalid.
357+
#[cfg(not(Py_3_12))]
320358
#[inline]
321359
pub unsafe fn set_ready(&mut self, val: c_uint) {
322360
let mut state = PyASCIIObjectState::from(self.state);
@@ -330,6 +368,7 @@ pub struct PyCompactUnicodeObject {
330368
pub _base: PyASCIIObject,
331369
pub utf8_length: Py_ssize_t,
332370
pub utf8: *mut c_char,
371+
#[cfg(not(Py_3_12))]
333372
pub wstr_length: Py_ssize_t,
334373
}
335374

@@ -359,6 +398,7 @@ extern "C" {
359398

360399
pub const SSTATE_NOT_INTERNED: c_uint = 0;
361400
pub const SSTATE_INTERNED_MORTAL: c_uint = 1;
401+
#[cfg(not(Py_3_12))]
362402
pub const SSTATE_INTERNED_IMMORTAL: c_uint = 2;
363403

364404
#[inline]
@@ -449,6 +489,14 @@ pub unsafe fn PyUnicode_GET_LENGTH(op: *mut PyObject) -> Py_ssize_t {
449489
(*(op as *mut PyASCIIObject)).length
450490
}
451491

492+
#[cfg(Py_3_12)]
493+
#[inline]
494+
pub unsafe fn PyUnicode_IS_READY(_op: *mut PyObject) -> c_uint {
495+
// kept in CPython for backwards compatibility
496+
1
497+
}
498+
499+
#[cfg(not(Py_3_12))]
452500
#[inline]
453501
pub unsafe fn PyUnicode_IS_READY(op: *mut PyObject) -> c_uint {
454502
(*(op as *mut PyASCIIObject)).ready()

pyo3-ffi/src/unicodeobject.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ extern "C" {
8383
pub fn PyUnicode_FromFormat(format: *const c_char, ...) -> *mut PyObject;
8484
#[cfg_attr(PyPy, link_name = "PyPyUnicode_InternInPlace")]
8585
pub fn PyUnicode_InternInPlace(arg1: *mut *mut PyObject);
86+
#[cfg(not(Py_3_12))]
87+
#[cfg_attr(Py_3_10, deprecated(note = "Python 3.10"))]
8688
pub fn PyUnicode_InternImmortal(arg1: *mut *mut PyObject);
8789
#[cfg_attr(PyPy, link_name = "PyPyUnicode_InternFromString")]
8890
pub fn PyUnicode_InternFromString(u: *const c_char) -> *mut PyObject;

0 commit comments

Comments
 (0)