python3_sys/
unicodeobject.rs

1use libc::{c_char, c_int, c_void, wchar_t};
2
3use crate::object::*;
4#[cfg(not(Py_LIMITED_API))]
5use crate::pyport::Py_hash_t;
6use crate::pyport::Py_ssize_t;
7
8#[cfg(not(Py_LIMITED_API))]
9#[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3 / PEP 393")]
10pub type Py_UNICODE = wchar_t;
11
12pub type Py_UCS4 = u32;
13pub type Py_UCS2 = u16;
14pub type Py_UCS1 = u8;
15
16#[cfg_attr(windows, link(name = "pythonXY"))]
17extern "C" {
18    pub static mut PyUnicode_Type: PyTypeObject;
19    pub static mut PyUnicodeIter_Type: PyTypeObject;
20}
21
22#[inline(always)]
23pub unsafe fn PyUnicode_Check(op: *mut PyObject) -> c_int {
24    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
25}
26
27#[inline(always)]
28pub unsafe fn PyUnicode_CheckExact(op: *mut PyObject) -> c_int {
29    (Py_TYPE(op) == &mut PyUnicode_Type) as c_int
30}
31
32pub const Py_UNICODE_REPLACEMENT_CHARACTER: Py_UCS4 = 0xFFFD;
33
34#[allow(deprecated)]
35#[cfg_attr(windows, link(name = "pythonXY"))]
36extern "C" {
37    #[cfg(not(Py_LIMITED_API))]
38    pub fn PyUnicode_New(size: Py_ssize_t, maxchar: Py_UCS4) -> *mut PyObject;
39
40    #[cfg(not(Py_LIMITED_API))]
41    pub fn PyUnicode_CopyCharacters(
42        to: *mut PyObject,
43        to_start: Py_ssize_t,
44        from: *mut PyObject,
45        from_start: Py_ssize_t,
46        how_many: Py_ssize_t,
47    ) -> Py_ssize_t;
48    #[cfg(not(Py_LIMITED_API))]
49    pub fn PyUnicode_Fill(
50        unicode: *mut PyObject,
51        start: Py_ssize_t,
52        length: Py_ssize_t,
53        fill_char: Py_UCS4,
54    ) -> Py_ssize_t;
55    #[cfg(all(not(Py_LIMITED_API), not(Py_3_12)))]
56    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3 / PEP 393")]
57    pub fn PyUnicode_FromUnicode(u: *const Py_UNICODE, size: Py_ssize_t) -> *mut PyObject;
58
59    pub fn PyUnicode_FromStringAndSize(u: *const c_char, size: Py_ssize_t) -> *mut PyObject;
60    pub fn PyUnicode_FromString(u: *const c_char) -> *mut PyObject;
61
62    #[cfg(not(Py_LIMITED_API))]
63    pub fn PyUnicode_FromKindAndData(
64        kind: c_int,
65        buffer: *const c_void,
66        size: Py_ssize_t,
67    ) -> *mut PyObject;
68
69    pub fn PyUnicode_Substring(
70        str: *mut PyObject,
71        start: Py_ssize_t,
72        end: Py_ssize_t,
73    ) -> *mut PyObject;
74    pub fn PyUnicode_AsUCS4(
75        unicode: *mut PyObject,
76        buffer: *mut Py_UCS4,
77        buflen: Py_ssize_t,
78        copy_null: c_int,
79    ) -> *mut Py_UCS4;
80    pub fn PyUnicode_AsUCS4Copy(unicode: *mut PyObject) -> *mut Py_UCS4;
81    #[cfg(all(not(Py_LIMITED_API), not(Py_3_12)))]
82    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3 / PEP 393")]
83    pub fn PyUnicode_AsUnicode(unicode: *mut PyObject) -> *mut Py_UNICODE;
84    #[cfg(all(not(Py_LIMITED_API), not(Py_3_12)))]
85    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3 / PEP 393")]
86    pub fn PyUnicode_AsUnicodeAndSize(
87        unicode: *mut PyObject,
88        size: *mut Py_ssize_t,
89    ) -> *mut Py_UNICODE;
90    pub fn PyUnicode_GetLength(unicode: *mut PyObject) -> Py_ssize_t;
91    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3 / PEP 393")]
92    pub fn PyUnicode_GetSize(unicode: *mut PyObject) -> Py_ssize_t;
93    pub fn PyUnicode_ReadChar(unicode: *mut PyObject, index: Py_ssize_t) -> Py_UCS4;
94    pub fn PyUnicode_WriteChar(
95        unicode: *mut PyObject,
96        index: Py_ssize_t,
97        character: Py_UCS4,
98    ) -> c_int;
99    #[cfg(all(not(Py_LIMITED_API), not(Py_3_10)))]
100    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3 / PEP 393")]
101    pub fn PyUnicode_GetMax() -> Py_UNICODE;
102    pub fn PyUnicode_Resize(unicode: *mut *mut PyObject, length: Py_ssize_t) -> c_int;
103    pub fn PyUnicode_FromEncodedObject(
104        obj: *mut PyObject,
105        encoding: *const c_char,
106        errors: *const c_char,
107    ) -> *mut PyObject;
108    pub fn PyUnicode_FromObject(obj: *mut PyObject) -> *mut PyObject;
109    ignore! {
110        pub fn PyUnicode_FromFormatV(format: *const c_char, vargs: va_list) -> *mut PyObject;
111    }
112    pub fn PyUnicode_FromFormat(format: *const c_char, ...) -> *mut PyObject;
113    pub fn PyUnicode_InternInPlace(arg1: *mut *mut PyObject) -> ();
114    #[deprecated(since = "0.6.1", note = "Deprecated since Python 3.10")]
115    pub fn PyUnicode_InternImmortal(arg1: *mut *mut PyObject) -> ();
116    pub fn PyUnicode_InternFromString(u: *const c_char) -> *mut PyObject;
117    pub fn PyUnicode_FromWideChar(w: *const wchar_t, size: Py_ssize_t) -> *mut PyObject;
118    pub fn PyUnicode_AsWideChar(
119        unicode: *mut PyObject,
120        w: *mut wchar_t,
121        size: Py_ssize_t,
122    ) -> Py_ssize_t;
123    pub fn PyUnicode_AsWideCharString(
124        unicode: *mut PyObject,
125        size: *mut Py_ssize_t,
126    ) -> *mut wchar_t;
127    pub fn PyUnicode_FromOrdinal(ordinal: c_int) -> *mut PyObject;
128    #[cfg(not(Py_3_9))]
129    pub fn PyUnicode_ClearFreeList() -> c_int;
130    #[cfg(any(not(Py_LIMITED_API), Py_3_10))]
131    pub fn PyUnicode_AsUTF8AndSize(unicode: *mut PyObject, size: *mut Py_ssize_t) -> *const c_char;
132    #[cfg(not(Py_LIMITED_API))]
133    pub fn PyUnicode_AsUTF8(unicode: *mut PyObject) -> *const c_char;
134    pub fn PyUnicode_GetDefaultEncoding() -> *const c_char;
135    pub fn PyUnicode_Decode(
136        s: *const c_char,
137        size: Py_ssize_t,
138        encoding: *const c_char,
139        errors: *const c_char,
140    ) -> *mut PyObject;
141    pub fn PyUnicode_AsDecodedObject(
142        unicode: *mut PyObject,
143        encoding: *const c_char,
144        errors: *const c_char,
145    ) -> *mut PyObject;
146    pub fn PyUnicode_AsDecodedUnicode(
147        unicode: *mut PyObject,
148        encoding: *const c_char,
149        errors: *const c_char,
150    ) -> *mut PyObject;
151    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
152    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3 / PEP 393, removed in Python 3.11")]
153    pub fn PyUnicode_Encode(
154        s: *const Py_UNICODE,
155        size: Py_ssize_t,
156        encoding: *const c_char,
157        errors: *const c_char,
158    ) -> *mut PyObject;
159    #[deprecated(
160        since = "0.2.1",
161        note = "Deprecated since Python 3.6; use PyUnicode_AsEncodedString() instead"
162    )]
163    pub fn PyUnicode_AsEncodedObject(
164        unicode: *mut PyObject,
165        encoding: *const c_char,
166        errors: *const c_char,
167    ) -> *mut PyObject;
168    pub fn PyUnicode_AsEncodedString(
169        unicode: *mut PyObject,
170        encoding: *const c_char,
171        errors: *const c_char,
172    ) -> *mut PyObject;
173    #[deprecated(
174        since = "0.2.1",
175        note = "Deprecated since Python 3.6; use PyUnicode_AsEncodedString() instead"
176    )]
177    pub fn PyUnicode_AsEncodedUnicode(
178        unicode: *mut PyObject,
179        encoding: *const c_char,
180        errors: *const c_char,
181    ) -> *mut PyObject;
182    pub fn PyUnicode_BuildEncodingMap(string: *mut PyObject) -> *mut PyObject;
183    pub fn PyUnicode_DecodeUTF7(
184        string: *const c_char,
185        length: Py_ssize_t,
186        errors: *const c_char,
187    ) -> *mut PyObject;
188    pub fn PyUnicode_DecodeUTF7Stateful(
189        string: *const c_char,
190        length: Py_ssize_t,
191        errors: *const c_char,
192        consumed: *mut Py_ssize_t,
193    ) -> *mut PyObject;
194    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
195    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
196    pub fn PyUnicode_EncodeUTF7(
197        data: *const Py_UNICODE,
198        length: Py_ssize_t,
199        base64SetO: c_int,
200        base64WhiteSpace: c_int,
201        errors: *const c_char,
202    ) -> *mut PyObject;
203    pub fn PyUnicode_DecodeUTF8(
204        string: *const c_char,
205        length: Py_ssize_t,
206        errors: *const c_char,
207    ) -> *mut PyObject;
208    pub fn PyUnicode_DecodeUTF8Stateful(
209        string: *const c_char,
210        length: Py_ssize_t,
211        errors: *const c_char,
212        consumed: *mut Py_ssize_t,
213    ) -> *mut PyObject;
214    pub fn PyUnicode_AsUTF8String(unicode: *mut PyObject) -> *mut PyObject;
215    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
216    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
217    pub fn PyUnicode_EncodeUTF8(
218        data: *const Py_UNICODE,
219        length: Py_ssize_t,
220        errors: *const c_char,
221    ) -> *mut PyObject;
222    pub fn PyUnicode_DecodeUTF32(
223        string: *const c_char,
224        length: Py_ssize_t,
225        errors: *const c_char,
226        byteorder: *mut c_int,
227    ) -> *mut PyObject;
228    pub fn PyUnicode_DecodeUTF32Stateful(
229        string: *const c_char,
230        length: Py_ssize_t,
231        errors: *const c_char,
232        byteorder: *mut c_int,
233        consumed: *mut Py_ssize_t,
234    ) -> *mut PyObject;
235    pub fn PyUnicode_AsUTF32String(unicode: *mut PyObject) -> *mut PyObject;
236    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
237    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
238    pub fn PyUnicode_EncodeUTF32(
239        data: *const Py_UNICODE,
240        length: Py_ssize_t,
241        errors: *const c_char,
242        byteorder: c_int,
243    ) -> *mut PyObject;
244    pub fn PyUnicode_DecodeUTF16(
245        string: *const c_char,
246        length: Py_ssize_t,
247        errors: *const c_char,
248        byteorder: *mut c_int,
249    ) -> *mut PyObject;
250    pub fn PyUnicode_DecodeUTF16Stateful(
251        string: *const c_char,
252        length: Py_ssize_t,
253        errors: *const c_char,
254        byteorder: *mut c_int,
255        consumed: *mut Py_ssize_t,
256    ) -> *mut PyObject;
257    pub fn PyUnicode_AsUTF16String(unicode: *mut PyObject) -> *mut PyObject;
258    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
259    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
260    pub fn PyUnicode_EncodeUTF16(
261        data: *const Py_UNICODE,
262        length: Py_ssize_t,
263        errors: *const c_char,
264        byteorder: c_int,
265    ) -> *mut PyObject;
266    pub fn PyUnicode_DecodeUnicodeEscape(
267        string: *const c_char,
268        length: Py_ssize_t,
269        errors: *const c_char,
270    ) -> *mut PyObject;
271    pub fn PyUnicode_AsUnicodeEscapeString(unicode: *mut PyObject) -> *mut PyObject;
272    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
273    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
274    pub fn PyUnicode_EncodeUnicodeEscape(
275        data: *const Py_UNICODE,
276        length: Py_ssize_t,
277    ) -> *mut PyObject;
278    pub fn PyUnicode_DecodeRawUnicodeEscape(
279        string: *const c_char,
280        length: Py_ssize_t,
281        errors: *const c_char,
282    ) -> *mut PyObject;
283    pub fn PyUnicode_AsRawUnicodeEscapeString(unicode: *mut PyObject) -> *mut PyObject;
284    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
285    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
286    pub fn PyUnicode_EncodeRawUnicodeEscape(
287        data: *const Py_UNICODE,
288        length: Py_ssize_t,
289    ) -> *mut PyObject;
290    pub fn PyUnicode_DecodeLatin1(
291        string: *const c_char,
292        length: Py_ssize_t,
293        errors: *const c_char,
294    ) -> *mut PyObject;
295    pub fn PyUnicode_AsLatin1String(unicode: *mut PyObject) -> *mut PyObject;
296    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
297    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
298    pub fn PyUnicode_EncodeLatin1(
299        data: *const Py_UNICODE,
300        length: Py_ssize_t,
301        errors: *const c_char,
302    ) -> *mut PyObject;
303    pub fn PyUnicode_DecodeASCII(
304        string: *const c_char,
305        length: Py_ssize_t,
306        errors: *const c_char,
307    ) -> *mut PyObject;
308    pub fn PyUnicode_AsASCIIString(unicode: *mut PyObject) -> *mut PyObject;
309    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
310    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
311    pub fn PyUnicode_EncodeASCII(
312        data: *const Py_UNICODE,
313        length: Py_ssize_t,
314        errors: *const c_char,
315    ) -> *mut PyObject;
316    pub fn PyUnicode_DecodeCharmap(
317        string: *const c_char,
318        length: Py_ssize_t,
319        mapping: *mut PyObject,
320        errors: *const c_char,
321    ) -> *mut PyObject;
322    pub fn PyUnicode_AsCharmapString(
323        unicode: *mut PyObject,
324        mapping: *mut PyObject,
325    ) -> *mut PyObject;
326    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
327    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
328    pub fn PyUnicode_EncodeCharmap(
329        data: *const Py_UNICODE,
330        length: Py_ssize_t,
331        mapping: *mut PyObject,
332        errors: *const c_char,
333    ) -> *mut PyObject;
334    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
335    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
336    pub fn PyUnicode_TranslateCharmap(
337        data: *const Py_UNICODE,
338        length: Py_ssize_t,
339        table: *mut PyObject,
340        errors: *const c_char,
341    ) -> *mut PyObject;
342
343    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
344    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
345    pub fn PyUnicode_EncodeDecimal(
346        s: *mut Py_UNICODE,
347        length: Py_ssize_t,
348        output: *mut c_char,
349        errors: *const c_char,
350    ) -> c_int;
351    #[cfg(all(not(Py_LIMITED_API), not(Py_3_11)))]
352    #[deprecated(since = "0.2.1", note = "Deprecated since Python 3.3")]
353    pub fn PyUnicode_TransformDecimalToASCII(
354        s: *mut Py_UNICODE,
355        length: Py_ssize_t,
356    ) -> *mut PyObject;
357    pub fn PyUnicode_DecodeLocaleAndSize(
358        str: *const c_char,
359        len: Py_ssize_t,
360        errors: *const c_char,
361    ) -> *mut PyObject;
362    pub fn PyUnicode_DecodeLocale(str: *const c_char, errors: *const c_char) -> *mut PyObject;
363    pub fn PyUnicode_EncodeLocale(unicode: *mut PyObject, errors: *const c_char) -> *mut PyObject;
364    pub fn PyUnicode_FSConverter(arg1: *mut PyObject, arg2: *mut c_void) -> c_int;
365    pub fn PyUnicode_FSDecoder(arg1: *mut PyObject, arg2: *mut c_void) -> c_int;
366    pub fn PyUnicode_DecodeFSDefault(s: *const c_char) -> *mut PyObject;
367    pub fn PyUnicode_DecodeFSDefaultAndSize(s: *const c_char, size: Py_ssize_t) -> *mut PyObject;
368    pub fn PyUnicode_EncodeFSDefault(unicode: *mut PyObject) -> *mut PyObject;
369    pub fn PyUnicode_Concat(left: *mut PyObject, right: *mut PyObject) -> *mut PyObject;
370    pub fn PyUnicode_Append(pleft: *mut *mut PyObject, right: *mut PyObject) -> ();
371    pub fn PyUnicode_AppendAndDel(pleft: *mut *mut PyObject, right: *mut PyObject) -> ();
372    pub fn PyUnicode_Split(
373        s: *mut PyObject,
374        sep: *mut PyObject,
375        maxsplit: Py_ssize_t,
376    ) -> *mut PyObject;
377    pub fn PyUnicode_Splitlines(s: *mut PyObject, keepends: c_int) -> *mut PyObject;
378    pub fn PyUnicode_Partition(s: *mut PyObject, sep: *mut PyObject) -> *mut PyObject;
379    pub fn PyUnicode_RPartition(s: *mut PyObject, sep: *mut PyObject) -> *mut PyObject;
380    pub fn PyUnicode_RSplit(
381        s: *mut PyObject,
382        sep: *mut PyObject,
383        maxsplit: Py_ssize_t,
384    ) -> *mut PyObject;
385    pub fn PyUnicode_Translate(
386        str: *mut PyObject,
387        table: *mut PyObject,
388        errors: *const c_char,
389    ) -> *mut PyObject;
390    pub fn PyUnicode_Join(separator: *mut PyObject, seq: *mut PyObject) -> *mut PyObject;
391    pub fn PyUnicode_Tailmatch(
392        str: *mut PyObject,
393        substr: *mut PyObject,
394        start: Py_ssize_t,
395        end: Py_ssize_t,
396        direction: c_int,
397    ) -> Py_ssize_t;
398    pub fn PyUnicode_Find(
399        str: *mut PyObject,
400        substr: *mut PyObject,
401        start: Py_ssize_t,
402        end: Py_ssize_t,
403        direction: c_int,
404    ) -> Py_ssize_t;
405    pub fn PyUnicode_FindChar(
406        str: *mut PyObject,
407        ch: Py_UCS4,
408        start: Py_ssize_t,
409        end: Py_ssize_t,
410        direction: c_int,
411    ) -> Py_ssize_t;
412    pub fn PyUnicode_Count(
413        str: *mut PyObject,
414        substr: *mut PyObject,
415        start: Py_ssize_t,
416        end: Py_ssize_t,
417    ) -> Py_ssize_t;
418    pub fn PyUnicode_Replace(
419        str: *mut PyObject,
420        substr: *mut PyObject,
421        replstr: *mut PyObject,
422        maxcount: Py_ssize_t,
423    ) -> *mut PyObject;
424    pub fn PyUnicode_Compare(left: *mut PyObject, right: *mut PyObject) -> c_int;
425    pub fn PyUnicode_CompareWithASCIIString(left: *mut PyObject, right: *const c_char) -> c_int;
426    pub fn PyUnicode_RichCompare(
427        left: *mut PyObject,
428        right: *mut PyObject,
429        op: c_int,
430    ) -> *mut PyObject;
431    pub fn PyUnicode_Format(format: *mut PyObject, args: *mut PyObject) -> *mut PyObject;
432    pub fn PyUnicode_Contains(container: *mut PyObject, element: *mut PyObject) -> c_int;
433    pub fn PyUnicode_IsIdentifier(s: *mut PyObject) -> c_int;
434    #[cfg(all(not(Py_LIMITED_API), not(Py_3_10)))]
435    #[deprecated(since = "0.6.1", note = "Deprecated since Python 3.3; removed in 3.10")]
436    pub fn PyUnicode_AsUnicodeCopy(unicode: *mut PyObject) -> *mut Py_UNICODE;
437
438    #[cfg(not(any(Py_LIMITED_API, Py_3_12)))]
439    fn _PyUnicode_Ready(o: *mut PyObject) -> c_int;
440}
441
442#[repr(C)]
443#[cfg(not(Py_LIMITED_API))]
444pub struct PyASCIIObject {
445    pub ob_base: PyObject,
446    pub length: Py_ssize_t,
447    pub hash: Py_hash_t,
448    pub state: u32,
449    #[cfg(not(Py_3_12))]
450    pub wstr: *mut c_void,
451}
452
453#[repr(C)]
454#[cfg(not(Py_LIMITED_API))]
455pub struct PyCompactUnicodeObject {
456    _base: PyASCIIObject,
457    utf8_length: Py_ssize_t,
458    utf8: *mut u8,
459    #[cfg(not(Py_3_12))]
460    wstr_length: Py_ssize_t,
461}
462
463#[repr(C)]
464#[cfg(not(Py_LIMITED_API))]
465pub struct PyUnicodeObject {
466    _base: PyASCIIObject,
467    data: *mut c_void,
468}
469
470#[cfg(not(Py_LIMITED_API))]
471#[inline]
472unsafe fn PyUnicode_IS_ASCII(o: *mut PyObject) -> bool {
473    let ascii_bit = 1 << 6;
474    let state = (*(o as *mut PyASCIIObject)).state;
475    (state & ascii_bit) != 0
476}
477
478#[cfg(not(Py_LIMITED_API))]
479#[inline]
480unsafe fn PyUnicode_IS_COMPACT(o: *mut PyObject) -> bool {
481    let compact_bit = 1 << 5;
482    let state = (*(o as *mut PyASCIIObject)).state;
483    (state & compact_bit) != 0
484}
485
486#[cfg(not(Py_LIMITED_API))]
487pub const PyUnicode_WCHAR_KIND: u32 = 0;
488#[cfg(not(Py_LIMITED_API))]
489pub const PyUnicode_1BYTE_KIND: u32 = 1;
490#[cfg(not(Py_LIMITED_API))]
491pub const PyUnicode_2BYTE_KIND: u32 = 2;
492#[cfg(not(Py_LIMITED_API))]
493pub const PyUnicode_4BYTE_KIND: u32 = 4;
494
495#[cfg(not(Py_LIMITED_API))]
496#[inline]
497pub unsafe fn PyUnicode_KIND(o: *mut PyObject) -> u32 {
498    debug_assert!(PyUnicode_Check(o) > 0);
499    #[cfg(not(Py_3_12))]
500    debug_assert!(PyUnicode_IS_READY(o));
501    let state = (*(o as *mut PyASCIIObject)).state;
502    (state >> 2) & 7
503}
504
505#[cfg(not(Py_LIMITED_API))]
506pub unsafe fn PyUnicode_DATA(o: *mut PyObject) -> *mut c_void {
507    debug_assert!(PyUnicode_Check(o) > 0);
508    #[cfg(not(Py_3_12))]
509    debug_assert!(PyUnicode_IS_READY(o));
510    if PyUnicode_IS_COMPACT(o) {
511        // fn _PyUnicode_COMPACT_DATA
512        if PyUnicode_IS_ASCII(o) {
513            (o as *mut PyASCIIObject).offset(1) as *mut c_void
514        } else {
515            (o as *mut PyCompactUnicodeObject).offset(1) as *mut c_void
516        }
517    } else {
518        // fn _PyUnicode_NONCOMPACT_DATA
519        let data = (*(o as *mut PyUnicodeObject)).data;
520        debug_assert!(!data.is_null());
521        data
522    }
523}
524
525#[cfg(not(Py_LIMITED_API))]
526#[inline]
527pub unsafe fn PyUnicode_GET_LENGTH(o: *mut PyObject) -> Py_ssize_t {
528    debug_assert!(PyUnicode_Check(o) > 0);
529    #[cfg(not(Py_3_12))]
530    debug_assert!(PyUnicode_IS_READY(o));
531    (*(o as *mut PyASCIIObject)).length
532}
533
534#[cfg(not(any(Py_LIMITED_API, Py_3_12)))]
535#[inline]
536unsafe fn PyUnicode_IS_READY(o: *mut PyObject) -> bool {
537    let ready_bit = 1 << 7;
538    let state = (*(o as *mut PyASCIIObject)).state;
539    (state & ready_bit) != 0
540}
541
542#[cfg(not(Py_LIMITED_API))]
543#[inline]
544pub unsafe fn PyUnicode_READY(o: *mut PyObject) -> c_int {
545    debug_assert!(PyUnicode_Check(o) > 0);
546    #[cfg(Py_3_12)]
547    {
548        return 0;
549    }
550    #[cfg(not(Py_3_12))]
551    {
552        if PyUnicode_IS_READY(o) {
553            0
554        } else {
555            _PyUnicode_Ready(o)
556        }
557    }
558}