| 1 | #![cfg_attr (docsrs, feature(doc_cfg, doc_auto_cfg))] |
| 2 | //! Raw FFI declarations for Python's C API. |
| 3 | //! |
| 4 | //! PyO3 can be used to write native Python modules or run Python code and modules from Rust. |
| 5 | //! |
| 6 | //! This crate just provides low level bindings to the Python interpreter. |
| 7 | //! It is meant for advanced users only - regular PyO3 users shouldn't |
| 8 | //! need to interact with this crate at all. |
| 9 | //! |
| 10 | //! The contents of this crate are not documented here, as it would entail |
| 11 | //! basically copying the documentation from CPython. Consult the [Python/C API Reference |
| 12 | //! Manual][capi] for up-to-date documentation. |
| 13 | //! |
| 14 | //! # Safety |
| 15 | //! |
| 16 | //! The functions in this crate lack individual safety documentation, but |
| 17 | //! generally the following apply: |
| 18 | //! - Pointer arguments have to point to a valid Python object of the correct type, |
| 19 | //! although null pointers are sometimes valid input. |
| 20 | //! - The vast majority can only be used safely while the GIL is held. |
| 21 | //! - Some functions have additional safety requirements, consult the |
| 22 | //! [Python/C API Reference Manual][capi] |
| 23 | //! for more information. |
| 24 | //! |
| 25 | //! |
| 26 | //! # Feature flags |
| 27 | //! |
| 28 | //! PyO3 uses [feature flags] to enable you to opt-in to additional functionality. For a detailed |
| 29 | //! description, see the [Features chapter of the guide]. |
| 30 | //! |
| 31 | //! ## Optional feature flags |
| 32 | //! |
| 33 | //! The following features customize PyO3's behavior: |
| 34 | //! |
| 35 | //! - `abi3`: Restricts PyO3's API to a subset of the full Python API which is guaranteed by |
| 36 | //! [PEP 384] to be forward-compatible with future Python versions. |
| 37 | //! - `extension-module`: This will tell the linker to keep the Python symbols unresolved, so that |
| 38 | //! your module can also be used with statically linked Python interpreters. Use this feature when |
| 39 | //! building an extension module. |
| 40 | //! |
| 41 | //! ## `rustc` environment flags |
| 42 | //! |
| 43 | //! PyO3 uses `rustc`'s `--cfg` flags to enable or disable code used for different Python versions. |
| 44 | //! If you want to do this for your own crate, you can do so with the [`pyo3-build-config`] crate. |
| 45 | //! |
| 46 | //! - `Py_3_7`, `Py_3_8`, `Py_3_9`, `Py_3_10`, `Py_3_11`, `Py_3_12`, `Py_3_13`: Marks code that is |
| 47 | //! only enabled when compiling for a given minimum Python version. |
| 48 | //! - `Py_LIMITED_API`: Marks code enabled when the `abi3` feature flag is enabled. |
| 49 | //! - `Py_GIL_DISABLED`: Marks code that runs only in the free-threaded build of CPython. |
| 50 | //! - `PyPy` - Marks code enabled when compiling for PyPy. |
| 51 | //! - `GraalPy` - Marks code enabled when compiling for GraalPy. |
| 52 | //! |
| 53 | //! Additionally, you can query for the values `Py_DEBUG`, `Py_REF_DEBUG`, |
| 54 | //! `Py_TRACE_REFS`, and `COUNT_ALLOCS` from `py_sys_config` to query for the |
| 55 | //! corresponding C build-time defines. For example, to conditionally define |
| 56 | //! debug code using `Py_DEBUG`, you could do: |
| 57 | //! |
| 58 | //! ```rust,ignore |
| 59 | //! #[cfg(py_sys_config = "Py_DEBUG" )] |
| 60 | //! println!("only runs if python was compiled with Py_DEBUG" ) |
| 61 | //! ``` |
| 62 | //! |
| 63 | //! To use these attributes, add [`pyo3-build-config`] as a build dependency in |
| 64 | //! your `Cargo.toml`: |
| 65 | //! |
| 66 | //! ```toml |
| 67 | //! [build-dependencies] |
| 68 | #![doc = concat!("pyo3-build-config = \"" , env!("CARGO_PKG_VERSION" ), " \"" )] |
| 69 | //! ``` |
| 70 | //! |
| 71 | //! And then either create a new `build.rs` file in the project root or modify |
| 72 | //! the existing `build.rs` file to call `use_pyo3_cfgs()`: |
| 73 | //! |
| 74 | //! ```rust,ignore |
| 75 | //! fn main() { |
| 76 | //! pyo3_build_config::use_pyo3_cfgs(); |
| 77 | //! } |
| 78 | //! ``` |
| 79 | //! |
| 80 | //! # Minimum supported Rust and Python versions |
| 81 | //! |
| 82 | //! `pyo3-ffi` supports the following Python distributions: |
| 83 | //! - CPython 3.7 or greater |
| 84 | //! - PyPy 7.3 (Python 3.9+) |
| 85 | //! - GraalPy 24.0 or greater (Python 3.10+) |
| 86 | //! |
| 87 | //! # Example: Building Python Native modules |
| 88 | //! |
| 89 | //! PyO3 can be used to generate a native Python module. The easiest way to try this out for the |
| 90 | //! first time is to use [`maturin`]. `maturin` is a tool for building and publishing Rust-based |
| 91 | //! Python packages with minimal configuration. The following steps set up some files for an example |
| 92 | //! Python module, install `maturin`, and then show how to build and import the Python module. |
| 93 | //! |
| 94 | //! First, create a new folder (let's call it `string_sum`) containing the following two files: |
| 95 | //! |
| 96 | //! **`Cargo.toml`** |
| 97 | //! |
| 98 | //! ```toml |
| 99 | //! [lib] |
| 100 | //! name = "string_sum" |
| 101 | //! # "cdylib" is necessary to produce a shared library for Python to import from. |
| 102 | //! # |
| 103 | //! # Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able |
| 104 | //! # to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.: |
| 105 | //! # crate-type = ["cdylib", "rlib"] |
| 106 | //! crate-type = ["cdylib"] |
| 107 | //! |
| 108 | //! [dependencies.pyo3-ffi] |
| 109 | #![doc = concat!("version = \"" , env!("CARGO_PKG_VERSION" ), " \"" )] |
| 110 | //! features = ["extension-module"] |
| 111 | //! |
| 112 | //! [build-dependencies] |
| 113 | //! # This is only necessary if you need to configure your build based on |
| 114 | //! # the Python version or the compile-time configuration for the interpreter. |
| 115 | #![doc = concat!("pyo3_build_config = \"" , env!("CARGO_PKG_VERSION" ), " \"" )] |
| 116 | //! ``` |
| 117 | //! |
| 118 | //! If you need to use conditional compilation based on Python version or how |
| 119 | //! Python was compiled, you need to add `pyo3-build-config` as a |
| 120 | //! `build-dependency` in your `Cargo.toml` as in the example above and either |
| 121 | //! create a new `build.rs` file or modify an existing one so that |
| 122 | //! `pyo3_build_config::use_pyo3_cfgs()` gets called at build time: |
| 123 | //! |
| 124 | //! **`build.rs`** |
| 125 | //! ```rust,ignore |
| 126 | //! fn main() { |
| 127 | //! pyo3_build_config::use_pyo3_cfgs() |
| 128 | //! } |
| 129 | //! ``` |
| 130 | //! |
| 131 | //! **`src/lib.rs`** |
| 132 | //! ```rust |
| 133 | //! use std::os::raw::{c_char, c_long}; |
| 134 | //! use std::ptr; |
| 135 | //! |
| 136 | //! use pyo3_ffi::*; |
| 137 | //! |
| 138 | //! static mut MODULE_DEF: PyModuleDef = PyModuleDef { |
| 139 | //! m_base: PyModuleDef_HEAD_INIT, |
| 140 | //! m_name: c_str!("string_sum" ).as_ptr(), |
| 141 | //! m_doc: c_str!("A Python module written in Rust." ).as_ptr(), |
| 142 | //! m_size: 0, |
| 143 | //! m_methods: unsafe { METHODS as *const [PyMethodDef] as *mut PyMethodDef }, |
| 144 | //! m_slots: std::ptr::null_mut(), |
| 145 | //! m_traverse: None, |
| 146 | //! m_clear: None, |
| 147 | //! m_free: None, |
| 148 | //! }; |
| 149 | //! |
| 150 | //! static mut METHODS: &[PyMethodDef] = &[ |
| 151 | //! PyMethodDef { |
| 152 | //! ml_name: c_str!("sum_as_string" ).as_ptr(), |
| 153 | //! ml_meth: PyMethodDefPointer { |
| 154 | //! PyCFunctionFast: sum_as_string, |
| 155 | //! }, |
| 156 | //! ml_flags: METH_FASTCALL, |
| 157 | //! ml_doc: c_str!("returns the sum of two integers as a string" ).as_ptr(), |
| 158 | //! }, |
| 159 | //! // A zeroed PyMethodDef to mark the end of the array. |
| 160 | //! PyMethodDef::zeroed(), |
| 161 | //! ]; |
| 162 | //! |
| 163 | //! // The module initialization function, which must be named `PyInit_<your_module>`. |
| 164 | //! #[allow(non_snake_case)] |
| 165 | //! #[no_mangle] |
| 166 | //! pub unsafe extern "C" fn PyInit_string_sum() -> *mut PyObject { |
| 167 | //! let module = PyModule_Create(ptr::addr_of_mut!(MODULE_DEF)); |
| 168 | //! if module.is_null() { |
| 169 | //! return module; |
| 170 | //! } |
| 171 | //! #[cfg (Py_GIL_DISABLED)] |
| 172 | //! { |
| 173 | //! if PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED) < 0 { |
| 174 | //! Py_DECREF(module); |
| 175 | //! return std::ptr::null_mut(); |
| 176 | //! } |
| 177 | //! } |
| 178 | //! module |
| 179 | //! } |
| 180 | //! |
| 181 | //! /// A helper to parse function arguments |
| 182 | //! /// If we used PyO3's proc macros they'd handle all of this boilerplate for us :) |
| 183 | //! unsafe fn parse_arg_as_i32(obj: *mut PyObject, n_arg: usize) -> Option<i32> { |
| 184 | //! if PyLong_Check(obj) == 0 { |
| 185 | //! let msg = format!( |
| 186 | //! "sum_as_string expected an int for positional argument {} \0" , |
| 187 | //! n_arg |
| 188 | //! ); |
| 189 | //! PyErr_SetString(PyExc_TypeError, msg.as_ptr().cast::<c_char>()); |
| 190 | //! return None; |
| 191 | //! } |
| 192 | //! |
| 193 | //! // Let's keep the behaviour consistent on platforms where `c_long` is bigger than 32 bits. |
| 194 | //! // In particular, it is an i32 on Windows but i64 on most Linux systems |
| 195 | //! let mut overflow = 0; |
| 196 | //! let i_long: c_long = PyLong_AsLongAndOverflow(obj, &mut overflow); |
| 197 | //! |
| 198 | //! #[allow (irrefutable_let_patterns)] // some platforms have c_long equal to i32 |
| 199 | //! if overflow != 0 { |
| 200 | //! raise_overflowerror(obj); |
| 201 | //! None |
| 202 | //! } else if let Ok(i) = i_long.try_into() { |
| 203 | //! Some(i) |
| 204 | //! } else { |
| 205 | //! raise_overflowerror(obj); |
| 206 | //! None |
| 207 | //! } |
| 208 | //! } |
| 209 | //! |
| 210 | //! unsafe fn raise_overflowerror(obj: *mut PyObject) { |
| 211 | //! let obj_repr = PyObject_Str(obj); |
| 212 | //! if !obj_repr.is_null() { |
| 213 | //! let mut size = 0; |
| 214 | //! let p = PyUnicode_AsUTF8AndSize(obj_repr, &mut size); |
| 215 | //! if !p.is_null() { |
| 216 | //! let s = std::str::from_utf8_unchecked(std::slice::from_raw_parts( |
| 217 | //! p.cast::<u8>(), |
| 218 | //! size as usize, |
| 219 | //! )); |
| 220 | //! let msg = format!("cannot fit {} in 32 bits \0" , s); |
| 221 | //! |
| 222 | //! PyErr_SetString(PyExc_OverflowError, msg.as_ptr().cast::<c_char>()); |
| 223 | //! } |
| 224 | //! Py_DECREF(obj_repr); |
| 225 | //! } |
| 226 | //! } |
| 227 | //! |
| 228 | //! pub unsafe extern "C" fn sum_as_string( |
| 229 | //! _self: *mut PyObject, |
| 230 | //! args: *mut *mut PyObject, |
| 231 | //! nargs: Py_ssize_t, |
| 232 | //! ) -> *mut PyObject { |
| 233 | //! if nargs != 2 { |
| 234 | //! PyErr_SetString( |
| 235 | //! PyExc_TypeError, |
| 236 | //! c_str!("sum_as_string expected 2 positional arguments" ).as_ptr(), |
| 237 | //! ); |
| 238 | //! return std::ptr::null_mut(); |
| 239 | //! } |
| 240 | //! |
| 241 | //! let (first, second) = (*args, *args.add(1)); |
| 242 | //! |
| 243 | //! let first = match parse_arg_as_i32(first, 1) { |
| 244 | //! Some(x) => x, |
| 245 | //! None => return std::ptr::null_mut(), |
| 246 | //! }; |
| 247 | //! let second = match parse_arg_as_i32(second, 2) { |
| 248 | //! Some(x) => x, |
| 249 | //! None => return std::ptr::null_mut(), |
| 250 | //! }; |
| 251 | //! |
| 252 | //! match first.checked_add(second) { |
| 253 | //! Some(sum) => { |
| 254 | //! let string = sum.to_string(); |
| 255 | //! PyUnicode_FromStringAndSize(string.as_ptr().cast::<c_char>(), string.len() as isize) |
| 256 | //! } |
| 257 | //! None => { |
| 258 | //! PyErr_SetString( |
| 259 | //! PyExc_OverflowError, |
| 260 | //! c_str!("arguments too large to add" ).as_ptr(), |
| 261 | //! ); |
| 262 | //! std::ptr::null_mut() |
| 263 | //! } |
| 264 | //! } |
| 265 | //! } |
| 266 | //! ``` |
| 267 | //! |
| 268 | //! With those two files in place, now `maturin` needs to be installed. This can be done using |
| 269 | //! Python's package manager `pip`. First, load up a new Python `virtualenv`, and install `maturin` |
| 270 | //! into it: |
| 271 | //! ```bash |
| 272 | //! $ cd string_sum |
| 273 | //! $ python -m venv .env |
| 274 | //! $ source .env/bin/activate |
| 275 | //! $ pip install maturin |
| 276 | //! ``` |
| 277 | //! |
| 278 | //! Now build and execute the module: |
| 279 | //! ```bash |
| 280 | //! $ maturin develop |
| 281 | //! # lots of progress output as maturin runs the compilation... |
| 282 | //! $ python |
| 283 | //! >>> import string_sum |
| 284 | //! >>> string_sum.sum_as_string(5, 20) |
| 285 | //! '25' |
| 286 | //! ``` |
| 287 | //! |
| 288 | //! As well as with `maturin`, it is possible to build using [setuptools-rust] or |
| 289 | //! [manually][manual_builds]. Both offer more flexibility than `maturin` but require further |
| 290 | //! configuration. |
| 291 | //! |
| 292 | //! This example stores the module definition statically and uses the `PyModule_Create` function |
| 293 | //! in the CPython C API to register the module. This is the "old" style for registering modules |
| 294 | //! and has the limitation that it cannot support subinterpreters. You can also create a module |
| 295 | //! using the new multi-phase initialization API that does support subinterpreters. See the |
| 296 | //! `sequential` project located in the `examples` directory at the root of the `pyo3-ffi` crate |
| 297 | //! for a worked example of how to this using `pyo3-ffi`. |
| 298 | //! |
| 299 | //! # Using Python from Rust |
| 300 | //! |
| 301 | //! To embed Python into a Rust binary, you need to ensure that your Python installation contains a |
| 302 | //! shared library. The following steps demonstrate how to ensure this (for Ubuntu). |
| 303 | //! |
| 304 | //! To install the Python shared library on Ubuntu: |
| 305 | //! ```bash |
| 306 | //! sudo apt install python3-dev |
| 307 | //! ``` |
| 308 | //! |
| 309 | //! While most projects use the safe wrapper provided by pyo3, |
| 310 | //! you can take a look at the [`orjson`] library as an example on how to use `pyo3-ffi` directly. |
| 311 | //! For those well versed in C and Rust the [tutorials] from the CPython documentation |
| 312 | //! can be easily converted to rust as well. |
| 313 | //! |
| 314 | //! [tutorials]: https://docs.python.org/3/extending/ |
| 315 | //! [`orjson`]: https://github.com/ijl/orjson |
| 316 | //! [capi]: https://docs.python.org/3/c-api/index.html |
| 317 | //! [`maturin`]: https://github.com/PyO3/maturin "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages" |
| 318 | //! [`pyo3-build-config`]: https://docs.rs/pyo3-build-config |
| 319 | //! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book" |
| 320 | #![doc = concat!("[manual_builds]: https://pyo3.rs/v" , env!("CARGO_PKG_VERSION" ), "/building-and-distribution.html#manual-builds \"Manual builds - Building and Distribution - PyO3 user guide \"" )] |
| 321 | //! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions" |
| 322 | //! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI" |
| 323 | #![doc = concat!("[Features chapter of the guide]: https://pyo3.rs/v" , env!("CARGO_PKG_VERSION" ), "/features.html#features-reference \"Features eference - PyO3 user guide \"" )] |
| 324 | #![allow ( |
| 325 | missing_docs, |
| 326 | non_camel_case_types, |
| 327 | non_snake_case, |
| 328 | non_upper_case_globals, |
| 329 | clippy::upper_case_acronyms, |
| 330 | clippy::missing_safety_doc, |
| 331 | clippy::ptr_eq |
| 332 | )] |
| 333 | #![warn (elided_lifetimes_in_paths, unused_lifetimes)] |
| 334 | // This crate is a hand-maintained translation of CPython's headers, so requiring "unsafe" |
| 335 | // blocks within those translations increases maintenance burden without providing any |
| 336 | // additional safety. The safety of the functions in this crate is determined by the |
| 337 | // original CPython headers |
| 338 | #![allow (unsafe_op_in_unsafe_fn)] |
| 339 | |
| 340 | // Until `extern type` is stabilized, use the recommended approach to |
| 341 | // model opaque types: |
| 342 | // https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs |
| 343 | macro_rules! opaque_struct { |
| 344 | ($name:ident) => { |
| 345 | #[repr(C)] |
| 346 | pub struct $name([u8; 0]); |
| 347 | }; |
| 348 | } |
| 349 | |
| 350 | /// This is a helper macro to create a `&'static CStr`. |
| 351 | /// |
| 352 | /// It can be used on all Rust versions supported by PyO3, unlike c"" literals which |
| 353 | /// were stabilised in Rust 1.77. |
| 354 | /// |
| 355 | /// Due to the nature of PyO3 making heavy use of C FFI interop with Python, it is |
| 356 | /// common for PyO3 to use CStr. |
| 357 | /// |
| 358 | /// Examples: |
| 359 | /// |
| 360 | /// ```rust |
| 361 | /// use std::ffi::CStr; |
| 362 | /// |
| 363 | /// const HELLO: &CStr = pyo3_ffi::c_str!("hello" ); |
| 364 | /// static WORLD: &CStr = pyo3_ffi::c_str!("world" ); |
| 365 | /// ``` |
| 366 | #[macro_export ] |
| 367 | macro_rules! c_str { |
| 368 | ($s:expr) => { |
| 369 | $crate::_cstr_from_utf8_with_nul_checked(concat!($s, " \0" )) |
| 370 | }; |
| 371 | } |
| 372 | |
| 373 | /// Private helper for `c_str!` macro. |
| 374 | #[doc (hidden)] |
| 375 | pub const fn _cstr_from_utf8_with_nul_checked(s: &str) -> &CStr { |
| 376 | // TODO: Replace this implementation with `CStr::from_bytes_with_nul` when MSRV above 1.72. |
| 377 | let bytes: &[u8] = s.as_bytes(); |
| 378 | let len: usize = bytes.len(); |
| 379 | assert!( |
| 380 | !bytes.is_empty() && bytes[bytes.len() - 1] == b' \0' , |
| 381 | "string is not nul-terminated" |
| 382 | ); |
| 383 | let mut i: usize = 0; |
| 384 | let non_null_len: usize = len - 1; |
| 385 | while i < non_null_len { |
| 386 | assert!(bytes[i] != b' \0' , "string contains null bytes" ); |
| 387 | i += 1; |
| 388 | } |
| 389 | |
| 390 | unsafe { CStr::from_bytes_with_nul_unchecked(bytes) } |
| 391 | } |
| 392 | |
| 393 | use std::ffi::CStr; |
| 394 | |
| 395 | pub mod compat; |
| 396 | mod impl_; |
| 397 | |
| 398 | pub use self::abstract_::*; |
| 399 | pub use self::bltinmodule::*; |
| 400 | pub use self::boolobject::*; |
| 401 | pub use self::bytearrayobject::*; |
| 402 | pub use self::bytesobject::*; |
| 403 | pub use self::ceval::*; |
| 404 | #[cfg (Py_LIMITED_API)] |
| 405 | pub use self::code::*; |
| 406 | pub use self::codecs::*; |
| 407 | pub use self::compile::*; |
| 408 | pub use self::complexobject::*; |
| 409 | #[cfg (all(Py_3_8, not(Py_LIMITED_API)))] |
| 410 | pub use self::context::*; |
| 411 | #[cfg (not(Py_LIMITED_API))] |
| 412 | pub use self::datetime::*; |
| 413 | pub use self::descrobject::*; |
| 414 | pub use self::dictobject::*; |
| 415 | pub use self::enumobject::*; |
| 416 | pub use self::fileobject::*; |
| 417 | pub use self::fileutils::*; |
| 418 | pub use self::floatobject::*; |
| 419 | #[cfg (Py_3_9)] |
| 420 | pub use self::genericaliasobject::*; |
| 421 | pub use self::import::*; |
| 422 | pub use self::intrcheck::*; |
| 423 | pub use self::iterobject::*; |
| 424 | pub use self::listobject::*; |
| 425 | pub use self::longobject::*; |
| 426 | #[cfg (not(Py_LIMITED_API))] |
| 427 | pub use self::marshal::*; |
| 428 | pub use self::memoryobject::*; |
| 429 | pub use self::methodobject::*; |
| 430 | pub use self::modsupport::*; |
| 431 | pub use self::moduleobject::*; |
| 432 | pub use self::object::*; |
| 433 | pub use self::objimpl::*; |
| 434 | pub use self::osmodule::*; |
| 435 | #[cfg (not(any(PyPy, Py_LIMITED_API, Py_3_10)))] |
| 436 | pub use self::pyarena::*; |
| 437 | #[cfg (Py_3_11)] |
| 438 | pub use self::pybuffer::*; |
| 439 | pub use self::pycapsule::*; |
| 440 | pub use self::pyerrors::*; |
| 441 | pub use self::pyframe::*; |
| 442 | pub use self::pyhash::*; |
| 443 | pub use self::pylifecycle::*; |
| 444 | pub use self::pymem::*; |
| 445 | pub use self::pyport::*; |
| 446 | pub use self::pystate::*; |
| 447 | pub use self::pystrtod::*; |
| 448 | pub use self::pythonrun::*; |
| 449 | pub use self::rangeobject::*; |
| 450 | pub use self::setobject::*; |
| 451 | pub use self::sliceobject::*; |
| 452 | pub use self::structseq::*; |
| 453 | pub use self::sysmodule::*; |
| 454 | pub use self::traceback::*; |
| 455 | pub use self::tupleobject::*; |
| 456 | pub use self::typeslots::*; |
| 457 | pub use self::unicodeobject::*; |
| 458 | pub use self::warnings::*; |
| 459 | pub use self::weakrefobject::*; |
| 460 | |
| 461 | mod abstract_; |
| 462 | // skipped asdl.h |
| 463 | // skipped ast.h |
| 464 | mod bltinmodule; |
| 465 | mod boolobject; |
| 466 | mod bytearrayobject; |
| 467 | mod bytesobject; |
| 468 | // skipped cellobject.h |
| 469 | mod ceval; |
| 470 | // skipped classobject.h |
| 471 | #[cfg (Py_LIMITED_API)] |
| 472 | mod code; |
| 473 | mod codecs; |
| 474 | mod compile; |
| 475 | mod complexobject; |
| 476 | #[cfg (all(Py_3_8, not(Py_LIMITED_API)))] |
| 477 | mod context; // It's actually 3.7.1, but no cfg for patches. |
| 478 | #[cfg (not(Py_LIMITED_API))] |
| 479 | pub(crate) mod datetime; |
| 480 | mod descrobject; |
| 481 | mod dictobject; |
| 482 | // skipped dynamic_annotations.h |
| 483 | mod enumobject; |
| 484 | // skipped errcode.h |
| 485 | // skipped exports.h |
| 486 | mod fileobject; |
| 487 | mod fileutils; |
| 488 | mod floatobject; |
| 489 | // skipped empty frameobject.h |
| 490 | mod genericaliasobject; |
| 491 | mod import; |
| 492 | // skipped interpreteridobject.h |
| 493 | mod intrcheck; |
| 494 | mod iterobject; |
| 495 | mod listobject; |
| 496 | // skipped longintrepr.h |
| 497 | mod longobject; |
| 498 | #[cfg (not(Py_LIMITED_API))] |
| 499 | pub mod marshal; |
| 500 | mod memoryobject; |
| 501 | mod methodobject; |
| 502 | mod modsupport; |
| 503 | mod moduleobject; |
| 504 | // skipped namespaceobject.h |
| 505 | mod object; |
| 506 | mod objimpl; |
| 507 | // skipped odictobject.h |
| 508 | // skipped opcode.h |
| 509 | // skipped osdefs.h |
| 510 | mod osmodule; |
| 511 | // skipped parser_interface.h |
| 512 | // skipped patchlevel.h |
| 513 | // skipped picklebufobject.h |
| 514 | // skipped pyctype.h |
| 515 | // skipped py_curses.h |
| 516 | #[cfg (not(any(PyPy, Py_LIMITED_API, Py_3_10)))] |
| 517 | mod pyarena; |
| 518 | #[cfg (Py_3_11)] |
| 519 | mod pybuffer; |
| 520 | mod pycapsule; |
| 521 | // skipped pydtrace.h |
| 522 | mod pyerrors; |
| 523 | // skipped pyexpat.h |
| 524 | // skipped pyfpe.h |
| 525 | mod pyframe; |
| 526 | mod pyhash; |
| 527 | mod pylifecycle; |
| 528 | // skipped pymacconfig.h |
| 529 | // skipped pymacro.h |
| 530 | // skipped pymath.h |
| 531 | mod pymem; |
| 532 | mod pyport; |
| 533 | mod pystate; |
| 534 | // skipped pystats.h |
| 535 | mod pythonrun; |
| 536 | // skipped pystrhex.h |
| 537 | // skipped pystrcmp.h |
| 538 | mod pystrtod; |
| 539 | // skipped pythread.h |
| 540 | // skipped pytime.h |
| 541 | mod rangeobject; |
| 542 | mod setobject; |
| 543 | mod sliceobject; |
| 544 | mod structseq; |
| 545 | mod sysmodule; |
| 546 | mod traceback; |
| 547 | // skipped tracemalloc.h |
| 548 | mod tupleobject; |
| 549 | mod typeslots; |
| 550 | mod unicodeobject; |
| 551 | mod warnings; |
| 552 | mod weakrefobject; |
| 553 | |
| 554 | // Additional headers that are not exported by Python.h |
| 555 | #[deprecated (note = "Python 3.12" )] |
| 556 | pub mod structmember; |
| 557 | |
| 558 | // "Limited API" definitions matching Python's `include/cpython` directory. |
| 559 | #[cfg (not(Py_LIMITED_API))] |
| 560 | mod cpython; |
| 561 | |
| 562 | #[cfg (not(Py_LIMITED_API))] |
| 563 | pub use self::cpython::*; |
| 564 | |