Vendor deps.

This commit is contained in:
jimmy committed 2026-09-16 20:10:35 -04:00
1 parent 294527085e
commit 91e18fde3a
1714 files changed
+556667 -7

No files matched your search

+1
View File
@@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"039f415d5f61bb089f476da02570152921b93b8f041d2776f65f6bd4c100d07f","ACKNOWLEDGEMENTS":"417ebd38ebf3dfb26a3796b69b6f657215a81bd43032d0efa658515ebd5a9d21","Cargo.lock":"462608d22f721bcde65042c8acdf90e8dbcc0aaba7d2cd3a665751230efae5a7","Cargo.toml":"246de015ba73057315cb602fbc50f0b36fefb8bc4febb4bef54dce8301b15235","Cargo.toml.orig":"a0310fbf6673048715070bfb268026d4c14cc2976679510d85dbce71c24b617c","LICENSE-APACHE":"32c76dbe0e73d79100d5ece77c158399f2e2541bc5c78548a4ba45c1cb53c5c9","LICENSE-MIT":"afcbe3b2e6b37172b5a9ca869ee4c0b8cdc09316e5d4384864154482c33e5af6","README.md":"dd6839b7f554e51a96fa1dc7e5e330dc2fb86848f6e558ce1066c2241b37c59a","build.rs":"cbfa15e537070983f40b946a3d68bbcfb633af3c51a46ae610a6a4c5661f0765","examples/README.md":"598f11a10ce25ac2bd5cfa6311d53ea0595e8a7ee63cedbf94c92b8398e945ef","src/abstract_.rs":"e55baf2e316ed18cb38d91d9079831dcab49e235bd5ce59235cc2272bdb87956","src/bltinmodule.rs":"f8b5e223a10920756debeb3a85b98584050dc70b96aaa3cdc0a4d4056043671e","src/boolobject.rs":"e4db9ab5adc55b985bbb4ce81501b1359f8ede2c8e1e61935b297b38dfc88842","src/bytearrayobject.rs":"344b62759323eec72134dfdcdd7d5c8c2f814c88b3c90e96a02e95521d141c9d","src/bytesobject.rs":"c747c6a8b2a86133dfbaae191114aeda0e0b8e297643475eff0755d3a0ed9fe2","src/ceval.rs":"1b3f8a16754b962486a15e4dca70124644911150e50ca340a02de070cf75b357","src/codecs.rs":"c0f694fa3303438009435cc6fce4d746e3c07f3e5552fd0e18607d47cf0846c6","src/compat/mod.rs":"c17438ce8a051ae78fff5a9bf0c10a0b8dd762cb56dade7cc66c8690f5e80d97","src/compat/py_3_10.rs":"37f523e2febcb692e2caa0e14b8c3849629b4bb5f1061f48027149e58d82b9d6","src/compat/py_3_13.rs":"11398e75f09c998c50ee25134e6ea9390e8c204cc1a19fe8c13c6690e3a0cb40","src/compat/py_3_14.rs":"b0b68b108cca963de26747c2912f279376a10bcf8625977e437ce6da39dd874d","src/compat/py_3_15.rs":"990d28ec3ecae653244f350d2731517f10d1a212ecaa9506db1f1e41064e7b9f","src/compat/py_3_9.rs":"9e66c7623b18962d3f48f0d0150a6df9e1a3d01de86a776880be886a9b52ee3f","src/compile.rs":"021e3c5d871963a2131daf9b5df1aa92ff5d98f05117b5aa30084a3c833214da","src/complexobject.rs":"f70bcccd5f627483855d02d1153539e64e6cec3d1e6acbc3b631b398e6c39bfd","src/context.rs":"c2af1b0448077501d8109d5887dc318dc7dca5ebf0735dcd4fadc45ca9e37367","src/cpython/abstract_.rs":"d6c99359488e7cf340a9a742632b5cf59a34e275822b53bf7951bb970b5f59c1","src/cpython/bytearrayobject.rs":"d25ef262ed6bdda6965d51851bf1688c82f08fb323610917c5c9f985843d99b1","src/cpython/bytesobject.rs":"3737d7070a94d9c90cdedd4830d366dc7a465729b473fbed0eace9d6c8d76b21","src/cpython/cellobject.rs":"828add6165bd149c50536c8af66483374554c56bff4bc97201e22c3631423c31","src/cpython/ceval.rs":"a0e68e1ac57adbe372ba28b5b95f1a4c98a3da865fac3a938561ee00ae71a49e","src/cpython/code.rs":"62d9a0a73f8458dbcdbd9f9b2c79525565443ba6d6fff583077d321524763840","src/cpython/compile.rs":"e52c0dd125f91f2f5f00e17f8aced3e71ded3279454c94d881727f84cb1eeab2","src/cpython/complexobject.rs":"05df15f224ff1658e9c0ffc5d96803ae86218a0444729f819c2560e2322f29b7","src/cpython/critical_section.rs":"95748f8b9453e97c2e972336eb9af802ca8ec7211ba2be1828f6e224f3c38ead","src/cpython/descrobject.rs":"b16827457b8fadf2ddb5f9a6bc6e8a4ff96fd4bd0a5e0e7d3328e99c8ca7a547","src/cpython/dictobject.rs":"5b97cd13f8743f2c7fbc9642a3c654e328f0ffae2627fe4f1d9ae1ededd390b9","src/cpython/floatobject.rs":"4f2fc08244ba38eefb23a7bdceefaa6e8e06a0d9aa836fa1099315510577cb05","src/cpython/frameobject.rs":"c360ab503783c5c70b9b7353f165736ad7c73e04843f4631f3b87ecd300fcebd","src/cpython/funcobject.rs":"88752a9092da3157b1dacac2b3e1a0fb374206b16d963f8af80c6aeccde3d3ac","src/cpython/genobject.rs":"f49038b5ccddafd2f76e743b3c8b348d4364e25a0eb2867077564277cd7cb101","src/cpython/import.rs":"d1eefc11770d5880c98d9eeafd3db20e89052d097763eb9d26f0db505b95727e","src/cpython/initconfig.rs":"17e7c2a1c8508833a02cca1a7af28bc5130c34f2a031bfc08dca3140e3bd0546","src/cpython/listobject.rs":"fc914682189d84615e5a4887f18bac6d70fbea7957c6fd39ac816dd7858993ba","src/cpython/lock.rs":"124292ef80c2b6b66ccf6791775dccb487033dd4133ccd763b8ff991c956e3b0","src/cpython/longintrepr.rs":"a650a5eb187917de17f79f5233b18d76ea45aa1f1fe44bc06befee014c9f8746","src/cpython/longobject.rs":"5b5bb480ef42756462676d7615d0760302ebe213cfca92fb11e3a74dc3ef6809","src/cpython/marshal.rs":"fb732fcecde87bfd5e3aa09662b10855c4e6f758cd03b271aea217682d31bfb8","src/cpython/methodobject.rs":"955800c979658b52d9fd4aa0b800104788e91b65ecc665206344812659670b7b","src/cpython/mod.rs":"85df06d94d3c6cafd0681eb3d9dccc18b3a9b598ce7a92309e5699828cabee7a","src/cpython/object.rs":"677ddddf1331d4022fb121e10fca3c6307dbb94d10f04e33bd8d641c6fd07e3e","src/cpython/objimpl.rs":"a45474b699b6bc52ec72d9ec38c34ef2f6220da960b0ce5d63336ab182eb2949","src/cpython/pyatomic.rs":"4630ae7c572bad349146a28c6ccb5e0b38462579b07edfe78659fa4cdd4c35dc","src/cpython/pydebug.rs":"b20cef1c02466be5b6cbb0b25e1773c755d4cb6b049584a33113d6e581254a07","src/cpython/pyerrors.rs":"21cab54701badb7d1b0639aa9512e3ccd12c1cf30f83e7b7fbb6cf6c1015bff3","src/cpython/pyframe.rs":"6Line truncated
+6
View File
@@ -0,0 +1,6 @@
{
"git": {
"sha1": "a70d17f898df41b3d1632ee987f624f5222d8d39"
},
"path_in_vcs": "pyo3-ffi"
}
+6
View File
@@ -0,0 +1,6 @@
This is a Rust reimplementation of the CPython public header files as necessary
for binary compatibility, with additional metadata to support PyPy.
For original implementations please see:
- https://github.com/python/cpython
- https://github.com/pypy/pypy
Generated Vendored
+39
View File
@@ -0,0 +1,39 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "libc"
version = "0.2.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pyo3-build-config"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9"
dependencies = [
"target-lexicon",
]
[[package]]
name = "pyo3-ffi"
version = "0.29.2"
dependencies = [
"libc",
"paste",
"pyo3-build-config",
]
[[package]]
name = "target-lexicon"
version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
+121
View File
@@ -0,0 +1,121 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
rust-version = "1.83"
name = "pyo3-ffi"
version = "0.29.2"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
build = "build.rs"
links = "python"
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Python-API bindings for the PyO3 ecosystem"
homepage = "https://github.com/pyo3/pyo3"
readme = "README.md"
keywords = [
"pyo3",
"python",
"cpython",
"ffi",
]
categories = [
"api-bindings",
"development-tools::ffi",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/pyo3/pyo3"
[package.metadata.cpython]
min-version = "3.8"
max-version = "3.15"
[package.metadata.pypy]
min-version = "3.11"
max-version = "3.11"
[package.metadata.graalpy]
min-version = "3.12"
max-version = "3.13"
[features]
abi3 = []
abi3-py310 = ["abi3-py311"]
abi3-py311 = ["abi3-py312"]
abi3-py312 = ["abi3-py313"]
abi3-py313 = ["abi3-py314"]
abi3-py314 = ["abi3-py315"]
abi3-py315 = ["abi3"]
abi3-py38 = ["abi3-py39"]
abi3-py39 = ["abi3-py310"]
abi3t = []
abi3t-py315 = ["abi3t"]
default = []
extension-module = ["pyo3-build-config/extension-module"]
generate-import-lib = ["pyo3-build-config/generate-import-lib"]
[lib]
name = "pyo3_ffi"
path = "src/lib.rs"
[dependencies.libc]
version = "0.2.62"
[dev-dependencies.paste]
version = "1"
[build-dependencies.pyo3-build-config]
version = "=0.29.2"
[lints.clippy]
checked_conversions = "warn"
dbg_macro = "warn"
explicit_into_iter_loop = "warn"
explicit_iter_loop = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
let_unit_value = "warn"
manual_assert = "warn"
manual_ok_or = "warn"
todo = "warn"
undocumented_unsafe_blocks = "warn"
unnecessary_wraps = "warn"
used_underscore_binding = "warn"
useless_transmute = "warn"
[lints.rust]
elided_lifetimes_in_paths = "warn"
invalid_doc_attributes = "warn"
rust_2021_prelude_collisions = "warn"
unsafe_op_in_unsafe_fn = "warn"
unused_lifetimes = "warn"
[lints.rust.rust_2018_idioms]
level = "warn"
priority = -1
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = [
"cfg(pyo3_disable_reference_pool)",
"cfg(pyo3_leak_on_drop_without_reference_pool)",
"cfg(pyo3_use_raw_dylib)",
'cfg(pyo3_dll, values("python3", "python3_d", "python3t", "python3t_d", "python38", "python38_d", "python39", "python39_d", "python310", "python310_d", "python311", "python311_d", "python312", "python312_d", "python313", "python313_d", "python313t", "python313t_d", "python314", "python314_d", "python314t", "python314t_d", "python315", "python315_d", "python315t", "python315t_d", "python316", "python316_d", "python316t", "python316t_d", "libpypy3.11-c"))',
]
[lints.rustdoc]
bare_urls = "warn"
broken_intra_doc_links = "warn"
+63
View File
@@ -0,0 +1,63 @@
[package]
name = "pyo3-ffi"
version = "0.29.2"
description = "Python-API bindings for the PyO3 ecosystem"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"]
homepage = "https://github.com/pyo3/pyo3"
repository = "https://github.com/pyo3/pyo3"
categories = ["api-bindings", "development-tools::ffi"]
license = "MIT OR Apache-2.0"
edition = "2021"
links = "python"
rust-version.workspace = true
[dependencies]
libc = "0.2.62"
[features]
default = []
# Use the Python limited API. See https://www.python.org/dev/peps/pep-0384/ for more.
abi3 = []
# Use the Free-threaded Python limited API. See https://www.python.org/dev/peps/pep-0803/ for more.
abi3t = []
# With abi3, we can manually set the minimum Python version.
abi3-py38 = ["abi3-py39"]
abi3-py39 = ["abi3-py310"]
abi3-py310 = ["abi3-py311"]
abi3-py311 = ["abi3-py312"]
abi3-py312 = ["abi3-py313"]
abi3-py313 = ["abi3-py314"]
abi3-py314 = ["abi3-py315"]
abi3-py315 = ["abi3"]
abi3t-py315 = ["abi3t"]
# deprecated
extension-module = ["pyo3-build-config/extension-module"]
generate-import-lib = ["pyo3-build-config/generate-import-lib"]
[dev-dependencies]
paste = "1"
[build-dependencies]
pyo3-build-config = { path = "../pyo3-build-config", version = "=0.29.2" }
[lints]
workspace = true
[package.metadata.cpython]
min-version = "3.8"
max-version = "3.15" # inclusive
[package.metadata.pypy]
min-version = "3.11"
max-version = "3.11" # inclusive
[package.metadata.graalpy]
min-version = "3.12"
max-version = "3.13" # inclusive
+178
View File
@@ -0,0 +1,178 @@
Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
+25
View File
@@ -0,0 +1,25 @@
Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+286
View File
@@ -0,0 +1,286 @@
# pyo3-ffi
This crate provides [Rust](https://www.rust-lang.org/) FFI declarations for Python 3.
It supports both the stable and the unstable component of the ABI through the use of cfg flags.
Python Versions 3.8+ are supported.
It is meant for advanced users only - regular PyO3 users shouldn't
need to interact with this crate at all.
The contents of this crate are not documented here, as it would entail
basically copying the documentation from CPython. Consult the [Python/C API Reference
Manual][capi] for up-to-date documentation.
# Minimum supported Rust and Python versions
Requires Rust 1.83 or greater.
`pyo3-ffi` supports the following Python distributions:
- CPython 3.8 or greater
- PyPy 7.3 (Python 3.9+)
- GraalPy 24.0 or greater (Python 3.10+)
# Example: Building Python Native modules
PyO3 can be used to generate a native Python module. The easiest way to try this out for the
first time is to use [`maturin`]. `maturin` is a tool for building and publishing Rust-based
Python packages with minimal configuration. The following steps set up some files for an example
Python module, install `maturin`, and then show how to build and import the Python module.
First, create a new folder (let's call it `string_sum`) containing the following two files:
**`Cargo.toml`**
```toml
[lib]
name = "string_sum"
# "cdylib" is necessary to produce a shared library for Python to import from.
#
# Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
# to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
# crate-type = ["cdylib", "rlib"]
crate-type = ["cdylib"]
[dependencies]
pyo3-ffi = "0.29.2"
[build-dependencies]
# This is only necessary if you need to configure your build based on
# the Python version or the compile-time configuration for the interpreter.
pyo3_build_config = "0.29.2"
```
If you need to use conditional compilation based on Python version or how
Python was compiled, you need to add `pyo3-build-config` as a
`build-dependency` in your `Cargo.toml` as in the example above and either
create a new `build.rs` file or modify an existing one so that
`pyo3_build_config::use_pyo3_cfgs()` gets called at build time:
**`build.rs`**
```rust,ignore
fn main() {
pyo3_build_config::use_pyo3_cfgs()
}
```
**`src/lib.rs`**
```rust,no_run
#[cfg(Py_3_15)]
use std::ffi::c_void;
use std::ffi::{c_char, c_long};
use std::ptr;
use pyo3_ffi::*;
#[cfg(not(Py_3_15))]
static mut MODULE_DEF: PyModuleDef = PyModuleDef {
m_base: PyModuleDef_HEAD_INIT,
m_name: c"string_sum".as_ptr(),
m_doc: c"A Python module written in Rust.".as_ptr(),
m_size: 0,
m_methods: (&raw mut METHODS).cast(),
m_slots: (&raw mut SLOTS).cast(),
m_traverse: None,
m_clear: None,
m_free: None,
};
static mut METHODS: [PyMethodDef; 2] = [
PyMethodDef {
ml_name: c"sum_as_string".as_ptr(),
ml_meth: PyMethodDefPointer {
PyCFunctionFast: sum_as_string,
},
ml_flags: METH_FASTCALL,
ml_doc: c"returns the sum of two integers as a string".as_ptr(),
},
// A zeroed PyMethodDef to mark the end of the array.
PyMethodDef::zeroed(),
];
#[cfg(Py_3_15)]
PyABIInfo_VAR!(ABI_INFO);
const SLOTS_LEN: usize =
1 + cfg!(Py_3_12) as usize + cfg!(Py_GIL_DISABLED) as usize + 4 * (cfg!(Py_3_15) as usize);
static mut SLOTS: [PyModuleDef_Slot; SLOTS_LEN] = [
#[cfg(Py_3_15)]
PyModuleDef_Slot {
slot: Py_mod_abi,
value: (&raw mut ABI_INFO).cast(),
},
#[cfg(Py_3_15)]
PyModuleDef_Slot {
slot: Py_mod_name,
// safety: Python does not write to this field
value: c"string_sum".as_ptr() as *mut c_void,
},
#[cfg(Py_3_15)]
PyModuleDef_Slot {
slot: Py_mod_doc,
// safety: Python does not write to this field
value: c"A Python module written in Rust.".as_ptr() as *mut c_void,
},
#[cfg(Py_3_15)]
PyModuleDef_Slot {
slot: Py_mod_methods,
value: (&raw mut METHODS).cast(),
},
#[cfg(Py_3_12)]
PyModuleDef_Slot {
slot: Py_mod_multiple_interpreters,
value: Py_MOD_PER_INTERPRETER_GIL_SUPPORTED,
},
#[cfg(Py_GIL_DISABLED)]
PyModuleDef_Slot {
slot: Py_mod_gil,
value: Py_MOD_GIL_NOT_USED,
},
PyModuleDef_Slot {
slot: 0,
value: ptr::null_mut(),
},
];
// The module initialization function
#[cfg(not(Py_3_15))]
#[allow(non_snake_case, reason = "must be named `PyInit_<your_module>`")]
#[no_mangle]
pub unsafe extern "C" fn PyInit_string_sum() -> *mut PyObject {
PyModuleDef_Init(&raw mut MODULE_DEF)
}
#[cfg(Py_3_15)]
#[allow(non_snake_case, reason = "must be named `PyModExport_<your_module>`")]
#[no_mangle]
pub unsafe extern "C" fn PyModExport_string_sum() -> *mut PyModuleDef_Slot {
(&raw mut SLOTS).cast()
}
/// A helper to parse function arguments
/// If we used PyO3's proc macros they'd handle all of this boilerplate for us :)
unsafe fn parse_arg_as_i32(obj: *mut PyObject, n_arg: usize) -> Option<i32> {
if PyLong_Check(obj) == 0 {
let msg = format!(
"sum_as_string expected an int for positional argument {}\0",
n_arg
);
PyErr_SetString(PyExc_TypeError, msg.as_ptr().cast::<c_char>());
return None;
}
// Let's keep the behaviour consistent on platforms where `c_long` is bigger than 32 bits.
// In particular, it is an i32 on Windows but i64 on most Linux systems
let mut overflow = 0;
let i_long: c_long = PyLong_AsLongAndOverflow(obj, &mut overflow);
#[allow(
irrefutable_let_patterns,
reason = "some platforms have c_long equal to i32"
)]
if overflow != 0 {
raise_overflowerror(obj);
None
} else if let Ok(i) = i_long.try_into() {
Some(i)
} else {
raise_overflowerror(obj);
None
}
}
unsafe fn raise_overflowerror(obj: *mut PyObject) {
let obj_repr = PyObject_Str(obj);
if !obj_repr.is_null() {
let mut size = 0;
let p = PyUnicode_AsUTF8AndSize(obj_repr, &mut size);
if !p.is_null() {
let s = std::str::from_utf8_unchecked(std::slice::from_raw_parts(
p.cast::<u8>(),
size as usize,
));
let msg = format!("cannot fit {} in 32 bits\0", s);
PyErr_SetString(PyExc_OverflowError, msg.as_ptr().cast::<c_char>());
}
Py_DECREF(obj_repr);
}
}
pub unsafe extern "C" fn sum_as_string(
_self: *mut PyObject,
args: *mut *mut PyObject,
nargs: Py_ssize_t,
) -> *mut PyObject {
if nargs != 2 {
PyErr_SetString(
PyExc_TypeError,
c"sum_as_string expected 2 positional arguments".as_ptr(),
);
return std::ptr::null_mut();
}
let (first, second) = (*args, *args.add(1));
let first = match parse_arg_as_i32(first, 1) {
Some(x) => x,
None => return std::ptr::null_mut(),
};
let second = match parse_arg_as_i32(second, 2) {
Some(x) => x,
None => return std::ptr::null_mut(),
};
match first.checked_add(second) {
Some(sum) => {
let string = sum.to_string();
PyUnicode_FromStringAndSize(string.as_ptr().cast::<c_char>(), string.len() as isize)
}
None => {
PyErr_SetString(PyExc_OverflowError, c"arguments too large to add".as_ptr());
std::ptr::null_mut()
}
}
}
```
With those two files in place, now `maturin` needs to be installed. This can be done using
Python's package manager `pip`. First, load up a new Python `virtualenv`, and install `maturin`
into it:
```bash
$ cd string_sum
$ python -m venv .env
$ source .env/bin/activate
$ pip install maturin
```
Now build and execute the module:
```bash
$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
'25'
```
As well as with `maturin`, it is possible to build using [setuptools-rust] or
[manually][manual_builds]. Both offer more flexibility than `maturin` but require further
configuration.
While most projects use the safe wrapper provided by PyO3,
you can take a look at the [`orjson`] library as an example on how to use `pyo3-ffi` directly.
For those well versed in C and Rust the [tutorials] from the CPython documentation
can be easily converted to rust as well.
[tutorials]: https://docs.python.org/3/extending/
[`orjson`]: https://github.com/ijl/orjson
[capi]: https://docs.python.org/3/c-api/index.html
[`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"
[`pyo3-build-config`]: https://docs.rs/pyo3-build-config
[feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book"
[manual_builds]: https://pyo3.rs/latest/building-and-distribution.html#manual-builds "Manual builds - Building and Distribution - PyO3 user guide"
[setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions"
[PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI"
[Features chapter of the guide]: https://pyo3.rs/latest/features.html#features-reference "Features Reference - PyO3 user guide"
+369
View File
@@ -0,0 +1,369 @@
use pyo3_build_config::{
bail, ensure,
pyo3_build_script_impl::{
cargo_env_var, env_var, errors::Result, is_linking_libpython_for_target,
print_feature_cfgs, print_libpython_rpath_link_args, resolve_build_config,
target_triple_from_env, BuildConfig, BuildConfigSource, MaximumVersionExceeded,
},
warn, InterpreterConfig, PythonAbiKind, PythonImplementation, PythonVersion, StableAbi,
};
/// Minimum Python version PyO3 supports.
struct SupportedVersions {
min: PythonVersion,
max: PythonVersion,
}
const SUPPORTED_VERSIONS_CPYTHON: SupportedVersions = SupportedVersions {
min: PythonVersion { major: 3, minor: 8 },
max: PythonVersion {
major: 3,
minor: 15,
},
};
const SUPPORTED_VERSIONS_PYPY: SupportedVersions = SupportedVersions {
min: PythonVersion {
major: 3,
minor: 11,
},
max: SUPPORTED_VERSIONS_CPYTHON.max,
};
const SUPPORTED_VERSIONS_GRAALPY: SupportedVersions = SupportedVersions {
min: PythonVersion {
major: 3,
minor: 10,
},
max: SUPPORTED_VERSIONS_CPYTHON.max,
};
const MIN_FREE_THREADED_VERSION: PythonVersion = PythonVersion {
major: 3,
minor: 14,
};
const PY_3_15: PythonVersion = PythonVersion {
major: 3,
minor: 15,
};
fn ensure_python_version(interpreter_config: &InterpreterConfig) -> Result<()> {
// This is an undocumented env var which is only really intended to be used in CI / for testing
// and development.
if std::env::var("UNSAFE_PYO3_SKIP_VERSION_CHECK").as_deref() == Ok("1") {
return Ok(());
}
match interpreter_config.target_abi().implementation() {
PythonImplementation::CPython => {
let versions = SUPPORTED_VERSIONS_CPYTHON;
let interp_version = interpreter_config.target_abi().version();
ensure!(
interpreter_config.version() >= versions.min,
"the configured Python interpreter version ({}) is lower than PyO3's minimum supported version ({})",
interpreter_config.version(),
versions.min,
);
let v_plus_1 = PythonVersion {
major: versions.max.major,
minor: versions.max.minor + 1,
};
if interp_version == v_plus_1 {
warn!(
"Using experimental support for the Python {}.{} ABI. \
Build artifacts may not be compatible with the final release of CPython, \
so do not distribute them.",
v_plus_1.major, v_plus_1.minor,
);
} else if interp_version > v_plus_1 {
let mut error = MaximumVersionExceeded::new(interpreter_config, versions.max);
if interpreter_config.target_abi().kind().is_free_threaded() {
if interp_version >= PY_3_15 {
if env_var("PYO3_USE_STABLE_ABI_FORWARD_COMPATIBILITY")
.is_none_or(|os_str| os_str != "1")
{
error.add_help(
"set PYO3_USE_STABLE_ABI_FORWARD_COMPATIBILITY=1 to suppress this check and build anyway using the free-threaded stable ABI"
);
return Err(error.finish().into());
}
} else {
error.add_help(format!(
"the free-threaded build of CPython {}.{} does not support the limited API so this check cannot be suppressed.", interp_version.major, interp_version.minor
).as_str());
return Err(error.finish().into());
}
}
if env_var("PYO3_USE_ABI3_FORWARD_COMPATIBILITY").is_none_or(|os_str| os_str != "1")
&& env_var("PYO3_USE_STABLE_ABI_FORWARD_COMPATIBILITY")
.is_none_or(|os_str| os_str != "1")
{
error.add_help("set PYO3_USE_STABLE_ABI_FORWARD_COMPATIBILITY=1 to suppress this check and build anyway using the stable ABI");
return Err(error.finish().into());
}
}
if interpreter_config.target_abi().kind().is_free_threaded() {
ensure!(
interpreter_config.target_abi().version() >= MIN_FREE_THREADED_VERSION,
"PyO3 does not support the free-threaded build of CPython versions below {}, the selected Python version is {}",
MIN_FREE_THREADED_VERSION,
interpreter_config.target_abi().version(),
);
}
}
PythonImplementation::PyPy => {
let versions = SUPPORTED_VERSIONS_PYPY;
ensure!(
interpreter_config.target_abi().version() >= versions.min,
"the configured PyPy interpreter version ({}) is lower than PyO3's minimum supported version ({})",
interpreter_config.target_abi().version(),
versions.min,
);
// PyO3 does not support abi3, so we cannot offer forward compatibility
if interpreter_config.target_abi().version() > versions.max {
let error = MaximumVersionExceeded::new(interpreter_config, versions.max);
return Err(error.finish().into());
}
}
PythonImplementation::GraalPy => {
let versions = SUPPORTED_VERSIONS_GRAALPY;
ensure!(
interpreter_config.target_abi().version() >= versions.min,
"the configured GraalPy interpreter version ({}) is lower than PyO3's minimum supported version ({})",
interpreter_config.target_abi().version(),
versions.min,
);
// GraalPy does not support abi3, so we cannot offer forward compatibility
if interpreter_config.target_abi().version() > versions.max {
let error = MaximumVersionExceeded::new(interpreter_config, versions.max);
return Err(error.finish().into());
}
}
PythonImplementation::RustPython => {}
}
if let PythonAbiKind::Stable(abi) = interpreter_config.target_abi().kind() {
match interpreter_config.target_abi().implementation() {
PythonImplementation::CPython => match abi {
StableAbi::Abi3t => {
ensure!(
interpreter_config.target_abi().version() >= PY_3_15,
"Abi3t builds are not supported on CPython targets before Python 3.15"
)
}
StableAbi::Abi3 => {}
},
PythonImplementation::PyPy => warn!(
"PyPy does not yet support {abi} so the build artifacts will be version-specific. \
See https://github.com/pypy/pypy/issues/3397 for more information."
),
PythonImplementation::GraalPy => warn!(
"GraalPy does not support {abi} so the build artifacts will be version-specific."
),
PythonImplementation::RustPython => {}
}
}
Ok(())
}
fn ensure_target_pointer_width(interpreter_config: &InterpreterConfig) -> Result<()> {
if let Some(pointer_width) = interpreter_config.pointer_width() {
// Try to check whether the target architecture matches the python library
let rust_target = match cargo_env_var("CARGO_CFG_TARGET_POINTER_WIDTH")
.unwrap()
.as_str()
{
"64" => 64,
"32" => 32,
x => bail!("unexpected Rust target pointer width: {}", x),
};
ensure!(
rust_target == pointer_width,
"your Rust target architecture ({}-bit) does not match your python interpreter ({}-bit)",
rust_target,
pointer_width
);
}
Ok(())
}
/// `raw-dylib` currently does not support arbitrary names
/// (see https://internals.rust-lang.org/t/support-renames-with-link-name-kind-raw-dylib/24415)
/// so if the lib name is not one of the known subset, we must fall back to full linking.
fn lib_name_is_known_for_raw_dylib(lib_name: &str) -> bool {
// pyo3_dll cfg for raw-dylib linking on Windows
if matches!(
lib_name,
"python3" | "python3_d" | "python3t" | "python3t_d"
) {
return true;
}
// support raw-dylib linking for all CPython versions supported, plus the next prerelease
for i in SUPPORTED_VERSIONS_CPYTHON.min.minor..=SUPPORTED_VERSIONS_CPYTHON.max.minor + 1 {
if lib_name == format!("python3{i}") || lib_name == format!("python3{i}_d") {
return true;
}
if i >= 13 && (lib_name == format!("python3{i}t") || lib_name == format!("python3{i}t_d")) {
return true;
}
}
// PyPy DLL names (libpypy3.X-c.dll)
for i in SUPPORTED_VERSIONS_PYPY.min.minor..=SUPPORTED_VERSIONS_PYPY.max.minor {
if lib_name == format!("libpypy3.{i}-c") {
return true;
}
}
false
}
/// Whether to use raw-dylib linking.
///
/// Currently, this only applies if all of the following are true:
/// - The target OS is Windows.
/// - The Python library name is one of the [known subset][lib_name_is_known_for_raw_dylib].
/// - The `PYO3_USE_RAW_DYLIB` environment variable is not set, or is set to `1`.
///
/// NB in some cases (e.g. mixed C / Rust builds) it might be necessary to link the full Python
/// library rather than rely on the symbols which PyO3 defines as raw-dylib, which is why
/// we have the opt-out env var.
fn should_use_raw_dylib_linking(lib_name: &str) -> bool {
let target_os = cargo_env_var("CARGO_CFG_TARGET_OS").unwrap();
if target_os != "windows" {
return false;
}
match (
lib_name_is_known_for_raw_dylib(lib_name),
env_var("PYO3_USE_RAW_DYLIB"),
) {
(true, None) => true,
(true, Some(os_str)) if os_str == "1" => true,
(false, Some(os_str)) if os_str == "1" => {
warn!(
"PYO3_USE_RAW_DYLIB is set to 1 but the Python library name is not recognized. \
Falling back to full linking."
);
false
}
_ => false,
}
}
fn emit_link_config(build_config: &BuildConfig) -> Result<()> {
let target_os = cargo_env_var("CARGO_CFG_TARGET_OS").unwrap();
let interpreter_config = &build_config.interpreter_config;
let lib_name = interpreter_config
.lib_name()
.ok_or("attempted to link to Python shared library but config does not contain lib_name")?;
if should_use_raw_dylib_linking(lib_name) {
// Use raw-dylib linking: emit a cfg so that `extern_libpython!` picks the
// right `#[link(name = "...", kind = "raw-dylib")]` attribute at compile time.
// This eliminates the need for import libraries (.lib files) entirely.
//
// Note: raw-dylib is inherently dynamic linking. Static embedding of the
// Python interpreter on Windows is not supported by this path (and is not
// officially supported by CPython on Windows).
println!("cargo:rustc-cfg=pyo3_use_raw_dylib");
println!("cargo:rustc-cfg=pyo3_dll=\"{lib_name}\"");
return Ok(());
}
println!(
"cargo:rustc-link-lib={link_model}{alias}{lib_name}",
link_model = if interpreter_config.shared() {
""
} else {
"static="
},
// on windows we emit `#[link(name = "pythonXY")]` attributes
// and need this alias here to get the right name for the final link
alias = if target_os == "windows" {
"pythonXY:"
} else {
""
}
);
if let Some(lib_dir) = interpreter_config.lib_dir() {
println!("cargo:rustc-link-search=native={lib_dir}");
} else if matches!(build_config.source, BuildConfigSource::CrossCompile) {
warn!(
"The output binary will link to libpython, \
but PYO3_CROSS_LIB_DIR environment variable is not set. \
Ensure that the target Python library directory is \
in the rustc native library search path."
);
}
Ok(())
}
/// Prepares the PyO3 crate for compilation.
///
/// This uses pyo3-build-config implementation to detect the target Python interpreter and validate
/// it's suitable for building with.
///
/// Emits the cargo configuration based on this config as well as a few checks of the Rust compiler
/// version to enable features which aren't supported on MSRV.
fn configure_pyo3_ffi() -> Result<()> {
let target = target_triple_from_env();
let build_config = resolve_build_config(&target)?;
let interpreter_config = &build_config.interpreter_config;
if env_var("PYO3_PRINT_CONFIG").is_some_and(|os_str| os_str == "1") {
print_config_and_exit(interpreter_config);
}
ensure_python_version(interpreter_config)?;
ensure_target_pointer_width(interpreter_config)?;
// Serialize the whole interpreter config into DEP_PYTHON_PYO3_CONFIG env var.
interpreter_config.to_cargo_dep_env()?;
if is_linking_libpython_for_target(&target)
&& !interpreter_config.suppress_build_script_link_lines()
{
emit_link_config(&build_config)?;
}
for cfg in interpreter_config.build_script_outputs() {
println!("{cfg}")
}
// Extra lines come last, to support last write wins.
for line in interpreter_config.extra_build_script_lines() {
println!("{line}");
}
print_feature_cfgs();
// Make `cargo test` etc work with non-system Python installations
print_libpython_rpath_link_args(&target, interpreter_config);
Ok(())
}
fn print_config_and_exit(config: &InterpreterConfig) {
println!("\n-- PYO3_PRINT_CONFIG=1 is set, printing configuration and halting compile --");
config
.to_writer(std::io::stdout())
.expect("failed to print config to stdout");
println!("\nnote: unset the PYO3_PRINT_CONFIG environment variable and retry to compile with the above config");
std::process::exit(101);
}
fn main() {
pyo3_build_config::print_expected_cfgs();
if let Err(e) = configure_pyo3_ffi() {
eprintln!("error: {}", e.report());
std::process::exit(1)
}
}
+21
View File
@@ -0,0 +1,21 @@
# `pyo3-ffi` Examples
These example crates are a collection of toy extension modules built with
`pyo3-ffi`. They are all tested using `nox` in PyO3's CI.
Below is a brief description of each of these:
| Example | Description |
| `word-count` | Illustrates how to use pyo3-ffi to write a static rust extension |
| `sequential` | Illustrates how to use pyo3-ffi to write subinterpreter-safe modules using multi-phase module initialization |
## Creating new projects from these examples
To copy an example, use [`cargo-generate`](https://crates.io/crates/cargo-generate). Follow the commands below, replacing `<example>` with the example to start from:
```bash
$ cargo install cargo-generate
$ cargo generate --git https://github.com/PyO3/pyo3 examples/<example>
```
(`cargo generate` will take a little while to clone the PyO3 repo first; be patient when waiting for the command to run.)
+354
View File
@@ -0,0 +1,354 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_int};
#[cfg(any(Py_3_12, not(Py_LIMITED_API)))]
use libc::size_t;
#[inline]
#[cfg(all(
not(Py_3_13), // CPython exposed as a function in 3.13, in object.h
not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+
))]
pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) -> c_int {
PyObject_SetAttrString(o, attr_name, core::ptr::null_mut())
}
#[inline]
#[cfg(all(
not(Py_3_13), // CPython exposed as a function in 3.13, in object.h
not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+
))]
pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_int {
PyObject_SetAttr(o, attr_name, core::ptr::null_mut())
}
extern_libpython! {
#[cfg(all(
not(PyPy),
any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10
))]
#[cfg_attr(PyPy, link_name = "PyPyObject_CallNoArgs")]
pub fn PyObject_CallNoArgs(func: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_Call")]
pub fn PyObject_Call(
callable_object: *mut PyObject,
args: *mut PyObject,
kw: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_CallObject")]
pub fn PyObject_CallObject(
callable_object: *mut PyObject,
args: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_CallFunction")]
pub fn PyObject_CallFunction(
callable_object: *mut PyObject,
format: *const c_char,
...
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_CallMethod")]
pub fn PyObject_CallMethod(
o: *mut PyObject,
method: *const c_char,
format: *const c_char,
...
) -> *mut PyObject;
#[cfg(all(PyPy, not(Py_3_13)))] // called internally in PyUnicodeDecodeError_Create on PyPy
#[cfg_attr(PyPy, link_name = "_PyPyObject_CallFunction_SizeT")]
pub(crate) fn _PyObject_CallFunction_SizeT(
callable_object: *mut PyObject,
format: *const c_char,
...
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_CallFunctionObjArgs")]
pub fn PyObject_CallFunctionObjArgs(callable: *mut PyObject, ...) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_CallMethodObjArgs")]
pub fn PyObject_CallMethodObjArgs(
o: *mut PyObject,
method: *mut PyObject,
...
) -> *mut PyObject;
#[cfg(all(Py_3_12, Py_LIMITED_API))] // is an inline function in cpython/abstract.rs on version-specific ABI
#[cfg_attr(PyPy, link_name = "PyPyVectorcall_NARGS")]
pub fn PyVectorcall_NARGS(nargsf: size_t) -> Py_ssize_t;
#[cfg_attr(not(any(Py_3_12, PyPy)), link_name = "_PyVectorcall_Call")] // symbol made public in 3.12
#[cfg_attr(PyPy, link_name = "PyPyVectorcall_Call")]
pub fn PyVectorcall_Call(
callable: *mut PyObject,
tuple: *mut PyObject,
dict: *mut PyObject,
) -> *mut PyObject;
}
#[cfg(any(Py_3_12, not(Py_LIMITED_API)))]
pub const PY_VECTORCALL_ARGUMENTS_OFFSET: size_t = (1 as size_t)
.checked_shl((8 * core::mem::size_of::<size_t>() - 1) as u32)
.expect("size_t should fit the flag bits");
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyObject_Vectorcall")]
#[cfg(any(Py_3_12, all(Py_3_11, not(Py_LIMITED_API))))]
pub fn PyObject_Vectorcall(
callable: *mut PyObject,
args: *const *mut PyObject,
nargsf: size_t,
kwnames: *mut PyObject,
) -> *mut PyObject;
#[cfg(any(Py_3_12, all(Py_3_9, not(any(Py_LIMITED_API, PyPy)))))]
pub fn PyObject_VectorcallMethod(
name: *mut PyObject,
args: *const *mut PyObject,
nargsf: size_t,
kwnames: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_Type")]
pub fn PyObject_Type(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_Size")]
pub fn PyObject_Size(o: *mut PyObject) -> Py_ssize_t;
// PyObject_Length is a direct alias for PyObject_Size
#[cfg_attr(not(PyPy), link_name = "PyObject_Size")]
#[cfg_attr(PyPy, link_name = "PyPyObject_Size")]
pub fn PyObject_Length(o: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyObject_GetItem")]
pub fn PyObject_GetItem(o: *mut PyObject, key: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_SetItem")]
pub fn PyObject_SetItem(o: *mut PyObject, key: *mut PyObject, v: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_DelItemString")]
pub fn PyObject_DelItemString(o: *mut PyObject, key: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_DelItem")]
pub fn PyObject_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_Format")]
pub fn PyObject_Format(obj: *mut PyObject, format_spec: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_GetIter")]
pub fn PyObject_GetIter(arg1: *mut PyObject) -> *mut PyObject;
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyObject_GetAIter")]
pub fn PyObject_GetAIter(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyIter_Check")]
pub fn PyIter_Check(obj: *mut PyObject) -> c_int;
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyAIter_Check")]
pub fn PyAIter_Check(obj: *mut PyObject) -> c_int;
#[cfg(Py_3_14)]
#[cfg_attr(PyPy, link_name = "PyPyIter_NextItem")]
pub fn PyIter_NextItem(iter: *mut PyObject, item: *mut *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyIter_Next")]
pub fn PyIter_Next(arg1: *mut PyObject) -> *mut PyObject;
#[cfg(all(not(PyPy), Py_3_10))]
#[cfg_attr(PyPy, link_name = "PyPyIter_Send")]
pub fn PyIter_Send(
iter: *mut PyObject,
arg: *mut PyObject,
presult: *mut *mut PyObject,
) -> PySendResult;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Check")]
pub fn PyNumber_Check(o: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Add")]
pub fn PyNumber_Add(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Subtract")]
pub fn PyNumber_Subtract(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Multiply")]
pub fn PyNumber_Multiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_MatrixMultiply")]
pub fn PyNumber_MatrixMultiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_FloorDivide")]
pub fn PyNumber_FloorDivide(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_TrueDivide")]
pub fn PyNumber_TrueDivide(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Remainder")]
pub fn PyNumber_Remainder(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Divmod")]
pub fn PyNumber_Divmod(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Power")]
pub fn PyNumber_Power(o1: *mut PyObject, o2: *mut PyObject, o3: *mut PyObject)
-> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Negative")]
pub fn PyNumber_Negative(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Positive")]
pub fn PyNumber_Positive(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Absolute")]
pub fn PyNumber_Absolute(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Invert")]
pub fn PyNumber_Invert(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Lshift")]
pub fn PyNumber_Lshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Rshift")]
pub fn PyNumber_Rshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_And")]
pub fn PyNumber_And(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Xor")]
pub fn PyNumber_Xor(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Or")]
pub fn PyNumber_Or(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyIndex_Check")]
pub fn PyIndex_Check(o: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Index")]
pub fn PyNumber_Index(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_AsSsize_t")]
pub fn PyNumber_AsSsize_t(o: *mut PyObject, exc: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Long")]
pub fn PyNumber_Long(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_Float")]
pub fn PyNumber_Float(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceAdd")]
pub fn PyNumber_InPlaceAdd(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceSubtract")]
pub fn PyNumber_InPlaceSubtract(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceMultiply")]
pub fn PyNumber_InPlaceMultiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceMatrixMultiply")]
pub fn PyNumber_InPlaceMatrixMultiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceFloorDivide")]
pub fn PyNumber_InPlaceFloorDivide(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceTrueDivide")]
pub fn PyNumber_InPlaceTrueDivide(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceRemainder")]
pub fn PyNumber_InPlaceRemainder(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlacePower")]
pub fn PyNumber_InPlacePower(
o1: *mut PyObject,
o2: *mut PyObject,
o3: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceLshift")]
pub fn PyNumber_InPlaceLshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceRshift")]
pub fn PyNumber_InPlaceRshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceAnd")]
pub fn PyNumber_InPlaceAnd(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceXor")]
pub fn PyNumber_InPlaceXor(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyNumber_InPlaceOr")]
pub fn PyNumber_InPlaceOr(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
pub fn PyNumber_ToBase(n: *mut PyObject, base: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySequence_Check")]
pub fn PySequence_Check(o: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySequence_Size")]
pub fn PySequence_Size(o: *mut PyObject) -> Py_ssize_t;
// PySequence_Length is a direct alias for PySequence_Size
#[cfg_attr(not(PyPy), link_name = "PySequence_Size")]
#[cfg_attr(PyPy, link_name = "PyPySequence_Size")]
pub fn PySequence_Length(o: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPySequence_Concat")]
pub fn PySequence_Concat(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySequence_Repeat")]
pub fn PySequence_Repeat(o: *mut PyObject, count: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySequence_GetItem")]
pub fn PySequence_GetItem(o: *mut PyObject, i: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySequence_GetSlice")]
pub fn PySequence_GetSlice(o: *mut PyObject, i1: Py_ssize_t, i2: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySequence_SetItem")]
pub fn PySequence_SetItem(o: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySequence_DelItem")]
pub fn PySequence_DelItem(o: *mut PyObject, i: Py_ssize_t) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySequence_SetSlice")]
pub fn PySequence_SetSlice(
o: *mut PyObject,
i1: Py_ssize_t,
i2: Py_ssize_t,
v: *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySequence_DelSlice")]
pub fn PySequence_DelSlice(o: *mut PyObject, i1: Py_ssize_t, i2: Py_ssize_t) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySequence_Tuple")]
pub fn PySequence_Tuple(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySequence_List")]
pub fn PySequence_List(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySequence_Fast")]
pub fn PySequence_Fast(o: *mut PyObject, m: *const c_char) -> *mut PyObject;
pub fn PySequence_Count(o: *mut PyObject, value: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPySequence_Contains")]
pub fn PySequence_Contains(seq: *mut PyObject, ob: *mut PyObject) -> c_int;
// PySequence_In is a direct alias for PySequence_Contains
#[cfg_attr(not(PyPy), link_name = "PySequence_Contains")]
#[cfg_attr(PyPy, link_name = "PyPySequence_Contains")]
pub fn PySequence_In(o: *mut PyObject, value: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySequence_Index")]
pub fn PySequence_Index(o: *mut PyObject, value: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPySequence_InPlaceConcat")]
pub fn PySequence_InPlaceConcat(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySequence_InPlaceRepeat")]
pub fn PySequence_InPlaceRepeat(o: *mut PyObject, count: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyMapping_Check")]
pub fn PyMapping_Check(o: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyMapping_Size")]
pub fn PyMapping_Size(o: *mut PyObject) -> Py_ssize_t;
// PyMapping_Length is a direct alias for PyMapping_Size
#[cfg_attr(not(PyPy), link_name = "PyMapping_Size")]
#[cfg_attr(PyPy, link_name = "PyPyMapping_Size")]
pub fn PyMapping_Length(o: *mut PyObject) -> Py_ssize_t;
}
#[inline]
pub unsafe fn PyMapping_DelItemString(o: *mut PyObject, key: *mut c_char) -> c_int {
PyObject_DelItemString(o, key)
}
#[inline]
pub unsafe fn PyMapping_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int {
PyObject_DelItem(o, key)
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyString")]
pub fn PyMapping_HasKeyString(o: *mut PyObject, key: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyMapping_HasKey")]
pub fn PyMapping_HasKey(o: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyWithError")]
pub fn PyMapping_HasKeyWithError(o: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyStringWithError")]
pub fn PyMapping_HasKeyStringWithError(o: *mut PyObject, key: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyMapping_Keys")]
pub fn PyMapping_Keys(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyMapping_Values")]
pub fn PyMapping_Values(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyMapping_Items")]
pub fn PyMapping_Items(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyMapping_GetItemString")]
pub fn PyMapping_GetItemString(o: *mut PyObject, key: *const c_char) -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyMapping_GetOptionalItem")]
pub fn PyMapping_GetOptionalItem(
o: *mut PyObject,
key: *mut PyObject,
result: *mut *mut PyObject,
) -> c_int;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyMapping_GetOptionalItemString")]
pub fn PyMapping_GetOptionalItemString(
o: *mut PyObject,
key: *const c_char,
result: *mut *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyMapping_SetItemString")]
pub fn PyMapping_SetItemString(
o: *mut PyObject,
key: *const c_char,
value: *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_IsInstance")]
pub fn PyObject_IsInstance(object: *mut PyObject, typeorclass: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_IsSubclass")]
pub fn PyObject_IsSubclass(object: *mut PyObject, typeorclass: *mut PyObject) -> c_int;
}
+7
View File
@@ -0,0 +1,7 @@
use crate::object::PyTypeObject;
extern_libpython! {
pub static mut PyFilter_Type: PyTypeObject;
pub static mut PyMap_Type: PyTypeObject;
pub static mut PyZip_Type: PyTypeObject;
}
+69
View File
@@ -0,0 +1,69 @@
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
use crate::longobject::PyLongObject;
use crate::object::*;
use core::ffi::{c_int, c_long};
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyBool_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyBool_Check(op: *mut PyObject) -> c_int;
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "_PyPy_FalseStruct")]
static mut _Py_FalseStruct: PyLongObject;
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "_PyPy_TrueStruct")]
static mut _Py_TrueStruct: PyLongObject;
#[cfg(GraalPy)]
static mut _Py_FalseStructReference: *mut PyObject;
#[cfg(GraalPy)]
static mut _Py_TrueStructReference: *mut PyObject;
}
#[inline]
pub unsafe fn Py_False() -> *mut PyObject {
#[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))]
return Py_GetConstantBorrowed(Py_CONSTANT_FALSE);
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
return (&raw mut _Py_FalseStruct).cast();
#[cfg(GraalPy)]
return _Py_FalseStructReference;
}
#[inline]
pub unsafe fn Py_True() -> *mut PyObject {
#[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))]
return Py_GetConstantBorrowed(Py_CONSTANT_TRUE);
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
return (&raw mut _Py_TrueStruct).cast();
#[cfg(GraalPy)]
return _Py_TrueStructReference;
}
#[inline]
pub unsafe fn Py_IsTrue(x: *mut PyObject) -> c_int {
Py_Is(x, Py_True())
}
#[inline]
pub unsafe fn Py_IsFalse(x: *mut PyObject) -> c_int {
Py_Is(x, Py_False())
}
// skipped Py_RETURN_TRUE
// skipped Py_RETURN_FALSE
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyBool_FromLong")]
pub fn PyBool_FromLong(arg1: c_long) -> *mut PyObject;
}
+43
View File
@@ -0,0 +1,43 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_int};
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyByteArray_Type")]
pub static mut PyByteArray_Type: PyTypeObject;
pub static mut PyByteArrayIter_Type: PyTypeObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyByteArray_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyByteArray_Type)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyByteArray_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyByteArray_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyByteArray_FromObject")]
pub fn PyByteArray_FromObject(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyByteArray_Concat")]
pub fn PyByteArray_Concat(a: *mut PyObject, b: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyByteArray_FromStringAndSize")]
pub fn PyByteArray_FromStringAndSize(string: *const c_char, len: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyByteArray_Size")]
pub fn PyByteArray_Size(bytearray: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyByteArray_AsString")]
pub fn PyByteArray_AsString(bytearray: *mut PyObject) -> *mut c_char;
#[cfg_attr(PyPy, link_name = "PyPyByteArray_Resize")]
pub fn PyByteArray_Resize(bytearray: *mut PyObject, len: Py_ssize_t) -> c_int;
}
+69
View File
@@ -0,0 +1,69 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_int};
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyBytes_Type")]
pub static mut PyBytes_Type: PyTypeObject;
pub static mut PyBytesIter_Type: PyTypeObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyBytes_Check(op: *mut PyObject) -> c_int {
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyBytes_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyBytes_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyBytes_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyBytes_CheckExact(op: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBytes_FromStringAndSize")]
pub fn PyBytes_FromStringAndSize(arg1: *const c_char, arg2: Py_ssize_t) -> *mut PyObject;
pub fn PyBytes_FromString(arg1: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyBytes_FromObject")]
pub fn PyBytes_FromObject(arg1: *mut PyObject) -> *mut PyObject;
// skipped PyBytes_FromFormatV
//#[cfg_attr(PyPy, link_name = "PyPyBytes_FromFormatV")]
//pub fn PyBytes_FromFormatV(arg1: *const c_char, arg2: va_list)
// -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyBytes_FromFormat")]
pub fn PyBytes_FromFormat(arg1: *const c_char, ...) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyBytes_Size")]
pub fn PyBytes_Size(arg1: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyBytes_AsString")]
pub fn PyBytes_AsString(arg1: *mut PyObject) -> *mut c_char;
pub fn PyBytes_Repr(arg1: *mut PyObject, arg2: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyBytes_Concat")]
pub fn PyBytes_Concat(arg1: *mut *mut PyObject, arg2: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyBytes_ConcatAndDel")]
pub fn PyBytes_ConcatAndDel(arg1: *mut *mut PyObject, arg2: *mut PyObject);
pub fn PyBytes_DecodeEscape(
arg1: *const c_char,
arg2: Py_ssize_t,
arg3: *const c_char,
arg4: Py_ssize_t,
arg5: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyBytes_AsStringAndSize")]
pub fn PyBytes_AsStringAndSize(
obj: *mut PyObject,
s: *mut *mut c_char,
len: *mut Py_ssize_t,
) -> c_int;
}
// skipped F_LJUST
// skipped F_SIGN
// skipped F_BLANK
// skipped F_ALT
// skipped F_ZERO
+179
View File
@@ -0,0 +1,179 @@
use crate::object::PyObject;
use crate::pytypedefs::PyThreadState;
use core::ffi::{c_char, c_int, c_void};
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyEval_EvalCode")]
pub fn PyEval_EvalCode(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *mut PyObject,
) -> *mut PyObject;
pub fn PyEval_EvalCodeEx(
co: *mut PyObject,
globals: *mut PyObject,
locals: *mut PyObject,
args: *const *mut PyObject,
argc: c_int,
kwds: *const *mut PyObject,
kwdc: c_int,
defs: *const *mut PyObject,
defc: c_int,
kwdefs: *mut PyObject,
closure: *mut PyObject,
) -> *mut PyObject;
#[cfg(not(Py_3_13))]
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
#[cfg_attr(PyPy, link_name = "PyPyEval_CallObjectWithKeywords")]
pub fn PyEval_CallObjectWithKeywords(
func: *mut PyObject,
obj: *mut PyObject,
kwargs: *mut PyObject,
) -> *mut PyObject;
}
#[cfg(not(Py_3_13))]
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
#[inline]
pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject {
#[allow(deprecated)]
PyEval_CallObjectWithKeywords(func, arg, core::ptr::null_mut())
}
extern_libpython! {
#[cfg(not(Py_3_13))]
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
#[cfg_attr(PyPy, link_name = "PyPyEval_CallFunction")]
pub fn PyEval_CallFunction(obj: *mut PyObject, format: *const c_char, ...) -> *mut PyObject;
#[cfg(not(Py_3_13))]
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
#[cfg_attr(PyPy, link_name = "PyPyEval_CallMethod")]
pub fn PyEval_CallMethod(
obj: *mut PyObject,
methodname: *const c_char,
format: *const c_char,
...
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_GetBuiltins")]
pub fn PyEval_GetBuiltins() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_GetGlobals")]
pub fn PyEval_GetGlobals() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_GetLocals")]
pub fn PyEval_GetLocals() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_GetFrame")]
pub fn PyEval_GetFrame() -> *mut crate::PyFrameObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyEval_GetFrameBuiltins")]
pub fn PyEval_GetFrameBuiltins() -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyEval_GetFrameGlobals")]
pub fn PyEval_GetFrameGlobals() -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyEval_GetFrameLocals")]
pub fn PyEval_GetFrameLocals() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPy_AddPendingCall")]
pub fn Py_AddPendingCall(
func: Option<extern "C" fn(arg1: *mut c_void) -> c_int>,
arg: *mut c_void,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPy_MakePendingCalls")]
pub fn Py_MakePendingCalls() -> c_int;
#[cfg_attr(PyPy, link_name = "PyPy_SetRecursionLimit")]
pub fn Py_SetRecursionLimit(arg1: c_int);
#[cfg_attr(PyPy, link_name = "PyPy_GetRecursionLimit")]
pub fn Py_GetRecursionLimit() -> c_int;
#[cfg(Py_3_9)]
#[cfg_attr(PyPy, link_name = "PyPy_EnterRecursiveCall")]
pub fn Py_EnterRecursiveCall(arg1: *const c_char) -> c_int;
#[cfg(Py_3_9)]
#[cfg_attr(PyPy, link_name = "PyPy_LeaveRecursiveCall")]
pub fn Py_LeaveRecursiveCall();
#[cfg_attr(PyPy, link_name = "PyPyEval_GetFuncName")]
pub fn PyEval_GetFuncName(arg1: *mut PyObject) -> *const c_char;
#[cfg_attr(PyPy, link_name = "PyPyEval_GetFuncDesc")]
pub fn PyEval_GetFuncDesc(arg1: *mut PyObject) -> *const c_char;
#[cfg_attr(PyPy, link_name = "PyPyEval_EvalFrame")]
pub fn PyEval_EvalFrame(arg1: *mut crate::PyFrameObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_EvalFrameEx")]
pub fn PyEval_EvalFrameEx(f: *mut crate::PyFrameObject, exc: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_SaveThread")]
pub fn PyEval_SaveThread() -> *mut PyThreadState;
#[cfg(not(Py_3_13))]
#[cfg_attr(PyPy, link_name = "PyPyEval_ThreadsInitialized")]
#[cfg_attr(
Py_3_9,
deprecated(
note = "Deprecated in Python 3.9, this function always returns true in Python 3.7 or newer."
)
)]
pub fn PyEval_ThreadsInitialized() -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyEval_InitThreads")]
#[cfg_attr(
Py_3_9,
deprecated(
note = "Deprecated in Python 3.9, this function does nothing in Python 3.7 or newer."
)
)]
pub fn PyEval_InitThreads();
#[cfg(not(Py_3_13))]
#[deprecated(note = "Deprecated in Python 3.2")]
pub fn PyEval_AcquireLock();
#[cfg(not(Py_3_13))]
#[deprecated(note = "Deprecated in Python 3.2")]
pub fn PyEval_ReleaseLock();
#[cfg_attr(PyPy, link_name = "PyPyEval_AcquireThread")]
pub fn PyEval_AcquireThread(tstate: *mut PyThreadState);
#[cfg_attr(PyPy, link_name = "PyPyEval_ReleaseThread")]
pub fn PyEval_ReleaseThread(tstate: *mut PyThreadState);
}
// PyEval_RestoreThread calls take_gil, which calls pthread_exit on non-main threads
// during interpreter finalization on Python < 3.14. Redirect to the "safe" version that hangs instead,
// as Python 3.14 does.
// See https://github.com/rust-lang/rust/issues/135929
// C-unwind only supported (and necessary) since 1.71. Python 3.14+ does not do
// pthread_exit from PyEval_RestoreThread (https://github.com/python/cpython/issues/87135).
#[cfg(not(any(Py_3_14, target_arch = "wasm32")))]
mod raw {
use crate::pytypedefs::PyThreadState;
extern_libpython! { "C-unwind" {
#[cfg_attr(PyPy, link_name = "PyPyEval_RestoreThread")]
pub fn PyEval_RestoreThread(tstate: *mut PyThreadState);
}}
}
#[cfg(any(Py_3_14, target_arch = "wasm32"))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyEval_RestoreThread")]
pub fn PyEval_RestoreThread(tstate: *mut PyThreadState);
}
#[cfg(not(any(Py_3_14, target_arch = "wasm32")))]
pub unsafe extern "C" fn PyEval_RestoreThread(tstate: *mut PyThreadState) {
// Same note as in PyGILState_Ensure
let guard = crate::impl_::HangThread;
raw::PyEval_RestoreThread(tstate);
core::mem::forget(guard);
}
// skipped Py_BEGIN_ALLOW_THREADS
// skipped Py_BLOCK_THREADS
// skipped Py_UNBLOCK_THREADS
// skipped Py_END_ALLOW_THREADS
// skipped FVC_MASK
// skipped FVC_NONE
// skipped FVC_STR
// skipped FVC_REPR
// skipped FVC_ASCII
// skipped FVS_MASK
// skipped FVS_HAVE_SPEC
+58
View File
@@ -0,0 +1,58 @@
use crate::object::PyObject;
use core::ffi::{c_char, c_int};
extern_libpython! {
pub fn PyCodec_Register(search_function: *mut PyObject) -> c_int;
#[cfg(Py_3_10)]
#[cfg(not(PyPy))]
pub fn PyCodec_Unregister(search_function: *mut PyObject) -> c_int;
// skipped non-limited _PyCodec_Lookup from Include/codecs.h
// skipped non-limited _PyCodec_Forget from Include/codecs.h
pub fn PyCodec_KnownEncoding(encoding: *const c_char) -> c_int;
pub fn PyCodec_Encode(
object: *mut PyObject,
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
pub fn PyCodec_Decode(
object: *mut PyObject,
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
// skipped non-limited _PyCodec_LookupTextEncoding from Include/codecs.h
// skipped non-limited _PyCodec_EncodeText from Include/codecs.h
// skipped non-limited _PyCodec_DecodeText from Include/codecs.h
// skipped non-limited _PyCodecInfo_GetIncrementalDecoder from Include/codecs.h
// skipped non-limited _PyCodecInfo_GetIncrementalEncoder from Include/codecs.h
pub fn PyCodec_Encoder(encoding: *const c_char) -> *mut PyObject;
pub fn PyCodec_Decoder(encoding: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyCodec_IncrementalEncoder")]
pub fn PyCodec_IncrementalEncoder(
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyCodec_IncrementalDecoder")]
pub fn PyCodec_IncrementalDecoder(
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
pub fn PyCodec_StreamReader(
encoding: *const c_char,
stream: *mut PyObject,
errors: *const c_char,
) -> *mut PyObject;
pub fn PyCodec_StreamWriter(
encoding: *const c_char,
stream: *mut PyObject,
errors: *const c_char,
) -> *mut PyObject;
pub fn PyCodec_RegisterError(name: *const c_char, error: *mut PyObject) -> c_int;
pub fn PyCodec_LookupError(name: *const c_char) -> *mut PyObject;
pub fn PyCodec_StrictErrors(exc: *mut PyObject) -> *mut PyObject;
pub fn PyCodec_IgnoreErrors(exc: *mut PyObject) -> *mut PyObject;
pub fn PyCodec_ReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
pub fn PyCodec_XMLCharRefReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
pub fn PyCodec_BackslashReplaceErrors(exc: *mut PyObject) -> *mut PyObject;
// skipped non-limited PyCodec_NameReplaceErrors from Include/codecs.h
// skipped non-limited Py_hexdigits from Include/codecs.h
}
+64
View File
@@ -0,0 +1,64 @@
//! C API Compatibility Shims
//!
//! Some CPython C API functions added in recent versions of Python are
//! inherently safer to use than older C API constructs. This module
//! exposes functions available on all Python versions that wrap the
//! old C API on old Python versions and wrap the function directly
//! on newer Python versions.
// Unless otherwise noted, the compatibility shims are adapted from
// the pythoncapi-compat project: https://github.com/python/pythoncapi-compat
/// Internal helper macro which defines compatibility shims for C API functions, deferring to a
/// re-export when that's available.
macro_rules! compat_function {
(
originally_defined_for($cfg:meta);
$(#[$attrs:meta])*
pub unsafe fn $name:ident($($arg_names:ident: $arg_types:ty),* $(,)?) -> $ret:ty $body:block
) => {
// Define as a standalone function under docsrs cfg so that this shows as a unique function in the docs,
// not a re-export (the re-export has the wrong visibility)
#[cfg(any(docsrs, not($cfg)))]
#[cfg_attr(docsrs, doc(cfg(all())))]
$(#[$attrs])*
pub unsafe fn $name(
$($arg_names: $arg_types,)*
) -> $ret $body
#[cfg(all($cfg, not(docsrs)))]
pub use $crate::$name;
#[cfg(test)]
paste::paste! {
// Test that the compat function does not overlap with the original function. If the
// cfgs line up, then the two glob imports will resolve to the same item via the
// re-export. If the cfgs mismatch, then the use of $name will be ambiguous in cases
// where the function is defined twice, and the test will fail to compile.
#[allow(unused_imports, reason = "imports exist to try to trigger name conflicts")]
mod [<test_ $name _export>] {
use $crate::*;
use $crate::compat::*;
#[test]
fn test_export() {
let _ = $name;
}
}
}
};
}
mod py_3_10;
mod py_3_13;
mod py_3_14;
mod py_3_15;
mod py_3_9;
pub use self::py_3_10::*;
pub use self::py_3_13::*;
pub use self::py_3_14::*;
#[allow(unused_imports)]
pub use self::py_3_15::*;
pub use self::py_3_9::*;
+45
View File
@@ -0,0 +1,45 @@
compat_function!(
originally_defined_for(Py_3_10);
#[inline]
pub unsafe fn Py_NewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject {
crate::Py_INCREF(obj);
obj
}
);
compat_function!(
originally_defined_for(Py_3_10);
#[inline]
pub unsafe fn Py_XNewRef(obj: *mut crate::PyObject) -> *mut crate::PyObject {
crate::Py_XINCREF(obj);
obj
}
);
compat_function!(
originally_defined_for(Py_3_10);
#[inline]
pub unsafe fn PyModule_AddObjectRef(
module: *mut crate::PyObject,
name: *const core::ffi::c_char,
value: *mut crate::PyObject,
) -> core::ffi::c_int {
if value.is_null() && crate::PyErr_Occurred().is_null() {
crate::PyErr_SetString(
crate::PyExc_SystemError,
c"PyModule_AddObjectRef() must be called with an exception raised if value is NULL".as_ptr(),
);
return -1;
}
crate::Py_XINCREF(value);
let result = crate::PyModule_AddObject(module, name, value);
if result < 0 {
crate::Py_XDECREF(value);
}
result
}
);
+216
View File
@@ -0,0 +1,216 @@
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyDict_GetItemRef(
dp: *mut crate::PyObject,
key: *mut crate::PyObject,
result: *mut *mut crate::PyObject,
) -> core::ffi::c_int {
use crate::{compat::Py_NewRef, PyDict_GetItemWithError, PyErr_Occurred};
let item = PyDict_GetItemWithError(dp, key);
if !item.is_null() {
*result = Py_NewRef(item);
return 1; // found
}
*result = core::ptr::null_mut();
if PyErr_Occurred().is_null() {
return 0; // not found
}
-1
}
);
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyList_GetItemRef(
arg1: *mut crate::PyObject,
arg2: crate::Py_ssize_t,
) -> *mut crate::PyObject {
use crate::{PyList_GetItem, Py_XINCREF};
let item = PyList_GetItem(arg1, arg2);
Py_XINCREF(item);
item
}
);
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyImport_AddModuleRef(
name: *const core::ffi::c_char,
) -> *mut crate::PyObject {
use crate::{compat::Py_XNewRef, PyImport_AddModule};
Py_XNewRef(PyImport_AddModule(name))
}
);
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyWeakref_GetRef(
reference: *mut crate::PyObject,
pobj: *mut *mut crate::PyObject,
) -> core::ffi::c_int {
use crate::{
compat::Py_NewRef, PyErr_SetString, PyExc_TypeError, PyWeakref_Check,
PyWeakref_GetObject, Py_None,
};
if !reference.is_null() && PyWeakref_Check(reference) == 0 {
*pobj = core::ptr::null_mut();
PyErr_SetString(PyExc_TypeError, c"expected a weakref".as_ptr());
return -1;
}
let obj = PyWeakref_GetObject(reference);
if obj.is_null() {
// SystemError if reference is NULL
*pobj = core::ptr::null_mut();
return -1;
}
if obj == Py_None() {
*pobj = core::ptr::null_mut();
return 0;
}
*pobj = Py_NewRef(obj);
1
}
);
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyList_Extend(
list: *mut crate::PyObject,
iterable: *mut crate::PyObject,
) -> core::ffi::c_int {
crate::PyList_SetSlice(list, crate::PY_SSIZE_T_MAX, crate::PY_SSIZE_T_MAX, iterable)
}
);
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyList_Clear(list: *mut crate::PyObject) -> core::ffi::c_int {
crate::PyList_SetSlice(list, 0, crate::PY_SSIZE_T_MAX, core::ptr::null_mut())
}
);
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyModule_Add(
module: *mut crate::PyObject,
name: *const core::ffi::c_char,
value: *mut crate::PyObject,
) -> core::ffi::c_int {
let result = crate::compat::PyModule_AddObjectRef(module, name, value);
crate::Py_XDECREF(value);
result
}
);
#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyThreadState_GetUnchecked(
) -> *mut crate::PyThreadState {
crate::_PyThreadState_UncheckedGet()
}
);
compat_function!(
originally_defined_for(all(Py_3_13, any(not(Py_LIMITED_API), Py_3_15)));
#[inline]
pub unsafe fn PyDict_SetDefaultRef(
mp: *mut crate::PyObject,
key: *mut crate::PyObject,
default_value: *mut crate::PyObject,
result: *mut *mut crate::PyObject,
) -> core::ffi::c_int {
use crate::{
compat::{PyDict_GetItemRef, Py_NewRef},
PyDict_SetItem, PyObject, Py_DECREF,
};
let mut value: *mut PyObject = core::ptr::null_mut();
if PyDict_GetItemRef(mp, key, &mut value) < 0 {
// get error
if !result.is_null() {
*result = core::ptr::null_mut();
}
return -1;
}
if !value.is_null() {
// present
if !result.is_null() {
*result = value;
} else {
Py_DECREF(value);
}
return 1;
}
// missing, set the item
if PyDict_SetItem(mp, key, default_value) < 0 {
// set error
if !result.is_null() {
*result = core::ptr::null_mut();
}
return -1;
}
if !result.is_null() {
*result = Py_NewRef(default_value);
}
0
}
);
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyObject_GetOptionalAttr(
obj: *mut crate::PyObject,
name: *mut crate::PyObject,
result: *mut *mut crate::PyObject,
) -> core::ffi::c_int {
use crate::{PyErr_Clear, PyErr_ExceptionMatches, PyExc_AttributeError, PyObject_GetAttr};
let attr = PyObject_GetAttr(obj, name);
if !attr.is_null() {
*result = attr;
return 1; // found
}
*result = core::ptr::null_mut();
if PyErr_ExceptionMatches(PyExc_AttributeError) != 0 {
PyErr_Clear();
return 0; // not found
}
-1 // other error
}
);
compat_function!(
originally_defined_for(Py_3_13);
#[inline]
pub unsafe fn PyObject_HasAttrWithError(obj: *mut crate::PyObject, attr_name: *mut crate::PyObject) -> core::ffi::c_int {
let mut res: *mut crate::PyObject = core::ptr::null_mut();
let rc = crate::compat::PyObject_GetOptionalAttr(obj, attr_name, &mut res);
crate::Py_XDECREF(res);
rc
}
);
+45
View File
@@ -0,0 +1,45 @@
compat_function!(
originally_defined_for(all(Py_3_14, not(Py_LIMITED_API)));
#[inline]
pub unsafe fn Py_HashBuffer(
ptr: *const core::ffi::c_void,
len: crate::Py_ssize_t,
) -> crate::Py_hash_t {
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
{
crate::_Py_HashBytes(ptr, len)
}
#[cfg(any(Py_LIMITED_API, PyPy))]
{
let bytes = crate::PyBytes_FromStringAndSize(ptr as *const core::ffi::c_char, len);
if bytes.is_null() {
-1
} else {
let result = crate::PyObject_Hash(bytes);
crate::Py_DECREF(bytes);
result
}
}
}
);
compat_function!(
originally_defined_for(Py_3_14);
#[inline]
pub unsafe fn PyIter_NextItem(
iter: *mut crate::PyObject,
item: *mut *mut crate::PyObject,
) -> core::ffi::c_int {
*item = crate::PyIter_Next(iter);
if !(*item).is_null() {
1
} else if crate::PyErr_Occurred().is_null() {
0
} else {
-1
}
}
);
+193
View File
@@ -0,0 +1,193 @@
#[cfg(all(Py_3_15, not(Py_LIMITED_API)))]
pub use crate::PyBytesWriter;
#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(all(Py_3_15, not(Py_LIMITED_API)));
#[inline]
pub unsafe fn PyBytesWriter_Create(
size: crate::Py_ssize_t,
) -> *mut PyBytesWriter {
if size < 0 {
crate::PyErr_SetString(crate::PyExc_ValueError, c"size must be >= 0".as_ptr() as *const _);
return core::ptr::null_mut();
}
let writer: *mut PyBytesWriter = crate::PyMem_Malloc(core::mem::size_of::<PyBytesWriter>()).cast();
if writer.is_null() {
crate::PyErr_NoMemory();
return core::ptr::null_mut();
}
(*writer).obj = core::ptr::null_mut();
(*writer).size = 0;
if size >=1 {
if _PyBytesWriter_Resize_impl(writer, size, 0) < 0 {
PyBytesWriter_Discard(writer);
return core::ptr::null_mut();
}
(*writer).size = size;
}
writer
}
);
#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(all(Py_3_15, not(Py_LIMITED_API)));
#[inline]
pub unsafe fn PyBytesWriter_Discard(writer: *mut PyBytesWriter) -> () {
if writer.is_null() {
return;
}
crate::Py_XDECREF((*writer).obj);
crate::PyMem_Free(writer.cast());
}
);
#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(all(Py_3_15, not(Py_LIMITED_API)));
#[inline]
pub unsafe fn PyBytesWriter_Finish(writer: *mut PyBytesWriter) -> *mut crate::PyObject {
PyBytesWriter_FinishWithSize(writer, (*writer).size)
}
);
#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(all(Py_3_15, not(Py_LIMITED_API)));
#[inline]
pub unsafe fn PyBytesWriter_FinishWithSize(writer: *mut PyBytesWriter, size: crate::Py_ssize_t) -> *mut crate::PyObject {
let result = if size == 0 {
crate::PyBytes_FromStringAndSize(c"".as_ptr(), 0)
} else if (*writer).obj.is_null() {
crate::PyBytes_FromStringAndSize((*writer).small_buffer.as_ptr(), size)
} else {
if size != crate::PyBytes_Size((*writer).obj) && crate::_PyBytes_Resize(&mut (*writer).obj, size) < 0 {
PyBytesWriter_Discard(writer);
return core::ptr::null_mut();
}
core::mem::replace(&mut (*writer).obj, core::ptr::null_mut())
};
PyBytesWriter_Discard(writer);
result
}
);
#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(all(Py_3_15, not(Py_LIMITED_API)));
#[inline]
pub unsafe fn PyBytesWriter_GetData(writer: *mut PyBytesWriter) -> *mut core::ffi::c_void {
if (*writer).obj.is_null() {
(*writer).small_buffer.as_ptr() as *mut _
} else {
crate::PyBytes_AS_STRING((*writer).obj) as *mut _
}
}
);
#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(all(Py_3_15, not(Py_LIMITED_API)));
#[inline]
pub unsafe fn PyBytesWriter_GetSize(writer: *mut PyBytesWriter) -> crate::Py_ssize_t {
(*writer).size
}
);
#[cfg(not(Py_LIMITED_API))]
compat_function!(
originally_defined_for(all(Py_3_15, not(Py_LIMITED_API)));
#[inline]
pub unsafe fn PyBytesWriter_Resize(writer: *mut PyBytesWriter, size: crate::Py_ssize_t) -> core::ffi::c_int {
if size < 0 {
crate::PyErr_SetString(crate::PyExc_ValueError, c"size must be >= 0".as_ptr());
return -1;
}
if _PyBytesWriter_Resize_impl(writer, size, 1) < 0 {
return -1;
}
(*writer).size = size;
0
}
);
#[repr(C)]
#[cfg(not(any(Py_3_15, Py_LIMITED_API)))]
pub struct PyBytesWriter {
small_buffer: [core::ffi::c_char; 256],
obj: *mut crate::PyObject,
size: crate::Py_ssize_t,
}
#[inline]
#[cfg(not(any(Py_3_15, Py_LIMITED_API)))]
unsafe fn _PyBytesWriter_Resize_impl(
writer: *mut PyBytesWriter,
mut size: crate::Py_ssize_t,
resize: core::ffi::c_int,
) -> core::ffi::c_int {
let overallocate = resize;
assert!(size >= 0);
let allocated = if (*writer).obj.is_null() {
core::mem::size_of_val(&(*writer).small_buffer) as _
} else {
crate::PyBytes_Size((*writer).obj)
};
if size <= allocated {
return 0;
}
if overallocate > 0 {
#[cfg(windows)]
if size <= (crate::PY_SSIZE_T_MAX - size / 2) {
size += size / 2;
}
#[cfg(not(windows))]
if size <= (crate::PY_SSIZE_T_MAX - size / 4) {
size += size / 4;
}
}
if !(*writer).obj.is_null() {
if crate::_PyBytes_Resize(&mut (*writer).obj, size) > 0 {
return -1;
}
assert!(!(*writer).obj.is_null())
} else {
(*writer).obj = crate::PyBytes_FromStringAndSize(core::ptr::null_mut(), size);
if (*writer).obj.is_null() {
return -1;
}
if resize > 0 {
assert!((size as usize) > core::mem::size_of_val(&(*writer).small_buffer));
core::ptr::copy_nonoverlapping(
(*writer).small_buffer.as_ptr(),
crate::PyBytes_AS_STRING((*writer).obj) as *mut _,
core::mem::size_of_val(&(*writer).small_buffer),
);
}
}
0
}
+20
View File
@@ -0,0 +1,20 @@
compat_function!(
originally_defined_for(all(
not(PyPy),
any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10
));
#[inline]
pub unsafe fn PyObject_CallNoArgs(obj: *mut crate::PyObject) -> *mut crate::PyObject {
crate::PyObject_CallObject(obj, core::ptr::null_mut())
}
);
compat_function!(
originally_defined_for(all(Py_3_9, not(any(Py_LIMITED_API, PyPy))));
#[inline]
pub unsafe fn PyObject_CallMethodNoArgs(obj: *mut crate::PyObject, name: *mut crate::PyObject) -> *mut crate::PyObject {
crate::PyObject_CallMethodObjArgs(obj, name, core::ptr::null_mut::<crate::PyObject>())
}
);
+9
View File
@@ -0,0 +1,9 @@
use core::ffi::c_int;
pub const Py_single_input: c_int = 256;
pub const Py_file_input: c_int = 257;
pub const Py_eval_input: c_int = 258;
pub const Py_func_type_input: c_int = 345;
#[cfg(Py_3_9)]
pub const Py_fstring_input: c_int = 800;
+36
View File
@@ -0,0 +1,36 @@
use crate::object::*;
use core::ffi::{c_double, c_int};
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyComplex_Type")]
pub static mut PyComplex_Type: PyTypeObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyComplex_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyComplex_Type)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyComplex_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyComplex_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyComplex_CheckExact(op: *mut PyObject) -> c_int;
// skipped non-limited PyComplex_FromCComplex
#[cfg_attr(PyPy, link_name = "PyPyComplex_FromDoubles")]
pub fn PyComplex_FromDoubles(real: c_double, imag: c_double) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyComplex_RealAsDouble")]
pub fn PyComplex_RealAsDouble(op: *mut PyObject) -> c_double;
#[cfg_attr(PyPy, link_name = "PyPyComplex_ImagAsDouble")]
pub fn PyComplex_ImagAsDouble(op: *mut PyObject) -> c_double;
}
+60
View File
@@ -0,0 +1,60 @@
use crate::object::PyObject;
#[cfg(not(RustPython))]
use crate::object::PyTypeObject;
#[cfg(not(RustPython))]
use crate::Py_IS_TYPE;
use core::ffi::{c_char, c_int};
#[cfg(not(RustPython))]
extern_libpython! {
pub static mut PyContext_Type: PyTypeObject;
// skipped non-limited opaque PyContext
pub static mut PyContextVar_Type: PyTypeObject;
// skipped non-limited opaque PyContextVar
pub static mut PyContextToken_Type: PyTypeObject;
// skipped non-limited opaque PyContextToken
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyContext_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyContext_Type)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyContextVar_Type)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyContextToken_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyContext_CheckExact(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int;
pub fn PyContext_New() -> *mut PyObject;
pub fn PyContext_Copy(ctx: *mut PyObject) -> *mut PyObject;
pub fn PyContext_CopyCurrent() -> *mut PyObject;
pub fn PyContext_Enter(ctx: *mut PyObject) -> c_int;
pub fn PyContext_Exit(ctx: *mut PyObject) -> c_int;
pub fn PyContextVar_New(name: *const c_char, def: *mut PyObject) -> *mut PyObject;
pub fn PyContextVar_Get(
var: *mut PyObject,
default_value: *mut PyObject,
value: *mut *mut PyObject,
) -> c_int;
pub fn PyContextVar_Set(var: *mut PyObject, value: *mut PyObject) -> *mut PyObject;
pub fn PyContextVar_Reset(var: *mut PyObject, token: *mut PyObject) -> c_int;
// skipped non-limited _PyContext_NewHamtForTests
}
+280
View File
@@ -0,0 +1,280 @@
use crate::{vectorcallfunc, PyObject, Py_TYPE, Py_ssize_t};
#[cfg(all(any(not(PyPy), not(Py_3_11)), not(Py_3_12)))]
use core::ffi::c_char;
#[cfg(not(Py_3_11))]
use core::ffi::c_int;
#[cfg(not(any(PyPy, GraalPy)))]
use crate::{
PyListObject, PyList_Check, PyList_GET_ITEM, PyList_GET_SIZE, PyTupleObject, PyTuple_GET_ITEM,
PyTuple_GET_SIZE,
};
#[cfg(not(Py_3_11))]
use crate::Py_buffer;
#[cfg(not(any(PyPy, Py_3_11)))]
use crate::{PyCallable_Check, PyType_HasFeature, Py_TPFLAGS_HAVE_VECTORCALL};
#[cfg(not(any(Py_3_12, PyPy)))]
use crate::{PyThreadState, PyThreadState_GET, PyTuple_Check};
use libc::size_t;
// skipped private _PyObject_CallMethodId
// skipped private _PyStack_AsDict
#[cfg(not(Py_3_12))]
extern_libpython! {
#[cfg(not(PyPy))]
fn _Py_CheckFunctionResult(
tstate: *mut PyThreadState,
callable: *mut PyObject,
result: *mut PyObject,
where_: *const c_char,
) -> *mut PyObject;
#[cfg(not(PyPy))]
fn _PyObject_MakeTpCall(
tstate: *mut PyThreadState,
callable: *mut PyObject,
args: *const *mut PyObject,
nargs: Py_ssize_t,
keywords: *mut PyObject,
) -> *mut PyObject;
}
#[cfg(not(Py_3_12))]
const PY_VECTORCALL_ARGUMENTS_OFFSET: size_t = (1 as size_t)
.checked_shl((8 * core::mem::size_of::<size_t>() - 1) as u32)
.expect("size_t should fit the flag bits");
#[cfg(Py_3_12)] // public API from 3.12
use crate::PY_VECTORCALL_ARGUMENTS_OFFSET;
#[inline(always)]
pub unsafe fn PyVectorcall_NARGS(n: size_t) -> Py_ssize_t {
let n = n & !PY_VECTORCALL_ARGUMENTS_OFFSET;
n.try_into().expect("cannot fail due to mask")
}
#[cfg(any(PyPy, Py_3_11))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyVectorcall_Function")]
pub fn PyVectorcall_Function(callable: *mut PyObject) -> Option<vectorcallfunc>;
}
#[cfg(not(any(PyPy, Py_3_11)))]
#[inline(always)]
pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option<vectorcallfunc> {
assert!(!callable.is_null());
let tp = crate::Py_TYPE(callable);
if PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL) == 0 {
return None;
}
assert!(PyCallable_Check(callable) > 0);
let offset = (*tp).tp_vectorcall_offset;
assert!(offset > 0);
let ptr = callable.cast::<c_char>().offset(offset).cast();
*ptr
}
#[cfg(not(Py_3_12))]
#[cfg(not(PyPy))]
#[inline(always)]
unsafe fn _PyObject_VectorcallTstate(
tstate: *mut PyThreadState,
callable: *mut PyObject,
args: *const *mut PyObject,
nargsf: size_t,
kwnames: *mut PyObject,
) -> *mut PyObject {
assert!(kwnames.is_null() || PyTuple_Check(kwnames) > 0);
assert!(!args.is_null() || PyVectorcall_NARGS(nargsf) == 0);
match PyVectorcall_Function(callable) {
None => {
let nargs = PyVectorcall_NARGS(nargsf);
_PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames)
}
Some(func) => {
let res = func(callable, args, nargsf, kwnames);
_Py_CheckFunctionResult(tstate, callable, res, core::ptr::null_mut())
}
}
}
#[cfg(not(any(PyPy, GraalPy, Py_3_11)))] // exported as a function from 3.11, see abstract.rs
#[inline(always)]
pub unsafe fn PyObject_Vectorcall(
callable: *mut PyObject,
args: *const *mut PyObject,
nargsf: size_t,
kwnames: *mut PyObject,
) -> *mut PyObject {
_PyObject_VectorcallTstate(PyThreadState_GET(), callable, args, nargsf, kwnames)
}
extern_libpython! {
#[cfg_attr(
all(not(any(PyPy, GraalPy)), not(Py_3_9)),
link_name = "_PyObject_VectorcallDict"
)]
#[cfg_attr(all(PyPy, not(Py_3_9)), link_name = "_PyPyObject_VectorcallDict")]
#[cfg_attr(all(PyPy, Py_3_9), link_name = "PyPyObject_VectorcallDict")]
pub fn PyObject_VectorcallDict(
callable: *mut PyObject,
args: *const *mut PyObject,
nargsf: size_t,
kwdict: *mut PyObject,
) -> *mut PyObject;
}
#[cfg(not(any(Py_3_12, PyPy)))]
#[inline(always)]
pub unsafe fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject {
assert!(!arg.is_null());
let args_array = [core::ptr::null_mut(), arg];
let args = args_array.as_ptr().offset(1); // For PY_VECTORCALL_ARGUMENTS_OFFSET
let tstate = PyThreadState_GET();
let nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
_PyObject_VectorcallTstate(tstate, func, args, nargsf, core::ptr::null_mut())
}
extern_libpython! {
#[cfg(any(Py_3_12, PyPy))]
#[cfg_attr(PyPy, link_name = "PyPyObject_CallOneArg")]
pub fn PyObject_CallOneArg(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject;
}
#[cfg(all(Py_3_9, not(PyPy)))]
#[inline(always)]
pub unsafe fn PyObject_CallMethodNoArgs(
self_: *mut PyObject,
name: *mut PyObject,
) -> *mut PyObject {
crate::PyObject_VectorcallMethod(
name,
&self_,
1 | PY_VECTORCALL_ARGUMENTS_OFFSET,
core::ptr::null_mut(),
)
}
#[cfg(all(Py_3_9, not(PyPy)))]
#[inline(always)]
pub unsafe fn PyObject_CallMethodOneArg(
self_: *mut PyObject,
name: *mut PyObject,
arg: *mut PyObject,
) -> *mut PyObject {
let args = [self_, arg];
assert!(!arg.is_null());
crate::PyObject_VectorcallMethod(
name,
args.as_ptr(),
2 | PY_VECTORCALL_ARGUMENTS_OFFSET,
core::ptr::null_mut(),
)
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyObject_LengthHint")]
pub fn PyObject_LengthHint(o: *mut PyObject, arg1: Py_ssize_t) -> Py_ssize_t;
#[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11
#[cfg(all(Py_3_9, not(PyPy)))]
pub fn PyObject_CheckBuffer(obj: *mut PyObject) -> c_int;
}
#[cfg(not(any(Py_3_9, PyPy)))]
#[inline]
pub unsafe fn PyObject_CheckBuffer(o: *mut PyObject) -> c_int {
let tp_as_buffer = (*crate::Py_TYPE(o)).tp_as_buffer;
(!tp_as_buffer.is_null() && (*tp_as_buffer).bf_getbuffer.is_some()) as c_int
}
#[cfg(not(Py_3_11))] // moved to src/buffer.rs from 3.11
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyObject_GetBuffer")]
pub fn PyObject_GetBuffer(obj: *mut PyObject, view: *mut Py_buffer, flags: c_int) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_GetPointer")]
pub fn PyBuffer_GetPointer(
view: *mut Py_buffer,
indices: *mut Py_ssize_t,
) -> *mut core::ffi::c_void;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_SizeFromFormat")]
#[cfg(not(Py_3_9))] // return value changed from c_int to Py_ssize_t in 3.9
pub fn PyBuffer_SizeFromFormat(format: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_SizeFromFormat")]
#[cfg(Py_3_9)]
pub fn PyBuffer_SizeFromFormat(format: *const c_char) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_ToContiguous")]
pub fn PyBuffer_ToContiguous(
buf: *mut core::ffi::c_void,
view: *mut Py_buffer,
len: Py_ssize_t,
order: c_char,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_FromContiguous")]
pub fn PyBuffer_FromContiguous(
view: *mut Py_buffer,
buf: *mut core::ffi::c_void,
len: Py_ssize_t,
order: c_char,
) -> c_int;
pub fn PyObject_CopyData(dest: *mut PyObject, src: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_IsContiguous")]
pub fn PyBuffer_IsContiguous(view: *const Py_buffer, fort: c_char) -> c_int;
pub fn PyBuffer_FillContiguousStrides(
ndims: c_int,
shape: *mut Py_ssize_t,
strides: *mut Py_ssize_t,
itemsize: c_int,
fort: c_char,
);
#[cfg_attr(PyPy, link_name = "PyPyBuffer_FillInfo")]
pub fn PyBuffer_FillInfo(
view: *mut Py_buffer,
o: *mut PyObject,
buf: *mut core::ffi::c_void,
len: Py_ssize_t,
readonly: c_int,
flags: c_int,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_Release")]
pub fn PyBuffer_Release(view: *mut Py_buffer);
}
#[inline(always)]
pub unsafe fn PySequence_ITEM(seq: *mut PyObject, i: Py_ssize_t) -> *mut PyObject {
(*(*Py_TYPE(seq)).tp_as_sequence).sq_item.unwrap_unchecked()(seq, i)
}
#[inline(always)]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PySequence_Fast_GET_SIZE(seq: *mut PyObject) -> Py_ssize_t {
if PyList_Check(seq) == 1 {
PyList_GET_SIZE(seq)
} else {
PyTuple_GET_SIZE(seq)
}
}
#[inline(always)]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PySequence_Fast_GET_ITEM(seq: *mut PyObject, i: Py_ssize_t) -> *mut PyObject {
if PyList_Check(seq) == 1 {
PyList_GET_ITEM(seq, i)
} else {
PyTuple_GET_ITEM(seq, i)
}
}
#[inline(always)]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PySequence_Fast_ITEMS(seq: *mut PyObject) -> *mut *mut PyObject {
if PyList_Check(seq) == 1 {
(*seq.cast::<PyListObject>()).ob_item
} else {
(*seq.cast::<PyTupleObject>()).ob_item.as_mut_ptr()
}
}
+52
View File
@@ -0,0 +1,52 @@
#[cfg(Py_GIL_DISABLED)]
use crate::cpython::pyatomic::_Py_atomic_load_ssize_relaxed;
use crate::object::*;
use crate::pyport::Py_ssize_t;
use crate::PyByteArray_Check;
#[cfg(not(any(PyPy, GraalPy)))]
use core::ffi::c_char;
#[cfg(not(Py_3_9))]
use core::ffi::c_int;
#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))]
#[repr(C)]
pub struct PyByteArrayObject {
pub ob_base: PyVarObject,
pub ob_alloc: Py_ssize_t,
pub ob_bytes: *mut c_char,
pub ob_start: *mut c_char,
#[cfg(Py_3_9)]
pub ob_exports: Py_ssize_t,
#[cfg(not(Py_3_9))]
pub ob_exports: c_int,
#[cfg(Py_3_15)]
pub ob_bytes_object: *mut PyObject,
}
#[cfg(any(PyPy, GraalPy))]
opaque_struct!(pub PyByteArrayObject);
#[inline]
pub(crate) unsafe fn _PyByteArray_CAST(op: *mut PyObject) -> *mut PyByteArrayObject {
debug_assert_eq!(PyByteArray_Check(op), 1);
op.cast()
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PyByteArray_AS_STRING(op: *mut PyObject) -> *mut c_char {
(*_PyByteArray_CAST(op)).ob_start
}
#[inline]
pub unsafe fn PyByteArray_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
let byte_array = _PyByteArray_CAST(op);
#[cfg(Py_GIL_DISABLED)]
{
_Py_atomic_load_ssize_relaxed(&raw const (*_PyVarObject_CAST(byte_array.cast())).ob_size)
}
#[cfg(not(Py_GIL_DISABLED))]
{
Py_SIZE(byte_array.cast())
}
}
+62
View File
@@ -0,0 +1,62 @@
use crate::object::*;
use crate::Py_ssize_t;
#[cfg(not(Py_LIMITED_API))]
use core::ffi::c_char;
use core::ffi::c_int;
#[cfg(Py_3_15)]
use core::ffi::c_void;
#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))]
#[repr(C)]
pub struct PyBytesObject {
pub ob_base: PyVarObject,
#[cfg_attr(
Py_3_11,
deprecated(note = "Deprecated in Python 3.11 and will be removed in a future version.")
)]
pub ob_shash: crate::Py_hash_t,
pub ob_sval: [c_char; 1],
}
#[cfg(any(PyPy, GraalPy, Py_LIMITED_API))]
opaque_struct!(pub PyBytesObject);
extern_libpython! {
#[cfg_attr(PyPy, link_name = "_PyPyBytes_Resize")]
pub(crate) fn _PyBytes_Resize(bytes: *mut *mut PyObject, newsize: Py_ssize_t) -> c_int;
}
#[cfg(not(Py_LIMITED_API))]
#[inline]
pub unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char {
#[cfg(not(any(PyPy, GraalPy)))]
return &(*op.cast::<PyBytesObject>()).ob_sval as *const c_char;
#[cfg(any(PyPy, GraalPy))]
return crate::PyBytes_AsString(op);
}
#[cfg(Py_3_15)]
opaque_struct!(pub PyBytesWriter);
#[cfg(Py_3_15)]
extern_libpython! {
pub fn PyBytesWriter_Create(size: Py_ssize_t) -> *mut PyBytesWriter;
pub fn PyBytesWriter_Discard(writer: *mut PyBytesWriter);
pub fn PyBytesWriter_Finish(writer: *mut PyBytesWriter) -> *mut PyObject;
pub fn PyBytesWriter_FinishWithSize(
writer: *mut PyBytesWriter,
size: Py_ssize_t,
) -> *mut PyObject;
pub fn PyBytesWriter_GetData(writer: *mut PyBytesWriter) -> *mut c_void;
pub fn PyBytesWriter_GetSize(writer: *mut PyBytesWriter) -> Py_ssize_t;
pub fn PyBytesWriter_Resize(writer: *mut PyBytesWriter, size: Py_ssize_t) -> c_int;
pub fn PyBytesWriter_Grow(writer: *mut PyBytesWriter, size: Py_ssize_t) -> c_int;
}
+24
View File
@@ -0,0 +1,24 @@
use crate::object::*;
use core::ffi::c_int;
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
pub struct PyCellObject {
pub ob_base: PyObject,
pub ob_ref: *mut PyObject,
}
extern_libpython! {
pub fn PyCell_New(o: *mut PyObject) -> *mut PyObject;
pub fn PyCell_Get(o: *mut PyObject) -> *mut PyObject;
pub fn PyCell_Set(o: *mut PyObject, val: *mut PyObject) -> c_int;
pub static mut PyCell_Type: PyTypeObject;
}
#[inline]
pub unsafe fn PyCell_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyCell_Type)
}
// skipped PyCell_SET
// skipped PyCell_GET
+46
View File
@@ -0,0 +1,46 @@
use crate::cpython::pystate::Py_tracefunc;
use crate::object::{freefunc, PyObject};
use crate::Py_ssize_t;
extern_libpython! {
pub fn PyEval_SetProfile(trace_func: Option<Py_tracefunc>, arg1: *mut PyObject);
#[cfg(Py_3_12)]
pub fn PyEval_SetProfileAllThreads(trace_func: Option<Py_tracefunc>, arg1: *mut PyObject);
pub fn PyEval_SetTrace(trace_func: Option<Py_tracefunc>, arg1: *mut PyObject);
#[cfg(Py_3_12)]
pub fn PyEval_SetTraceAllThreads(trace_func: Option<Py_tracefunc>, arg1: *mut PyObject);
// skipped PyEval_MergeCompilerFlags
// skipped private _PyEval_EvalFrameDefault
// was moved to the unstable API tier on Py_3_12, use link_name for older versions
#[cfg_attr(Py_3_12, link_name = "_PyEval_RequestCodeExtraIndex")]
pub fn PyUnstable_Eval_RequestCodeExtraIndex(func: freefunc) -> Py_ssize_t;
}
#[deprecated(
since = "0.29.0",
note = "renamed to PyUnstable_Eval_RequestCodeExtraIndex"
)]
#[inline]
pub unsafe extern "C" fn _PyEval_RequestCodeExtraIndex(func: freefunc) -> Py_ssize_t {
PyUnstable_Eval_RequestCodeExtraIndex(func)
}
extern_libpython! {
// skipped private _PyEval_SliceIndex
// skipped private _PyEval_SliceIndexNotNone
// skipped private _PyEval_UnpackIndices
// skipped PerfMapState
// skipped PyUnstable_PerfMapState_Init
// skipped PyUnstable_WritePerfMapEntry
// skipped PyUnstable_PerfMapState_Fini
// skipped PyUnstable_CopyPerfMapFile
// skipped PyUnstable_PerfTrampoline_CompileCode
// skipped PyUnstable_PerfTrampoline_SetPersistAfterFork
}
+177
View File
@@ -0,0 +1,177 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
#[cfg(not(GraalPy))]
use crate::PyCodeObject;
#[cfg(not(GraalPy))]
use core::ffi::c_char;
use core::ffi::{c_int, c_void};
// skipped private _PY_MONITORING_LOCAL_EVENTS
// skipped private _PY_MONITORING_UNGROUPED_EVENTS
// skipped private _PY_MONITORING_EVENTS
// skipped private _PyLocalMonitors
// skipped private _Py_GlobalMonitors
// skipped private _Py_CODEUNIT
// skipped private _Py_OPCODE
// skipped private _Py_OPARG
// skipped private _py_make_codeunit
// skipped private _py_set_opcode
// skipped private _Py_MAKE_CODEUNIT
// skipped private _Py_SET_OPCODE
// skipped private _PyCoCached
// skipped private _PyCoLineInstrumentationData
// skipped private _PyCoMonitoringData
// skipped private _PyExecutorArray
/* Masks for co_flags */
pub const CO_OPTIMIZED: c_int = 0x0001;
pub const CO_NEWLOCALS: c_int = 0x0002;
pub const CO_VARARGS: c_int = 0x0004;
pub const CO_VARKEYWORDS: c_int = 0x0008;
pub const CO_NESTED: c_int = 0x0010;
pub const CO_GENERATOR: c_int = 0x0020;
/* The CO_NOFREE flag is set if there are no free or cell variables.
This information is redundant, but it allows a single flag test
to determine whether there is any extra work to be done when the
call frame it setup.
*/
pub const CO_NOFREE: c_int = 0x0040;
/* The CO_COROUTINE flag is set for coroutine functions (defined with
``async def`` keywords) */
pub const CO_COROUTINE: c_int = 0x0080;
pub const CO_ITERABLE_COROUTINE: c_int = 0x0100;
pub const CO_ASYNC_GENERATOR: c_int = 0x0200;
pub const CO_FUTURE_DIVISION: c_int = 0x2000;
pub const CO_FUTURE_ABSOLUTE_IMPORT: c_int = 0x4000; /* do absolute imports by default */
pub const CO_FUTURE_WITH_STATEMENT: c_int = 0x8000;
pub const CO_FUTURE_PRINT_FUNCTION: c_int = 0x1_0000;
pub const CO_FUTURE_UNICODE_LITERALS: c_int = 0x2_0000;
pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x4_0000;
pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000;
// skipped CO_FUTURE_ANNOTATIONS
// skipped CO_CELL_NOT_AN_ARG
pub const CO_MAXBLOCKS: usize = 20;
#[cfg(not(PyPy))]
extern_libpython! {
pub static mut PyCode_Type: PyTypeObject;
}
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyCode_Type)
}
extern_libpython! {
#[cfg(PyPy)]
#[link_name = "PyPyCode_Check"]
pub fn PyCode_Check(op: *mut PyObject) -> c_int;
}
// skipped PyCode_GetNumFree (requires knowledge of code object layout)
extern_libpython! {
#[cfg(not(GraalPy))]
#[cfg_attr(PyPy, link_name = "PyPyCode_New")]
pub fn PyCode_New(
argcount: c_int,
kwonlyargcount: c_int,
nlocals: c_int,
stacksize: c_int,
flags: c_int,
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
varnames: *mut PyObject,
freevars: *mut PyObject,
cellvars: *mut PyObject,
filename: *mut PyObject,
name: *mut PyObject,
firstlineno: c_int,
lnotab: *mut PyObject,
) -> *mut PyCodeObject;
#[cfg(not(GraalPy))]
pub fn PyCode_NewWithPosOnlyArgs(
argcount: c_int,
posonlyargcount: c_int,
kwonlyargcount: c_int,
nlocals: c_int,
stacksize: c_int,
flags: c_int,
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
varnames: *mut PyObject,
freevars: *mut PyObject,
cellvars: *mut PyObject,
filename: *mut PyObject,
name: *mut PyObject,
firstlineno: c_int,
lnotab: *mut PyObject,
) -> *mut PyCodeObject;
#[cfg(not(GraalPy))]
#[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")]
pub fn PyCode_NewEmpty(
filename: *const c_char,
funcname: *const c_char,
firstlineno: c_int,
) -> *mut PyCodeObject;
#[cfg(not(GraalPy))]
pub fn PyCode_Addr2Line(arg1: *mut PyCodeObject, arg2: c_int) -> c_int;
// skipped PyCodeAddressRange "for internal use only"
// skipped _PyCode_CheckLineNumber
// skipped _PyCode_ConstantKey
pub fn PyCode_Optimize(
code: *mut PyObject,
consts: *mut PyObject,
names: *mut PyObject,
lnotab: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(not(Py_3_12), link_name = "_PyCode_GetExtra")]
pub fn PyUnstable_Code_GetExtra(
code: *mut PyObject,
index: Py_ssize_t,
extra: *mut *mut c_void,
) -> c_int;
#[cfg_attr(not(Py_3_12), link_name = "_PyCode_SetExtra")]
pub fn PyUnstable_Code_SetExtra(
code: *mut PyObject,
index: Py_ssize_t,
extra: *mut c_void,
) -> c_int;
}
#[deprecated(since = "0.29.0", note = "renamed to PyUnstable_Code_GetExtra")]
#[inline]
pub unsafe extern "C" fn _PyCode_GetExtra(
code: *mut PyObject,
index: Py_ssize_t,
extra: *mut *mut c_void,
) -> c_int {
PyUnstable_Code_GetExtra(code, index, extra)
}
#[deprecated(since = "0.29.0", note = "renamed to PyUnstable_Code_SetExtra")]
#[inline]
pub unsafe extern "C" fn _PyCode_SetExtra(
code: *mut PyObject,
index: Py_ssize_t,
extra: *mut c_void,
) -> c_int {
PyUnstable_Code_SetExtra(code, index, extra)
}
+95
View File
@@ -0,0 +1,95 @@
#[cfg(not(any(PyPy, Py_3_10)))]
use crate::object::PyObject;
#[cfg(not(any(PyPy, Py_3_10)))]
use crate::pyarena::*;
#[cfg(not(any(PyPy, Py_3_10)))]
use crate::pythonrun::*;
#[cfg(not(any(PyPy, Py_3_10)))]
use crate::PyCodeObject;
use crate::INT_MAX;
#[cfg(not(any(PyPy, Py_3_10)))]
use core::ffi::c_char;
use core::ffi::c_int;
// skipped PyCF_MASK
// skipped PyCF_MASK_OBSOLETE
// skipped PyCF_SOURCE_IS_UTF8
// skipped PyCF_DONT_IMPLY_DEDENT
// skipped PyCF_ONLY_AST
// skipped PyCF_IGNORE_COOKIE
// skipped PyCF_TYPE_COMMENTS
// skipped PyCF_ALLOW_TOP_LEVEL_AWAIT
// skipped PyCF_OPTIMIZED_AST
// skipped PyCF_COMPILE_MASK
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCompilerFlags {
pub cf_flags: c_int,
pub cf_feature_version: c_int,
}
// skipped _PyCompilerFlags_INIT
// NB this type technically existed in the header until 3.13, when it was
// moved to the internal CPython headers.
//
// We choose not to expose it in the public API past 3.10, as it is
// not used in the public API past that point.
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyFutureFeatures {
pub ff_features: c_int,
pub ff_lineno: c_int,
}
// FIXME: these constants should probably be &CStr, if they are used at all
pub const FUTURE_NESTED_SCOPES: &str = "nested_scopes";
pub const FUTURE_GENERATORS: &str = "generators";
pub const FUTURE_DIVISION: &str = "division";
pub const FUTURE_ABSOLUTE_IMPORT: &str = "absolute_import";
pub const FUTURE_WITH_STATEMENT: &str = "with_statement";
pub const FUTURE_PRINT_FUNCTION: &str = "print_function";
pub const FUTURE_UNICODE_LITERALS: &str = "unicode_literals";
pub const FUTURE_BARRY_AS_BDFL: &str = "barry_as_FLUFL";
pub const FUTURE_GENERATOR_STOP: &str = "generator_stop";
pub const FUTURE_ANNOTATIONS: &str = "annotations";
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
extern_libpython! {
pub fn PyNode_Compile(arg1: *mut _node, arg2: *const c_char) -> *mut PyCodeObject;
pub fn PyAST_CompileEx(
_mod: *mut _mod,
filename: *const c_char,
flags: *mut PyCompilerFlags,
optimize: c_int,
arena: *mut PyArena,
) -> *mut PyCodeObject;
pub fn PyAST_CompileObject(
_mod: *mut _mod,
filename: *mut PyObject,
flags: *mut PyCompilerFlags,
optimize: c_int,
arena: *mut PyArena,
) -> *mut PyCodeObject;
pub fn PyFuture_FromAST(_mod: *mut _mod, filename: *const c_char) -> *mut PyFutureFeatures;
pub fn PyFuture_FromASTObject(
_mod: *mut _mod,
filename: *mut PyObject,
) -> *mut PyFutureFeatures;
}
pub const PY_INVALID_STACK_EFFECT: c_int = INT_MAX;
extern_libpython! {
pub fn PyCompile_OpcodeStackEffect(opcode: c_int, oparg: c_int) -> c_int;
pub fn PyCompile_OpcodeStackEffectWithJump(opcode: c_int, oparg: c_int, jump: c_int) -> c_int;
}
+30
View File
@@ -0,0 +1,30 @@
use crate::PyObject;
use core::ffi::c_double;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Py_complex {
pub real: c_double,
pub imag: c_double,
}
// skipped private function _Py_c_sum
// skipped private function _Py_c_diff
// skipped private function _Py_c_neg
// skipped private function _Py_c_prod
// skipped private function _Py_c_quot
// skipped private function _Py_c_pow
// skipped private function _Py_c_abs
#[repr(C)]
pub struct PyComplexObject {
pub ob_base: PyObject,
pub cval: Py_complex,
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyComplex_FromCComplex")]
pub fn PyComplex_FromCComplex(v: Py_complex) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyComplex_AsCComplex")]
pub fn PyComplex_AsCComplex(op: *mut PyObject) -> Py_complex;
}
+11
View File
@@ -0,0 +1,11 @@
use crate::PyMutex;
use crate::{PyCriticalSection, PyCriticalSection2};
extern_libpython! {
pub fn PyCriticalSection_BeginMutex(c: *mut PyCriticalSection, m: *mut PyMutex);
pub fn PyCriticalSection2_BeginMutex(
c: *mut PyCriticalSection2,
m1: *mut PyMutex,
m2: *mut PyMutex,
);
}
+81
View File
@@ -0,0 +1,81 @@
use crate::{PyGetSetDef, PyMethodDef, PyObject, PyTypeObject};
use core::ffi::{c_char, c_int, c_void};
#[cfg(Py_3_11)]
use crate::PyMemberDef;
pub type wrapperfunc = Option<
unsafe extern "C" fn(
slf: *mut PyObject,
args: *mut PyObject,
wrapped: *mut c_void,
) -> *mut PyObject,
>;
pub type wrapperfunc_kwds = Option<
unsafe extern "C" fn(
slf: *mut PyObject,
args: *mut PyObject,
wrapped: *mut c_void,
kwds: *mut PyObject,
) -> *mut PyObject,
>;
#[repr(C)]
pub struct wrapperbase {
pub name: *const c_char,
pub offset: c_int,
pub function: *mut c_void,
pub wrapper: wrapperfunc,
pub doc: *const c_char,
pub flags: c_int,
pub name_strobj: *mut PyObject,
}
pub const PyWrapperFlag_KEYWORDS: c_int = 1;
#[repr(C)]
pub struct PyDescrObject {
pub ob_base: PyObject,
pub d_type: *mut PyTypeObject,
pub d_name: *mut PyObject,
pub d_qualname: *mut PyObject,
}
// skipped non-limited PyDescr_TYPE
// skipped non-limited PyDescr_NAME
#[repr(C)]
pub struct PyMethodDescrObject {
pub d_common: PyDescrObject,
pub d_method: *mut PyMethodDef,
#[cfg(not(PyPy))]
pub vectorcall: Option<crate::vectorcallfunc>,
}
#[repr(C)]
pub struct PyMemberDescrObject {
pub d_common: PyDescrObject,
#[cfg(not(Py_3_11))]
pub d_member: *mut PyGetSetDef,
#[cfg(Py_3_11)]
pub d_member: *mut PyMemberDef,
}
#[repr(C)]
pub struct PyGetSetDescrObject {
pub d_common: PyDescrObject,
pub d_getset: *mut PyGetSetDef,
}
#[repr(C)]
pub struct PyWrapperDescrObject {
pub d_common: PyDescrObject,
pub d_base: *mut wrapperbase,
pub d_wrapped: *mut c_void,
}
// skipped _PyMethodWrapper_Type
// skipped non-limited PyDescr_NewWrapper
// skipped non-limited PyDescr_IsData
+114
View File
@@ -0,0 +1,114 @@
#[cfg(not(GraalPy))]
use crate::object::*;
#[cfg(not(any(PyPy, GraalPy)))]
use crate::pyport::Py_ssize_t;
#[cfg(all(GraalPy, Py_3_13))]
use crate::PyObject;
#[cfg(all(not(PyPy), Py_3_13))]
use core::ffi::c_char;
#[cfg(all(not(PyPy), Py_3_12))]
use core::ffi::c_int;
#[cfg(not(PyPy))]
opaque_struct!(pub PyDictKeysObject);
#[cfg(Py_3_11)]
#[cfg(not(PyPy))]
opaque_struct!(pub PyDictValues);
#[cfg(not(any(GraalPy, PyPy)))]
#[repr(C)]
#[derive(Debug)]
pub struct PyDictObject {
pub ob_base: PyObject,
pub ma_used: Py_ssize_t,
#[cfg_attr(
Py_3_12,
deprecated(note = "Deprecated in Python 3.12 and will be removed in the future.")
)]
#[cfg(not(Py_3_14))]
pub ma_version_tag: u64,
#[cfg(Py_3_14)]
_ma_watcher_tag: u64,
pub ma_keys: *mut PyDictKeysObject,
#[cfg(not(Py_3_11))]
pub ma_values: *mut *mut PyObject,
#[cfg(Py_3_11)]
pub ma_values: *mut PyDictValues,
}
#[cfg(PyPy)]
#[repr(C)]
#[derive(Debug)]
pub struct PyDictObject {
pub ob_base: PyObject,
_tmpkeys: *mut PyObject,
}
extern_libpython! {
#[cfg(Py_3_15)]
pub fn PyFrozenDict_New(iterable: *mut PyObject) -> *mut PyObject;
}
// skipped private _PyDict_GetItem_KnownHash
// skipped private _PyDict_GetItemStringWithError
extern_libpython! {
#[cfg(not(GraalPy))]
pub fn PyDict_SetDefault(
mp: *mut PyObject,
key: *mut PyObject,
default_obj: *mut PyObject,
) -> *mut PyObject;
/*
#[cfg(all(Py_3_13, not(Py_3_15)))]
pub fn PyDict_SetDefaultRef(
mp: *mut PyObject,
key: *mut PyObject,
default_obj: *mut PyObject,
result: *mut *mut PyObject,
) -> c_int;
*/
}
// skipped PyDict_GET_SIZE
extern_libpython! {
#[cfg(Py_3_13)]
pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const c_char) -> c_int;
}
// skipped private _PyDict_NewPresized
extern_libpython! {
#[cfg(Py_3_13)]
pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: *mut *mut PyObject)
-> c_int;
#[cfg(Py_3_13)]
pub fn PyDict_PopString(
dict: *mut PyObject,
key: *const c_char,
result: *mut *mut PyObject,
) -> c_int;
}
// skipped private _PyDict_Pop
// skipped PY_FOREACH_DICT_EVENT
// skipped PyDict_WatchEvent
// skipped PyDict_WatchCallback
// skipped PyDict_AddWatcher
extern_libpython! {
#[cfg(Py_3_12)]
pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int;
#[cfg(Py_3_12)]
#[cfg(not(GraalPy))]
pub fn PyDict_Watch(watcher_id: c_int, dict: *mut PyObject) -> c_int;
#[cfg(Py_3_12)]
#[cfg(not(GraalPy))]
pub fn PyDict_Unwatch(watcher_id: c_int, dict: *mut PyObject) -> c_int;
}
+35
View File
@@ -0,0 +1,35 @@
#[cfg(GraalPy)]
use crate::PyFloat_AsDouble;
#[cfg(not(GraalPy))]
use crate::PyFloat_Check;
use crate::PyObject;
use core::ffi::c_double;
#[repr(C)]
pub struct PyFloatObject {
pub ob_base: PyObject,
pub ob_fval: c_double,
}
#[inline]
#[cfg(not(GraalPy))]
unsafe fn _PyFloat_CAST(op: *mut PyObject) -> *mut PyFloatObject {
debug_assert_eq!(PyFloat_Check(op), 1);
op.cast()
}
#[inline]
pub unsafe fn PyFloat_AS_DOUBLE(op: *mut PyObject) -> c_double {
#[cfg(not(GraalPy))]
return (*_PyFloat_CAST(op)).ob_fval;
#[cfg(GraalPy)]
return PyFloat_AsDouble(op);
}
// skipped PyFloat_Pack2
// skipped PyFloat_Pack4
// skipped PyFloat_Pack8
// skipped PyFloat_Unpack2
// skipped PyFloat_Unpack4
// skipped PyFloat_Unpack8
+51
View File
@@ -0,0 +1,51 @@
#[cfg(not(GraalPy))]
use crate::object::*;
#[cfg(not(GraalPy))]
use crate::PyCodeObject;
use crate::PyFrameObject;
#[cfg(not(GraalPy))]
use crate::PyThreadState;
#[cfg(not(any(PyPy, GraalPy, Py_3_11)))]
use core::ffi::c_char;
use core::ffi::c_int;
#[cfg(not(any(PyPy, GraalPy, Py_3_11)))]
pub type PyFrameState = c_char;
#[repr(C)]
#[derive(Copy, Clone)]
#[cfg(not(any(PyPy, GraalPy, Py_3_11)))]
pub struct PyTryBlock {
pub b_type: c_int,
pub b_handler: c_int,
pub b_level: c_int,
}
// skipped _PyFrame_IsRunnable
// skipped _PyFrame_IsExecuting
// skipped _PyFrameHasCompleted
extern_libpython! {
#[cfg(not(GraalPy))]
#[cfg_attr(PyPy, link_name = "PyPyFrame_New")]
pub fn PyFrame_New(
tstate: *mut PyThreadState,
code: *mut PyCodeObject,
globals: *mut PyObject,
locals: *mut PyObject,
) -> *mut PyFrameObject;
// skipped _PyFrame_New_NoTrack
pub fn PyFrame_BlockSetup(f: *mut PyFrameObject, _type: c_int, handler: c_int, level: c_int);
#[cfg(not(any(PyPy, GraalPy, Py_3_11)))]
pub fn PyFrame_BlockPop(f: *mut PyFrameObject) -> *mut PyTryBlock;
pub fn PyFrame_LocalsToFast(f: *mut PyFrameObject, clear: c_int);
pub fn PyFrame_FastToLocalsWithError(f: *mut PyFrameObject) -> c_int;
pub fn PyFrame_FastToLocals(f: *mut PyFrameObject);
// skipped _PyFrame_DebugMallocStats
#[cfg(not(Py_3_9))]
pub fn PyFrame_ClearFreeList() -> c_int;
}
+103
View File
@@ -0,0 +1,103 @@
use crate::{PyObject, Py_IS_TYPE};
use core::ffi::c_int;
#[cfg(all(not(any(PyPy, GraalPy)), not(Py_3_10)))]
#[repr(C)]
pub struct PyFunctionObject {
pub ob_base: PyObject,
pub func_code: *mut PyObject,
pub func_globals: *mut PyObject,
pub func_defaults: *mut PyObject,
pub func_kwdefaults: *mut PyObject,
pub func_closure: *mut PyObject,
pub func_doc: *mut PyObject,
pub func_name: *mut PyObject,
pub func_dict: *mut PyObject,
pub func_weakreflist: *mut PyObject,
pub func_module: *mut PyObject,
pub func_annotations: *mut PyObject,
pub func_qualname: *mut PyObject,
pub vectorcall: Option<crate::vectorcallfunc>,
}
#[cfg(all(not(any(PyPy, GraalPy)), Py_3_10))]
#[repr(C)]
pub struct PyFunctionObject {
pub ob_base: PyObject,
pub func_globals: *mut PyObject,
pub func_builtins: *mut PyObject,
pub func_name: *mut PyObject,
pub func_qualname: *mut PyObject,
pub func_code: *mut PyObject,
pub func_defaults: *mut PyObject,
pub func_kwdefaults: *mut PyObject,
pub func_closure: *mut PyObject,
pub func_doc: *mut PyObject,
pub func_dict: *mut PyObject,
pub func_weakreflist: *mut PyObject,
pub func_module: *mut PyObject,
pub func_annotations: *mut PyObject,
#[cfg(Py_3_14)]
pub func_annotate: *mut PyObject,
#[cfg(Py_3_12)]
pub func_typeparams: *mut PyObject,
pub vectorcall: Option<crate::vectorcallfunc>,
#[cfg(Py_3_11)]
pub func_version: u32,
}
#[cfg(PyPy)]
#[repr(C)]
pub struct PyFunctionObject {
pub ob_base: PyObject,
pub func_name: *mut PyObject,
}
#[cfg(GraalPy)]
pub struct PyFunctionObject {
pub ob_base: PyObject,
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyFunction_Type")]
pub static mut PyFunction_Type: crate::PyTypeObject;
}
#[inline]
pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyFunction_Type)
}
extern_libpython! {
pub fn PyFunction_New(code: *mut PyObject, globals: *mut PyObject) -> *mut PyObject;
pub fn PyFunction_NewWithQualName(
code: *mut PyObject,
globals: *mut PyObject,
qualname: *mut PyObject,
) -> *mut PyObject;
pub fn PyFunction_GetCode(op: *mut PyObject) -> *mut PyObject;
pub fn PyFunction_GetGlobals(op: *mut PyObject) -> *mut PyObject;
pub fn PyFunction_GetModule(op: *mut PyObject) -> *mut PyObject;
pub fn PyFunction_GetDefaults(op: *mut PyObject) -> *mut PyObject;
pub fn PyFunction_SetDefaults(op: *mut PyObject, defaults: *mut PyObject) -> c_int;
pub fn PyFunction_GetKwDefaults(op: *mut PyObject) -> *mut PyObject;
pub fn PyFunction_SetKwDefaults(op: *mut PyObject, defaults: *mut PyObject) -> c_int;
pub fn PyFunction_GetClosure(op: *mut PyObject) -> *mut PyObject;
pub fn PyFunction_SetClosure(op: *mut PyObject, closure: *mut PyObject) -> c_int;
pub fn PyFunction_GetAnnotations(op: *mut PyObject) -> *mut PyObject;
pub fn PyFunction_SetAnnotations(op: *mut PyObject, annotations: *mut PyObject) -> c_int;
}
// skipped _PyFunction_Vectorcall
// skipped PyFunction_GET_CODE
// skipped PyFunction_GET_GLOBALS
// skipped PyFunction_GET_MODULE
// skipped PyFunction_GET_DEFAULTS
// skipped PyFunction_GET_KW_DEFAULTS
// skipped PyFunction_GET_CLOSURE
// skipped PyFunction_GET_ANNOTATIONS
// skipped PyClassMethod_Type
// skipped PyStaticMethod_Type
// skipped PyClassMethod_New
// skipped PyStaticMethod_New
+100
View File
@@ -0,0 +1,100 @@
use crate::object::*;
use crate::PyFrameObject;
#[cfg(all(Py_3_11, not(any(PyPy, GraalPy, Py_3_14))))]
use core::ffi::c_char;
use core::ffi::c_int;
#[cfg(not(any(PyPy, GraalPy, Py_3_14)))]
#[repr(C)]
pub struct PyGenObject {
pub ob_base: PyObject,
#[cfg(not(Py_3_11))]
pub gi_frame: *mut PyFrameObject,
#[cfg(not(Py_3_10))]
pub gi_running: c_int,
#[cfg(not(Py_3_12))]
pub gi_code: *mut PyObject,
pub gi_weakreflist: *mut PyObject,
pub gi_name: *mut PyObject,
pub gi_qualname: *mut PyObject,
#[allow(
private_interfaces,
reason = "PyGenObject layout was public until 3.14"
)]
pub gi_exc_state: crate::cpython::pystate::_PyErr_StackItem,
#[cfg(Py_3_11)]
pub gi_origin_or_finalizer: *mut PyObject,
#[cfg(Py_3_11)]
pub gi_hooks_inited: c_char,
#[cfg(Py_3_11)]
pub gi_closed: c_char,
#[cfg(Py_3_11)]
pub gi_running_async: c_char,
#[cfg(Py_3_11)]
pub gi_frame_state: i8,
#[cfg(Py_3_11)]
pub gi_iframe: [*mut PyObject; 1],
}
#[cfg(all(Py_3_14, not(any(PyPy, GraalPy))))]
opaque_struct!(pub PyGenObject);
extern_libpython! {
pub static mut PyGen_Type: PyTypeObject;
}
#[inline]
pub unsafe fn PyGen_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyGen_Type)
}
#[inline]
pub unsafe fn PyGen_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyGen_Type)
}
extern_libpython! {
pub fn PyGen_New(frame: *mut PyFrameObject) -> *mut PyObject;
// skipped PyGen_NewWithQualName
// skipped _PyGen_SetStopIterationValue
// skipped _PyGen_FetchStopIterationValue
// skipped _PyGen_yf
// skipped _PyGen_Finalize
#[cfg(not(any(Py_3_9, PyPy)))]
#[deprecated(note = "This function was never documented in the Python API.")]
pub fn PyGen_NeedsFinalizing(op: *mut PyGenObject) -> c_int;
}
// skipped PyCoroObject
extern_libpython! {
pub static mut PyCoro_Type: PyTypeObject;
}
// skipped _PyCoroWrapper_Type
#[inline]
pub unsafe fn PyCoro_CheckExact(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyCoro_Type)
}
// skipped _PyCoro_GetAwaitableIter
// skipped PyCoro_New
// skipped PyAsyncGenObject
extern_libpython! {
pub static mut PyAsyncGen_Type: PyTypeObject;
// skipped _PyAsyncGenASend_Type
// skipped _PyAsyncGenWrappedValue_Type
// skipped _PyAsyncGenAThrow_Type
}
// skipped PyAsyncGen_New
#[inline]
pub unsafe fn PyAsyncGen_CheckExact(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyAsyncGen_Type)
}
// skipped _PyAsyncGenValueWrapperNew
+51
View File
@@ -0,0 +1,51 @@
#[cfg(any(not(PyPy), Py_3_14))]
use crate::PyObject;
#[cfg(any(not(PyPy), Py_3_14))]
use core::ffi::c_char;
#[cfg(not(PyPy))]
use core::ffi::{c_int, c_uchar};
#[cfg(not(PyPy))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct _inittab {
pub name: *const c_char,
pub initfunc: Option<unsafe extern "C" fn() -> *mut PyObject>,
}
extern_libpython! {
#[cfg(not(PyPy))]
pub static mut PyImport_Inittab: *mut _inittab;
#[cfg(not(PyPy))]
pub fn PyImport_ExtendInittab(newtab: *mut _inittab) -> c_int;
}
#[cfg(not(PyPy))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct _frozen {
pub name: *const c_char,
pub code: *const c_uchar,
pub size: c_int,
#[cfg(Py_3_11)]
pub is_package: c_int,
#[cfg(all(Py_3_11, not(Py_3_13)))]
pub get_code: Option<unsafe extern "C" fn() -> *mut PyObject>,
}
extern_libpython! {
#[cfg(not(PyPy))]
pub static mut PyImport_FrozenModules: *const _frozen;
#[cfg(Py_3_14)]
pub fn PyImport_ImportModuleAttr(
mod_name: *mut PyObject,
attr_name: *mut PyObject,
) -> *mut PyObject;
#[cfg(Py_3_14)]
pub fn PyImport_ImportModuleAttrString(
mod_name: *const c_char,
attr_name: *const c_char,
) -> *mut PyObject;
}
+237
View File
@@ -0,0 +1,237 @@
/* --- PyStatus ----------------------------------------------- */
use crate::Py_ssize_t;
use core::ffi::{c_char, c_int, c_ulong};
use libc::wchar_t;
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum _PyStatus_TYPE {
_PyStatus_TYPE_OK = 0,
_PyStatus_TYPE_ERROR = 1,
_PyStatus_TYPE_EXIT = 2,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyStatus {
pub _type: _PyStatus_TYPE,
pub func: *const c_char,
pub err_msg: *const c_char,
pub exitcode: c_int,
}
extern_libpython! {
pub fn PyStatus_Ok() -> PyStatus;
pub fn PyStatus_Error(err_msg: *const c_char) -> PyStatus;
pub fn PyStatus_NoMemory() -> PyStatus;
pub fn PyStatus_Exit(exitcode: c_int) -> PyStatus;
pub fn PyStatus_IsError(err: PyStatus) -> c_int;
pub fn PyStatus_IsExit(err: PyStatus) -> c_int;
pub fn PyStatus_Exception(err: PyStatus) -> c_int;
}
/* --- PyWideStringList ------------------------------------------------ */
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyWideStringList {
pub length: Py_ssize_t,
pub items: *mut *mut wchar_t,
}
extern_libpython! {
pub fn PyWideStringList_Append(list: *mut PyWideStringList, item: *const wchar_t) -> PyStatus;
pub fn PyWideStringList_Insert(
list: *mut PyWideStringList,
index: Py_ssize_t,
item: *const wchar_t,
) -> PyStatus;
}
/* --- PyPreConfig ----------------------------------------------- */
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyPreConfig {
pub _config_init: c_int,
pub parse_argv: c_int,
pub isolated: c_int,
pub use_environment: c_int,
pub configure_locale: c_int,
pub coerce_c_locale: c_int,
pub coerce_c_locale_warn: c_int,
#[cfg(windows)]
pub legacy_windows_fs_encoding: c_int,
pub utf8_mode: c_int,
pub dev_mode: c_int,
pub allocator: c_int,
}
extern_libpython! {
pub fn PyPreConfig_InitPythonConfig(config: *mut PyPreConfig);
pub fn PyPreConfig_InitIsolatedConfig(config: *mut PyPreConfig);
}
/* --- PyConfig ---------------------------------------------- */
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyConfig {
pub _config_init: c_int,
pub isolated: c_int,
pub use_environment: c_int,
pub dev_mode: c_int,
pub install_signal_handlers: c_int,
pub use_hash_seed: c_int,
pub hash_seed: c_ulong,
pub faulthandler: c_int,
#[cfg(all(Py_3_9, not(Py_3_10)))]
pub _use_peg_parser: c_int,
pub tracemalloc: c_int,
#[cfg(Py_3_12)]
pub perf_profiling: c_int,
#[cfg(Py_3_14)]
pub remote_debug: c_int,
pub import_time: c_int,
#[cfg(Py_3_11)]
pub code_debug_ranges: c_int,
pub show_ref_count: c_int,
#[cfg(not(Py_3_9))]
pub show_alloc_count: c_int,
pub dump_refs: c_int,
#[cfg(Py_3_11)]
pub dump_refs_file: *mut wchar_t,
pub malloc_stats: c_int,
#[cfg(Py_3_15)]
pub pymalloc_hugepages: c_int,
pub filesystem_encoding: *mut wchar_t,
pub filesystem_errors: *mut wchar_t,
pub pycache_prefix: *mut wchar_t,
pub parse_argv: c_int,
#[cfg(Py_3_10)]
pub orig_argv: PyWideStringList,
pub argv: PyWideStringList,
#[cfg(not(Py_3_10))]
pub program_name: *mut wchar_t,
pub xoptions: PyWideStringList,
pub warnoptions: PyWideStringList,
pub site_import: c_int,
pub bytes_warning: c_int,
#[cfg(Py_3_10)]
pub warn_default_encoding: c_int,
pub inspect: c_int,
pub interactive: c_int,
pub optimization_level: c_int,
pub parser_debug: c_int,
pub write_bytecode: c_int,
pub verbose: c_int,
pub quiet: c_int,
pub user_site_directory: c_int,
pub configure_c_stdio: c_int,
pub buffered_stdio: c_int,
pub stdio_encoding: *mut wchar_t,
pub stdio_errors: *mut wchar_t,
#[cfg(windows)]
pub legacy_windows_stdio: c_int,
pub check_hash_pycs_mode: *mut wchar_t,
#[cfg(Py_3_11)]
pub use_frozen_modules: c_int,
#[cfg(Py_3_11)]
pub safe_path: c_int,
#[cfg(Py_3_12)]
pub int_max_str_digits: c_int,
#[cfg(Py_3_14)]
pub thread_inherit_context: c_int,
#[cfg(Py_3_14)]
pub context_aware_warnings: c_int,
#[cfg(all(Py_3_14, target_os = "macos"))]
pub use_system_logger: c_int,
#[cfg(Py_3_13)]
pub cpu_count: c_int,
#[cfg(Py_GIL_DISABLED)]
pub enable_gil: c_int,
#[cfg(all(Py_3_14, Py_GIL_DISABLED))]
pub tlbc_enabled: c_int,
#[cfg(Py_3_15)]
pub lazy_imports: c_int,
pub pathconfig_warnings: c_int,
#[cfg(Py_3_10)]
pub program_name: *mut wchar_t,
pub pythonpath_env: *mut wchar_t,
pub home: *mut wchar_t,
#[cfg(Py_3_10)]
pub platlibdir: *mut wchar_t,
pub module_search_paths_set: c_int,
pub module_search_paths: PyWideStringList,
#[cfg(Py_3_11)]
pub stdlib_dir: *mut wchar_t,
pub executable: *mut wchar_t,
pub base_executable: *mut wchar_t,
pub prefix: *mut wchar_t,
pub base_prefix: *mut wchar_t,
pub exec_prefix: *mut wchar_t,
pub base_exec_prefix: *mut wchar_t,
#[cfg(all(Py_3_9, not(Py_3_10)))]
pub platlibdir: *mut wchar_t,
pub skip_source_first_line: c_int,
pub run_command: *mut wchar_t,
pub run_module: *mut wchar_t,
pub run_filename: *mut wchar_t,
#[cfg(Py_3_13)]
pub sys_path_0: *mut wchar_t,
pub _install_importlib: c_int,
pub _init_main: c_int,
#[cfg(all(Py_3_9, not(Py_3_12)))]
pub _isolated_interpreter: c_int,
#[cfg(Py_3_11)]
pub _is_python_build: c_int,
#[cfg(all(Py_3_9, not(Py_3_10)))]
pub _orig_argv: PyWideStringList,
#[cfg(all(Py_3_13, py_sys_config = "Py_DEBUG"))]
pub run_presite: *mut wchar_t,
}
extern_libpython! {
pub fn PyConfig_InitPythonConfig(config: *mut PyConfig);
pub fn PyConfig_InitIsolatedConfig(config: *mut PyConfig);
pub fn PyConfig_Clear(config: *mut PyConfig);
pub fn PyConfig_SetString(
config: *mut PyConfig,
config_str: *mut *mut wchar_t,
str: *const wchar_t,
) -> PyStatus;
pub fn PyConfig_SetBytesString(
config: *mut PyConfig,
config_str: *mut *mut wchar_t,
str: *const c_char,
) -> PyStatus;
pub fn PyConfig_Read(config: *mut PyConfig) -> PyStatus;
pub fn PyConfig_SetBytesArgv(
config: *mut PyConfig,
argc: Py_ssize_t,
argv: *mut *const c_char,
) -> PyStatus;
pub fn PyConfig_SetArgv(
config: *mut PyConfig,
argc: Py_ssize_t,
argv: *mut *const wchar_t,
) -> PyStatus;
pub fn PyConfig_SetWideStringList(
config: *mut PyConfig,
list: *mut PyWideStringList,
length: Py_ssize_t,
items: *mut *mut wchar_t,
) -> PyStatus;
}
/* --- Helper functions --------------------------------------- */
extern_libpython! {
pub fn Py_GetArgcArgv(argc: *mut c_int, argv: *mut *mut *mut wchar_t);
}
+58
View File
@@ -0,0 +1,58 @@
#[cfg(Py_GIL_DISABLED)]
use crate::cpython::pyatomic::_Py_atomic_load_ssize_relaxed;
use crate::object::*;
#[cfg(not(PyPy))]
use crate::pyport::Py_ssize_t;
#[cfg(not(PyPy))]
use crate::PyList_Check;
#[cfg(not(PyPy))]
#[repr(C)]
pub struct PyListObject {
pub ob_base: PyVarObject,
pub ob_item: *mut *mut PyObject,
pub allocated: Py_ssize_t,
}
#[cfg(PyPy)]
pub struct PyListObject {
pub ob_base: PyObject,
}
#[inline]
#[cfg(not(PyPy))]
pub(crate) unsafe fn _PyList_CAST(op: *mut PyObject) -> *mut PyListObject {
debug_assert_eq!(PyList_Check(op), 1);
op.cast()
}
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyList_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
let list = _PyList_CAST(op);
#[cfg(Py_GIL_DISABLED)]
{
_Py_atomic_load_ssize_relaxed(&raw const (*_PyVarObject_CAST(list.cast())).ob_size)
}
#[cfg(not(Py_GIL_DISABLED))]
{
Py_SIZE(list.cast())
}
}
/// Macro, trading safety for speed
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PyList_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject {
*(*_PyList_CAST(op)).ob_item.offset(i)
}
/// Macro, *only* to be used to fill in brand new lists
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) {
*(*_PyList_CAST(op)).ob_item.offset(i) = v;
}
// skipped _PyList_Extend
// skipped _PyList_DebugMallocStats
+26
View File
@@ -0,0 +1,26 @@
#[cfg(Py_3_14)]
use core::ffi::c_int;
use core::sync::atomic::AtomicU8;
#[repr(transparent)]
#[derive(Debug)]
pub struct PyMutex {
pub(crate) _bits: AtomicU8,
}
// we don't impl Default because PyO3's safe wrappers don't need it
#[allow(clippy::new_without_default)]
impl PyMutex {
pub const fn new() -> PyMutex {
PyMutex {
_bits: AtomicU8::new(0),
}
}
}
extern_libpython! {
pub fn PyMutex_Lock(m: *mut PyMutex);
pub fn PyMutex_Unlock(m: *mut PyMutex);
#[cfg(Py_3_14)]
pub fn PyMutex_IsLocked(m: *mut PyMutex) -> c_int;
}
+55
View File
@@ -0,0 +1,55 @@
use crate::{PyObject, Py_ssize_t};
use core::ffi::{c_int, c_void};
use crate::Py_uintptr_t;
// skipped PyLong_BASE
// skipped PyLong_MASK
// skipped _PyLong_New
// skipped _PyLong_Copy
// skipped _PyLong_FromDigits
// skipped _PyLong_SIGN_MASK
// skipped _PyLong_NON_SIZE_BITS
// skipped PyUnstable_Long_IsCompact
// skipped PyUnstable_Long_CompactValue
#[derive(Copy, Clone)]
#[repr(C)]
pub struct PyLongLayout {
pub bits_per_digit: u8,
pub digit_size: u8,
pub digits_order: i8,
pub digit_endianness: i8,
}
extern_libpython! {
pub fn PyLong_GetNativeLayout() -> *const PyLongLayout;
}
#[repr(C)]
pub struct PyLongExport {
pub value: i64,
pub negative: u8,
pub ndigits: Py_ssize_t,
pub digits: *const c_void,
_reserved: Py_uintptr_t,
}
extern_libpython! {
pub fn PyLong_Export(obj: *mut PyObject, export_long: *mut PyLongExport) -> c_int;
pub fn PyLong_FreeExport(export_long: *mut PyLongExport);
}
opaque_struct!(pub PyLongWriter);
extern_libpython! {
pub fn PyLongWriter_Create(
negative: c_int,
ndigits: Py_ssize_t,
digits: *mut *mut c_void,
) -> *mut PyLongWriter;
pub fn PyLongWriter_Finish(writer: *mut PyLongWriter) -> *mut PyObject;
pub fn PyLongWriter_Discard(writer: *mut PyLongWriter);
}
+55
View File
@@ -0,0 +1,55 @@
#[cfg(not(Py_3_13))]
use crate::longobject::*;
use crate::object::*;
use core::ffi::c_int;
#[cfg(not(Py_3_13))]
use core::ffi::c_uchar;
#[cfg(not(Py_3_13))]
use libc::size_t;
// skipped _PyLong_CAST
extern_libpython! {
#[cfg(Py_3_13)]
pub fn PyLong_FromUnicodeObject(u: *mut PyObject, base: c_int) -> *mut PyObject;
// skipped PyUnstable_Long_IsCompact
// skipped PyUnstable_Long_CompactValue
#[cfg(Py_3_14)]
pub fn PyLong_IsPositive(obj: *mut PyObject) -> c_int;
#[cfg(Py_3_14)]
pub fn PyLong_IsNegative(obj: *mut PyObject) -> c_int;
#[cfg(Py_3_14)]
pub fn PyLong_IsZero(obj: *mut PyObject) -> c_int;
// skipped PyLong_GetSign
// skipped _PyLong_Sign
// skipped non-limited _PyLong_NumBits
#[cfg(not(Py_3_13))]
#[cfg_attr(PyPy, link_name = "_PyPyLong_FromByteArray")]
#[doc(hidden)] // used in PyO3's older bytes conversions, but not otherwise public API
pub fn _PyLong_FromByteArray(
bytes: *const c_uchar,
n: size_t,
little_endian: c_int,
is_signed: c_int,
) -> *mut PyObject;
#[cfg(not(Py_3_13))]
#[doc(hidden)] // used in PyO3's older bytes conversions, but not otherwise public API
#[cfg_attr(PyPy, link_name = "_PyPyLong_AsByteArrayO")]
pub fn _PyLong_AsByteArray(
v: *mut PyLongObject,
bytes: *mut c_uchar,
n: size_t,
little_endian: c_int,
is_signed: c_int,
) -> c_int;
// skipped _PyLong_GCD
}
+29
View File
@@ -0,0 +1,29 @@
use crate::{PyObject, Py_ssize_t};
use core::ffi::{c_char, c_int, c_long};
use libc::FILE;
#[cfg(Py_3_15)]
pub const Py_MARSHAL_VERSION: c_int = 6;
#[cfg(not(Py_3_15))]
pub const Py_MARSHAL_VERSION: c_int = 5;
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyMarshal_WriteObjectToString")]
pub fn PyMarshal_WriteObjectToString(object: *mut PyObject, version: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyMarshal_ReadObjectFromString")]
pub fn PyMarshal_ReadObjectFromString(data: *const c_char, len: Py_ssize_t) -> *mut PyObject;
pub fn PyMarshal_WriteLongToFile(value: c_long, file: *mut FILE, version: c_int);
pub fn PyMarshal_WriteObjectToFile(object: *mut PyObject, file: *mut FILE, version: c_int);
pub fn PyMarshal_ReadLongFromFile(file: *mut FILE) -> c_long;
pub fn PyMarshal_ReadShortFromFile(file: *mut FILE) -> c_int;
pub fn PyMarshal_ReadObjectFromFile(file: *mut FILE) -> *mut PyObject;
pub fn PyMarshal_ReadLastObjectFromFile(file: *mut FILE) -> *mut PyObject;
}
+69
View File
@@ -0,0 +1,69 @@
use crate::object::*;
#[cfg(not(GraalPy))]
use crate::{PyCFunctionObject, PyMethodDefPointer, METH_METHOD, METH_STATIC};
use core::ffi::c_int;
#[cfg(not(GraalPy))]
pub struct PyCMethodObject {
pub func: PyCFunctionObject,
pub mm_class: *mut PyTypeObject,
}
extern_libpython! {
pub static mut PyCMethod_Type: PyTypeObject;
}
#[inline]
pub unsafe fn PyCMethod_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyCMethod_Type)
}
#[inline]
pub unsafe fn PyCMethod_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyCMethod_Type)
}
#[cfg(not(GraalPy))]
#[inline]
pub unsafe fn PyCFunction_GET_FUNCTION(func: *mut PyObject) -> PyMethodDefPointer {
debug_assert_eq!(PyCMethod_Check(func), 1);
let func = func.cast::<PyCFunctionObject>();
(*(*func).m_ml).ml_meth
}
#[cfg(not(GraalPy))]
#[inline]
pub unsafe fn PyCFunction_GET_SELF(func: *mut PyObject) -> *mut PyObject {
debug_assert_eq!(PyCMethod_Check(func), 1);
let func = func.cast::<PyCFunctionObject>();
if (*(*func).m_ml).ml_flags & METH_STATIC != 0 {
core::ptr::null_mut()
} else {
(*func).m_self
}
}
#[cfg(not(GraalPy))]
#[inline]
pub unsafe fn PyCFunction_GET_FLAGS(func: *mut PyObject) -> c_int {
debug_assert_eq!(PyCMethod_Check(func), 1);
let func = func.cast::<PyCFunctionObject>();
(*(*func).m_ml).ml_flags
}
#[cfg(not(GraalPy))]
#[inline]
pub unsafe fn PyCFunction_GET_CLASS(func: *mut PyObject) -> *mut PyTypeObject {
debug_assert_eq!(PyCMethod_Check(func), 1);
let func = func.cast::<PyCFunctionObject>();
if (*(*func).m_ml).ml_flags & METH_METHOD != 0 {
let func = func.cast::<PyCMethodObject>();
(*func).mm_class
} else {
core::ptr::null_mut()
}
}
+102
View File
@@ -0,0 +1,102 @@
pub(crate) mod abstract_;
pub(crate) mod bytearrayobject;
pub(crate) mod bytesobject;
pub(crate) mod cellobject;
#[cfg(not(PyPy))]
pub(crate) mod ceval;
pub(crate) mod code;
pub(crate) mod compile;
pub(crate) mod complexobject;
#[cfg(all(Py_3_14, Py_GIL_DISABLED))]
pub(crate) mod critical_section;
pub(crate) mod descrobject;
pub(crate) mod dictobject;
// skipped fileobject.h
// skipped fileutils.h
pub(crate) mod frameobject;
pub(crate) mod funcobject;
pub(crate) mod genobject;
#[cfg(any(not(PyPy), Py_3_14))]
pub(crate) mod import;
#[cfg(not(PyPy))]
pub(crate) mod initconfig;
// skipped interpreteridobject.h
pub(crate) mod listobject;
#[cfg(Py_3_13)]
pub(crate) mod lock;
#[cfg(Py_3_14)]
pub(crate) mod longintrepr;
pub(crate) mod longobject;
pub(crate) mod marshal;
#[cfg(all(Py_3_9, not(PyPy)))]
pub(crate) mod methodobject;
pub(crate) mod object;
pub(crate) mod objimpl;
pub(crate) mod pyatomic;
pub(crate) mod pydebug;
pub(crate) mod pyerrors;
#[cfg(not(PyPy))]
pub(crate) mod pylifecycle;
pub(crate) mod pymem;
pub(crate) mod pystate;
pub(crate) mod pythonrun;
// skipped sysmodule.h
pub(crate) mod floatobject;
pub(crate) mod pyframe;
pub(crate) mod pyhash;
pub(crate) mod setobject;
pub(crate) mod traceback;
pub(crate) mod tupleobject;
pub(crate) mod unicodeobject;
pub(crate) mod warnings;
pub(crate) mod weakrefobject;
pub use self::abstract_::*;
pub use self::bytearrayobject::*;
pub use self::bytesobject::*;
pub use self::cellobject::*;
#[cfg(not(PyPy))]
pub use self::ceval::*;
pub use self::code::*;
pub use self::compile::*;
pub use self::complexobject::*;
#[cfg(all(Py_3_14, Py_GIL_DISABLED))]
pub use self::critical_section::{PyCriticalSection2_BeginMutex, PyCriticalSection_BeginMutex};
pub use self::descrobject::*;
pub use self::dictobject::*;
pub use self::floatobject::*;
pub use self::frameobject::*;
pub use self::funcobject::*;
pub use self::genobject::*;
#[cfg(any(not(PyPy), Py_3_14))]
pub use self::import::*;
#[cfg(not(PyPy))]
pub use self::initconfig::*;
pub use self::listobject::*;
#[cfg(Py_3_13)]
pub use self::lock::*;
#[cfg(Py_3_14)]
pub use self::longintrepr::*;
pub use self::longobject::*;
pub use self::marshal::*;
#[cfg(all(Py_3_9, not(PyPy)))]
pub use self::methodobject::*;
pub use self::object::*;
pub use self::objimpl::*;
pub use self::pydebug::*;
pub use self::pyerrors::*;
pub use self::pyframe::*;
#[cfg(any(not(PyPy), Py_3_13))]
pub use self::pyhash::*;
#[cfg(not(PyPy))]
pub use self::pylifecycle::*;
pub use self::pymem::*;
pub use self::pystate::*;
pub use self::pythonrun::*;
pub use self::setobject::*;
pub use self::traceback::*;
pub use self::tupleobject::*;
pub use self::unicodeobject::*;
pub use self::warnings::*;
#[cfg(not(any(PyPy, GraalPy)))]
pub use self::weakrefobject::*;
+412
View File
@@ -0,0 +1,412 @@
use crate::vectorcallfunc;
use crate::{object, PyGetSetDef, PyMemberDef, PyMethodDef, PyObject, Py_ssize_t};
use core::ffi::{c_char, c_int, c_uint, c_void};
// skipped private _Py_NewReference
// skipped private _Py_NewReferenceNoTotal
// skipped private _Py_ResurrectReference
// skipped private _Py_ForgetReference
// skipped private _Py_GetGlobalRefTotal
// skipped private _Py_GetRefTotal
// skipped private _Py_GetLegacyRefTotal
// skipped private _PyInterpreterState_GetRefTotal
// skipped private _Py_Identifier
// skipped private _Py_static_string_init
// skipped private _Py_static_string
// skipped private _Py_IDENTIFIER
#[cfg(not(Py_3_11))] // moved to src/buffer.rs from Python
mod bufferinfo {
use crate::Py_ssize_t;
use core::ffi::{c_char, c_int, c_void};
use core::ptr;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Py_buffer {
pub buf: *mut c_void,
/// Owned reference
pub obj: *mut crate::PyObject,
pub len: Py_ssize_t,
pub itemsize: Py_ssize_t,
pub readonly: c_int,
pub ndim: c_int,
pub format: *mut c_char,
pub shape: *mut Py_ssize_t,
pub strides: *mut Py_ssize_t,
pub suboffsets: *mut Py_ssize_t,
pub internal: *mut c_void,
#[cfg(PyPy)]
pub flags: c_int,
#[cfg(PyPy)]
pub _strides: [Py_ssize_t; PyBUF_MAX_NDIM as usize],
#[cfg(PyPy)]
pub _shape: [Py_ssize_t; PyBUF_MAX_NDIM as usize],
}
impl Py_buffer {
#[allow(clippy::new_without_default)]
pub const fn new() -> Self {
Py_buffer {
buf: ptr::null_mut(),
obj: ptr::null_mut(),
len: 0,
itemsize: 0,
readonly: 0,
ndim: 0,
format: ptr::null_mut(),
shape: ptr::null_mut(),
strides: ptr::null_mut(),
suboffsets: ptr::null_mut(),
internal: ptr::null_mut(),
#[cfg(PyPy)]
flags: 0,
#[cfg(PyPy)]
_strides: [0; PyBUF_MAX_NDIM as usize],
#[cfg(PyPy)]
_shape: [0; PyBUF_MAX_NDIM as usize],
}
}
}
pub type getbufferproc = unsafe extern "C" fn(
arg1: *mut crate::PyObject,
arg2: *mut Py_buffer,
arg3: c_int,
) -> c_int;
pub type releasebufferproc =
unsafe extern "C" fn(arg1: *mut crate::PyObject, arg2: *mut Py_buffer);
/// Maximum number of dimensions
pub const PyBUF_MAX_NDIM: c_int = if cfg!(PyPy) { 36 } else { 64 };
/* Flags for getting buffers */
pub const PyBUF_SIMPLE: c_int = 0;
pub const PyBUF_WRITABLE: c_int = 0x0001;
/* we used to include an E, backwards compatible alias */
pub const PyBUF_WRITEABLE: c_int = PyBUF_WRITABLE;
pub const PyBUF_FORMAT: c_int = 0x0004;
pub const PyBUF_ND: c_int = 0x0008;
pub const PyBUF_STRIDES: c_int = 0x0010 | PyBUF_ND;
pub const PyBUF_C_CONTIGUOUS: c_int = 0x0020 | PyBUF_STRIDES;
pub const PyBUF_F_CONTIGUOUS: c_int = 0x0040 | PyBUF_STRIDES;
pub const PyBUF_ANY_CONTIGUOUS: c_int = 0x0080 | PyBUF_STRIDES;
pub const PyBUF_INDIRECT: c_int = 0x0100 | PyBUF_STRIDES;
pub const PyBUF_CONTIG: c_int = PyBUF_ND | PyBUF_WRITABLE;
pub const PyBUF_CONTIG_RO: c_int = PyBUF_ND;
pub const PyBUF_STRIDED: c_int = PyBUF_STRIDES | PyBUF_WRITABLE;
pub const PyBUF_STRIDED_RO: c_int = PyBUF_STRIDES;
pub const PyBUF_RECORDS: c_int = PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT;
pub const PyBUF_RECORDS_RO: c_int = PyBUF_STRIDES | PyBUF_FORMAT;
pub const PyBUF_FULL: c_int = PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT;
pub const PyBUF_FULL_RO: c_int = PyBUF_INDIRECT | PyBUF_FORMAT;
pub const PyBUF_READ: c_int = 0x100;
pub const PyBUF_WRITE: c_int = 0x200;
}
#[cfg(not(Py_3_11))]
pub use self::bufferinfo::*;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyNumberMethods {
pub nb_add: Option<object::binaryfunc>,
pub nb_subtract: Option<object::binaryfunc>,
pub nb_multiply: Option<object::binaryfunc>,
pub nb_remainder: Option<object::binaryfunc>,
pub nb_divmod: Option<object::binaryfunc>,
pub nb_power: Option<object::ternaryfunc>,
pub nb_negative: Option<object::unaryfunc>,
pub nb_positive: Option<object::unaryfunc>,
pub nb_absolute: Option<object::unaryfunc>,
pub nb_bool: Option<object::inquiry>,
pub nb_invert: Option<object::unaryfunc>,
pub nb_lshift: Option<object::binaryfunc>,
pub nb_rshift: Option<object::binaryfunc>,
pub nb_and: Option<object::binaryfunc>,
pub nb_xor: Option<object::binaryfunc>,
pub nb_or: Option<object::binaryfunc>,
pub nb_int: Option<object::unaryfunc>,
pub nb_reserved: *mut c_void,
pub nb_float: Option<object::unaryfunc>,
pub nb_inplace_add: Option<object::binaryfunc>,
pub nb_inplace_subtract: Option<object::binaryfunc>,
pub nb_inplace_multiply: Option<object::binaryfunc>,
pub nb_inplace_remainder: Option<object::binaryfunc>,
pub nb_inplace_power: Option<object::ternaryfunc>,
pub nb_inplace_lshift: Option<object::binaryfunc>,
pub nb_inplace_rshift: Option<object::binaryfunc>,
pub nb_inplace_and: Option<object::binaryfunc>,
pub nb_inplace_xor: Option<object::binaryfunc>,
pub nb_inplace_or: Option<object::binaryfunc>,
pub nb_floor_divide: Option<object::binaryfunc>,
pub nb_true_divide: Option<object::binaryfunc>,
pub nb_inplace_floor_divide: Option<object::binaryfunc>,
pub nb_inplace_true_divide: Option<object::binaryfunc>,
pub nb_index: Option<object::unaryfunc>,
pub nb_matrix_multiply: Option<object::binaryfunc>,
pub nb_inplace_matrix_multiply: Option<object::binaryfunc>,
}
#[repr(C)]
#[derive(Clone)]
pub struct PySequenceMethods {
pub sq_length: Option<object::lenfunc>,
pub sq_concat: Option<object::binaryfunc>,
pub sq_repeat: Option<object::ssizeargfunc>,
pub sq_item: Option<object::ssizeargfunc>,
pub was_sq_slice: *mut c_void,
pub sq_ass_item: Option<object::ssizeobjargproc>,
pub was_sq_ass_slice: *mut c_void,
pub sq_contains: Option<object::objobjproc>,
pub sq_inplace_concat: Option<object::binaryfunc>,
pub sq_inplace_repeat: Option<object::ssizeargfunc>,
}
#[repr(C)]
#[derive(Clone, Default)]
pub struct PyMappingMethods {
pub mp_length: Option<object::lenfunc>,
pub mp_subscript: Option<object::binaryfunc>,
pub mp_ass_subscript: Option<object::objobjargproc>,
}
#[cfg(Py_3_10)]
pub type sendfunc = unsafe extern "C" fn(
iter: *mut PyObject,
value: *mut PyObject,
result: *mut *mut PyObject,
) -> object::PySendResult;
#[repr(C)]
#[derive(Clone, Default)]
pub struct PyAsyncMethods {
pub am_await: Option<object::unaryfunc>,
pub am_aiter: Option<object::unaryfunc>,
pub am_anext: Option<object::unaryfunc>,
#[cfg(Py_3_10)]
pub am_send: Option<sendfunc>,
}
#[repr(C)]
#[derive(Clone, Default)]
pub struct PyBufferProcs {
pub bf_getbuffer: Option<crate::getbufferproc>,
pub bf_releasebuffer: Option<crate::releasebufferproc>,
}
pub type printfunc =
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut ::libc::FILE, arg3: c_int) -> c_int;
#[repr(C)]
#[derive(Debug)]
pub struct PyTypeObject {
pub ob_base: object::PyVarObject,
pub tp_name: *const c_char,
pub tp_basicsize: Py_ssize_t,
pub tp_itemsize: Py_ssize_t,
pub tp_dealloc: Option<object::destructor>,
pub tp_vectorcall_offset: Py_ssize_t,
pub tp_getattr: Option<object::getattrfunc>,
pub tp_setattr: Option<object::setattrfunc>,
pub tp_as_async: *mut PyAsyncMethods,
pub tp_repr: Option<object::reprfunc>,
pub tp_as_number: *mut PyNumberMethods,
pub tp_as_sequence: *mut PySequenceMethods,
pub tp_as_mapping: *mut PyMappingMethods,
pub tp_hash: Option<object::hashfunc>,
pub tp_call: Option<object::ternaryfunc>,
pub tp_str: Option<object::reprfunc>,
pub tp_getattro: Option<object::getattrofunc>,
pub tp_setattro: Option<object::setattrofunc>,
pub tp_as_buffer: *mut PyBufferProcs,
#[cfg(not(Py_GIL_DISABLED))]
pub tp_flags: core::ffi::c_ulong,
#[cfg(Py_GIL_DISABLED)]
pub tp_flags: crate::impl_::AtomicCULong,
pub tp_doc: *const c_char,
pub tp_traverse: Option<object::traverseproc>,
pub tp_clear: Option<object::inquiry>,
pub tp_richcompare: Option<object::richcmpfunc>,
pub tp_weaklistoffset: Py_ssize_t,
pub tp_iter: Option<object::getiterfunc>,
pub tp_iternext: Option<object::iternextfunc>,
pub tp_methods: *mut PyMethodDef,
pub tp_members: *mut PyMemberDef,
pub tp_getset: *mut PyGetSetDef,
pub tp_base: *mut PyTypeObject,
pub tp_dict: *mut object::PyObject,
pub tp_descr_get: Option<object::descrgetfunc>,
pub tp_descr_set: Option<object::descrsetfunc>,
pub tp_dictoffset: Py_ssize_t,
pub tp_init: Option<object::initproc>,
pub tp_alloc: Option<object::allocfunc>,
pub tp_new: Option<object::newfunc>,
pub tp_free: Option<object::freefunc>,
pub tp_is_gc: Option<object::inquiry>,
pub tp_bases: *mut object::PyObject,
pub tp_mro: *mut object::PyObject,
pub tp_cache: *mut object::PyObject,
pub tp_subclasses: *mut object::PyObject,
pub tp_weaklist: *mut object::PyObject,
pub tp_del: Option<object::destructor>,
pub tp_version_tag: c_uint,
pub tp_finalize: Option<object::destructor>,
pub tp_vectorcall: Option<vectorcallfunc>,
#[cfg(Py_3_12)]
pub tp_watched: c_char,
#[cfg(not(any(PyPy, Py_3_9)))]
pub tp_print: Option<printfunc>,
#[cfg(py_sys_config = "COUNT_ALLOCS")]
pub tp_allocs: Py_ssize_t,
#[cfg(py_sys_config = "COUNT_ALLOCS")]
pub tp_frees: Py_ssize_t,
#[cfg(py_sys_config = "COUNT_ALLOCS")]
pub tp_maxalloc: Py_ssize_t,
#[cfg(py_sys_config = "COUNT_ALLOCS")]
pub tp_prev: *mut PyTypeObject,
#[cfg(py_sys_config = "COUNT_ALLOCS")]
pub tp_next: *mut PyTypeObject,
#[cfg(Py_3_13)]
pub tp_versions_used: u16,
#[cfg(Py_3_15)]
pub _tp_iteritem: Option<object::_Py_iteritemfunc>,
}
#[cfg(Py_3_11)]
#[repr(C)]
#[derive(Clone)]
struct _specialization_cache {
getitem: *mut PyObject,
#[cfg(Py_3_12)]
getitem_version: u32,
#[cfg(Py_3_13)]
init: *mut PyObject,
}
#[repr(C)]
pub struct PyHeapTypeObject {
pub ht_type: PyTypeObject,
pub as_async: PyAsyncMethods,
pub as_number: PyNumberMethods,
pub as_mapping: PyMappingMethods,
pub as_sequence: PySequenceMethods,
pub as_buffer: PyBufferProcs,
pub ht_name: *mut object::PyObject,
pub ht_slots: *mut object::PyObject,
pub ht_qualname: *mut object::PyObject,
#[cfg(not(PyPy))]
pub ht_cached_keys: *mut c_void,
#[cfg(Py_3_9)]
pub ht_module: *mut object::PyObject,
#[cfg(all(Py_3_11, not(PyPy)))]
_ht_tpname: *mut c_char,
#[cfg(Py_3_14)]
pub ht_token: *mut c_void,
#[cfg(all(Py_3_11, not(PyPy)))]
_spec_cache: _specialization_cache,
#[cfg(all(Py_GIL_DISABLED, Py_3_14))]
pub unique_id: Py_ssize_t,
}
#[inline]
#[cfg(not(Py_3_11))]
pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut PyMemberDef {
let py_type = object::Py_TYPE(etype as *mut object::PyObject);
let ptr = etype.byte_offset((*py_type).tp_basicsize);
ptr as *mut PyMemberDef
}
// skipped private _PyType_Name
// skipped private _PyType_Lookup
// skipped private _PyType_LookupRef
extern_libpython! {
#[cfg(Py_3_12)]
pub fn PyType_GetDict(o: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_Print")]
pub fn PyObject_Print(o: *mut PyObject, fp: *mut ::libc::FILE, flags: c_int) -> c_int;
// skipped private _Py_BreakPoint
// skipped private _PyObject_Dump
// skipped _PyObject_GetAttrId
// skipped private _PyObject_GetDictPtr
pub fn PyObject_CallFinalizer(arg1: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyObject_CallFinalizerFromDealloc")]
pub fn PyObject_CallFinalizerFromDealloc(arg1: *mut PyObject) -> c_int;
// skipped private _PyObject_GenericGetAttrWithDict
// skipped private _PyObject_GenericSetAttrWithDict
// skipped private _PyObject_FunctionStr
}
// skipped Py_SETREF
// skipped Py_XSETREF
// skipped private _PyObject_ASSERT_FROM
// skipped private _PyObject_ASSERT_WITH_MSG
// skipped private _PyObject_ASSERT
// skipped private _PyObject_ASSERT_FAILED_MSG
// skipped private _PyObject_AssertFailed
// skipped private _PyTrash_begin
// skipped private _PyTrash_end
// skipped _PyTrash_thread_deposit_object
// skipped _PyTrash_thread_destroy_chain
// skipped Py_TRASHCAN_BEGIN
// skipped Py_TRASHCAN_END
// skipped PyObject_GetItemData
// skipped PyObject_VisitManagedDict
// skipped _PyObject_SetManagedDict
// skipped PyObject_ClearManagedDict
// skipped TYPE_MAX_WATCHERS
// skipped PyType_WatchCallback
// skipped PyType_AddWatcher
// skipped PyType_ClearWatcher
// skipped PyType_Watch
// skipped PyType_Unwatch
// skipped PyUnstable_Type_AssignVersionTag
// skipped PyRefTracerEvent
// skipped PyRefTracer
// skipped PyRefTracer_SetTracer
// skipped PyRefTracer_GetTracer
#[cfg(Py_3_14)]
extern_libpython! {
// skipped PyUnstable_Object_EnableDeferredRefcount
pub fn PyUnstable_Object_IsUniqueReferencedTemporary(obj: *mut PyObject) -> c_int;
// skipped PyUnstable_IsImmortal
pub fn PyUnstable_TryIncRef(obj: *mut PyObject) -> c_int;
pub fn PyUnstable_EnableTryIncRef(obj: *mut PyObject);
pub fn PyUnstable_Object_IsUniquelyReferenced(op: *mut PyObject) -> c_int;
}
#[cfg(Py_3_15)]
extern_libpython! {
pub fn PyUnstable_SetImmortal(op: *mut PyObject) -> c_int;
}
+62
View File
@@ -0,0 +1,62 @@
use core::ffi::c_int;
#[cfg(not(all(Py_3_11, any(PyPy, GraalPy))))]
use libc::size_t;
#[cfg(not(any(PyPy, GraalPy)))]
use core::ffi::c_void;
use crate::object::*;
// skipped _PyObject_SIZE
// skipped _PyObject_VAR_SIZE
// skipped _Py_GetAllocatedBlocks
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyObjectArenaAllocator {
pub ctx: *mut c_void,
pub alloc: Option<extern "C" fn(ctx: *mut c_void, size: size_t) -> *mut c_void>,
pub free: Option<extern "C" fn(ctx: *mut c_void, ptr: *mut c_void, size: size_t)>,
}
extern_libpython! {
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyObject_GetArenaAllocator(allocator: *mut PyObjectArenaAllocator);
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyObject_SetArenaAllocator(allocator: *mut PyObjectArenaAllocator);
#[cfg(Py_3_9)]
pub fn PyObject_IS_GC(o: *mut PyObject) -> c_int;
#[cfg(all(Py_3_9, not(any(PyPy, GraalPy))))]
pub fn PyObject_GET_WEAKREFS_LISTPTR(o: *mut PyObject) -> *mut *mut PyObject;
}
#[inline]
#[cfg(not(Py_3_9))]
pub unsafe fn PyObject_GET_WEAKREFS_LISTPTR(o: *mut PyObject) -> *mut *mut PyObject {
let weaklistoffset = (*Py_TYPE(o)).tp_weaklistoffset;
o.byte_offset(weaklistoffset) as *mut *mut PyObject
}
#[inline]
#[cfg(not(Py_3_9))]
pub unsafe fn PyObject_IS_GC(o: *mut PyObject) -> c_int {
(crate::PyType_IS_GC(Py_TYPE(o)) != 0
&& match (*Py_TYPE(o)).tp_is_gc {
Some(tp_is_gc) => tp_is_gc(o) != 0,
None => true,
}) as c_int
}
// skipped _PyObject_GC_Malloc
// skipped _PyObject_GC_Calloc
#[inline]
pub unsafe fn PyType_SUPPORTS_WEAKREFS(t: *mut PyTypeObject) -> c_int {
((*t).tp_weaklistoffset > 0) as c_int
}
// skipped PyUnstable_Object_GC_NewWithExtraData
+165
View File
@@ -0,0 +1,165 @@
use crate::pyport::Py_ssize_t;
use core::sync::atomic::{AtomicIsize, Ordering};
// skipped _Py_atomic_add_int
// skipped _Py_atomic_add_int8
// skipped _Py_atomic_add_int16
// skipped _Py_atomic_add_int32
// skipped _Py_atomic_add_int64
// skipped _Py_atomic_add_intptr
// skipped _Py_atomic_add_uint
// skipped _Py_atomic_add_uint8
// skipped _Py_atomic_add_uint16
// skipped _Py_atomic_add_uint32
// skipped _Py_atomic_add_uint64
// skipped _Py_atomic_add_uintptr
// skipped _Py_atomic_add_ssize
// skipped _Py_atomic_compare_exchange_int
// skipped _Py_atomic_compare_exchange_int8
// skipped _Py_atomic_compare_exchange_int16
// skipped _Py_atomic_compare_exchange_int32
// skipped _Py_atomic_compare_exchange_int64
// skipped _Py_atomic_compare_exchange_intptr
// skipped _Py_atomic_compare_exchange_uint
// skipped _Py_atomic_compare_exchange_uint8
// skipped _Py_atomic_compare_exchange_uint16
// skipped _Py_atomic_compare_exchange_uint32
// skipped _Py_atomic_compare_exchange_uint64
// skipped _Py_atomic_compare_exchange_uintptr
// skipped _Py_atomic_compare_exchange_ssize
// skipped _Py_atomic_compare_exchange_ptr
// skipped _Py_atomic_exchange_int
// skipped _Py_atomic_exchange_int8
// skipped _Py_atomic_exchange_int16
// skipped _Py_atomic_exchange_int32
// skipped _Py_atomic_exchange_int64
// skipped _Py_atomic_exchange_intptr
// skipped _Py_atomic_exchange_uint
// skipped _Py_atomic_exchange_uint8
// skipped _Py_atomic_exchange_uint16
// skipped _Py_atomic_exchange_uint32
// skipped _Py_atomic_exchange_uint64
// skipped _Py_atomic_exchange_uintptr
// skipped _Py_atomic_exchange_ssize
// skipped _Py_atomic_exchange_ptr
// skipped _Py_atomic_and_uint8
// skipped _Py_atomic_and_uint16
// skipped _Py_atomic_and_uint32
// skipped _Py_atomic_and_uint64
// skipped _Py_atomic_and_uintptr
// skipped _Py_atomic_or_uint8
// skipped _Py_atomic_or_uint16
// skipped _Py_atomic_or_uint32
// skipped _Py_atomic_or_uint64
// skipped _Py_atomic_or_uintptr
// skipped _Py_atomic_load_int
// skipped _Py_atomic_load_int8
// skipped _Py_atomic_load_int16
// skipped _Py_atomic_load_int32
// skipped _Py_atomic_load_int64
// skipped _Py_atomic_load_intptr
// skipped _Py_atomic_load_uint8
// skipped _Py_atomic_load_uint16
// skipped _Py_atomic_load_uint32
// skipped _Py_atomic_load_uint64
// skipped _Py_atomic_load_uintptr
// skipped _Py_atomic_load_uint
// skipped _Py_atomic_load_ssize
// skipped _Py_atomic_load_ptr
// skipped _Py_atomic_load_int_relaxed
// skipped _Py_atomic_load_char_relaxed
// skipped _Py_atomic_load_uchar_relaxed
// skipped _Py_atomic_load_short_relaxed
// skipped _Py_atomic_load_ushort_relaxed
// skipped _Py_atomic_load_long_relaxed
// skipped _Py_atomic_load_double_relaxed
// skipped _Py_atomic_load_llong_relaxed
// skipped _Py_atomic_load_int8_relaxed
// skipped _Py_atomic_load_int16_relaxed
// skipped _Py_atomic_load_int32_relaxed
// skipped _Py_atomic_load_int64_relaxed
// skipped _Py_atomic_load_intptr_relaxed
// skipped _Py_atomic_load_uint8_relaxed
// skipped _Py_atomic_load_uint16_relaxed
// skipped _Py_atomic_load_uint32_relaxed
// skipped _Py_atomic_load_uint64_relaxed
// skipped _Py_atomic_load_uintptr_relaxed
// skipped _Py_atomic_load_uint_relaxed
#[inline]
pub(crate) unsafe fn _Py_atomic_load_ssize_relaxed(value: *const Py_ssize_t) -> Py_ssize_t {
AtomicIsize::from_ptr(value.cast_mut()).load(Ordering::Relaxed)
}
// skipped _Py_atomic_load_ptr_relaxed
// skipped _Py_atomic_load_ullong_relaxed
// skipped _Py_atomic_store_int
// skipped _Py_atomic_store_int8
// skipped _Py_atomic_store_int16
// skipped _Py_atomic_store_int32
// skipped _Py_atomic_store_int64
// skipped _Py_atomic_store_intptr
// skipped _Py_atomic_store_uint8
// skipped _Py_atomic_store_uint16
// skipped _Py_atomic_store_uint32
// skipped _Py_atomic_store_uint64
// skipped _Py_atomic_store_uintptr
// skipped _Py_atomic_store_uint
// skipped _Py_atomic_store_ptr
// skipped _Py_atomic_store_ssize
// skipped _Py_atomic_store_int_relaxed
// skipped _Py_atomic_store_int8_relaxed
// skipped _Py_atomic_store_int16_relaxed
// skipped _Py_atomic_store_int32_relaxed
// skipped _Py_atomic_store_int64_relaxed
// skipped _Py_atomic_store_intptr_relaxed
// skipped _Py_atomic_store_uint8_relaxed
// skipped _Py_atomic_store_uint16_relaxed
// skipped _Py_atomic_store_uint32_relaxed
// skipped _Py_atomic_store_uint64_relaxed
// skipped _Py_atomic_store_uintptr_relaxed
// skipped _Py_atomic_store_uint_relaxed
// skipped _Py_atomic_store_ptr_relaxed
// skipped _Py_atomic_store_ssize_relaxed
// skipped _Py_atomic_store_ullong_relaxed
// skipped _Py_atomic_store_char_relaxed
// skipped _Py_atomic_store_uchar_relaxed
// skipped _Py_atomic_store_short_relaxed
// skipped _Py_atomic_store_ushort_relaxed
// skipped _Py_atomic_store_long_relaxed
// skipped _Py_atomic_store_float_relaxed
// skipped _Py_atomic_store_double_relaxed
// skipped _Py_atomic_store_llong_relaxed
// skipped _Py_atomic_load_ptr_acquire
// skipped _Py_atomic_load_uintptr_acquire
// skipped _Py_atomic_store_ptr_release
// skipped _Py_atomic_store_uintptr_release
// skipped _Py_atomic_store_ssize_release
// skipped _Py_atomic_store_int8_release
// skipped _Py_atomic_store_int_release
// skipped _Py_atomic_load_int_acquire
// skipped _Py_atomic_store_uint_release
// skipped _Py_atomic_store_uint32_release
// skipped _Py_atomic_store_uint64_release
// skipped _Py_atomic_load_uint64_acquire
// skipped _Py_atomic_load_uint32_acquire
// skipped _Py_atomic_load_ssize_acquire
// skipped _Py_atomic_fence_seq_cst
// skipped _Py_atomic_fence_acquire
// skipped _Py_atomic_fence_release
// skipped _Py_atomic_load_ptr_consume
// skipped _Py_atomic_load_ulong
// skipped _Py_atomic_load_ulong_relaxed
// skipped _Py_atomic_store_ulong
// skipped _Py_atomic_store_ulong_relaxed
+71
View File
@@ -0,0 +1,71 @@
use core::ffi::{c_char, c_int};
#[cfg(not(Py_LIMITED_API))]
extern_libpython! {
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_DebugFlag")]
pub static mut Py_DebugFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_VerboseFlag")]
pub static mut Py_VerboseFlag: c_int;
#[deprecated(note = "Python 3.12")]
pub static mut Py_QuietFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_InteractiveFlag")]
pub static mut Py_InteractiveFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_InspectFlag")]
pub static mut Py_InspectFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_OptimizeFlag")]
pub static mut Py_OptimizeFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_NoSiteFlag")]
pub static mut Py_NoSiteFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_BytesWarningFlag")]
pub static mut Py_BytesWarningFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_UseClassExceptionsFlag")]
pub static mut Py_UseClassExceptionsFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_FrozenFlag")]
pub static mut Py_FrozenFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_IgnoreEnvironmentFlag")]
pub static mut Py_IgnoreEnvironmentFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_DontWriteBytecodeFlag")]
pub static mut Py_DontWriteBytecodeFlag: c_int;
#[deprecated(note = "Python 3.12")]
#[cfg_attr(PyPy, link_name = "PyPy_NoUserSiteDirectory")]
pub static mut Py_NoUserSiteDirectory: c_int;
#[deprecated(note = "Python 3.12")]
pub static mut Py_UnbufferedStdioFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_HashRandomizationFlag")]
pub static mut Py_HashRandomizationFlag: c_int;
#[deprecated(note = "Python 3.12")]
pub static mut Py_IsolatedFlag: c_int;
#[cfg(windows)]
#[deprecated(note = "Python 3.12")]
pub static mut Py_LegacyWindowsFSEncodingFlag: c_int;
#[cfg(windows)]
#[deprecated(note = "Python 3.12")]
pub static mut Py_LegacyWindowsStdioFlag: c_int;
}
extern_libpython! {
#[cfg(Py_3_11)]
pub fn Py_GETENV(name: *const c_char) -> *mut c_char;
}
#[cfg(not(Py_3_11))]
#[inline(always)]
pub unsafe fn Py_GETENV(name: *const c_char) -> *mut c_char {
#[allow(deprecated)]
if Py_IgnoreEnvironmentFlag != 0 {
core::ptr::null_mut()
} else {
libc::getenv(name)
}
}
+190
View File
@@ -0,0 +1,190 @@
use crate::PyObject;
#[cfg(not(any(PyPy, GraalPy)))]
use crate::Py_ssize_t;
#[repr(C)]
#[derive(Debug)]
pub struct PyBaseExceptionObject {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub dict: *mut PyObject,
#[cfg(not(PyPy))]
pub args: *mut PyObject,
#[cfg(all(Py_3_11, not(PyPy)))]
pub notes: *mut PyObject,
#[cfg(not(PyPy))]
pub traceback: *mut PyObject,
#[cfg(not(PyPy))]
pub context: *mut PyObject,
#[cfg(not(PyPy))]
pub cause: *mut PyObject,
#[cfg(not(PyPy))]
pub suppress_context: char,
}
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
pub struct PySyntaxErrorObject {
pub ob_base: PyObject,
pub dict: *mut PyObject,
pub args: *mut PyObject,
#[cfg(Py_3_11)]
pub notes: *mut PyObject,
pub traceback: *mut PyObject,
pub context: *mut PyObject,
pub cause: *mut PyObject,
pub suppress_context: char,
pub msg: *mut PyObject,
pub filename: *mut PyObject,
pub lineno: *mut PyObject,
pub offset: *mut PyObject,
#[cfg(Py_3_10)]
pub end_lineno: *mut PyObject,
#[cfg(Py_3_10)]
pub end_offset: *mut PyObject,
pub text: *mut PyObject,
pub print_file_and_line: *mut PyObject,
#[cfg(Py_3_14)]
pub metadata: *mut PyObject,
}
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
pub struct PyImportErrorObject {
pub ob_base: PyObject,
pub dict: *mut PyObject,
pub args: *mut PyObject,
#[cfg(Py_3_11)]
pub notes: *mut PyObject,
pub traceback: *mut PyObject,
pub context: *mut PyObject,
pub cause: *mut PyObject,
pub suppress_context: char,
pub msg: *mut PyObject,
pub name: *mut PyObject,
pub path: *mut PyObject,
#[cfg(Py_3_12)]
pub name_from: *mut PyObject,
}
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
pub struct PyUnicodeErrorObject {
pub ob_base: PyObject,
pub dict: *mut PyObject,
pub args: *mut PyObject,
#[cfg(Py_3_11)]
pub notes: *mut PyObject,
pub traceback: *mut PyObject,
pub context: *mut PyObject,
pub cause: *mut PyObject,
pub suppress_context: char,
pub encoding: *mut PyObject,
pub object: *mut PyObject,
pub start: Py_ssize_t,
pub end: Py_ssize_t,
pub reason: *mut PyObject,
}
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
pub struct PySystemExitObject {
pub ob_base: PyObject,
pub dict: *mut PyObject,
pub args: *mut PyObject,
#[cfg(Py_3_11)]
pub notes: *mut PyObject,
pub traceback: *mut PyObject,
pub context: *mut PyObject,
pub cause: *mut PyObject,
pub suppress_context: char,
pub code: *mut PyObject,
}
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
pub struct PyOSErrorObject {
pub ob_base: PyObject,
pub dict: *mut PyObject,
pub args: *mut PyObject,
#[cfg(Py_3_11)]
pub notes: *mut PyObject,
pub traceback: *mut PyObject,
pub context: *mut PyObject,
pub cause: *mut PyObject,
pub suppress_context: char,
pub myerrno: *mut PyObject,
pub strerror: *mut PyObject,
pub filename: *mut PyObject,
pub filename2: *mut PyObject,
#[cfg(windows)]
pub winerror: *mut PyObject,
pub written: Py_ssize_t,
}
#[repr(C)]
#[derive(Debug)]
pub struct PyStopIterationObject {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub dict: *mut PyObject,
#[cfg(not(PyPy))]
pub args: *mut PyObject,
#[cfg(all(Py_3_11, not(PyPy)))]
pub notes: *mut PyObject,
#[cfg(not(PyPy))]
pub traceback: *mut PyObject,
#[cfg(not(PyPy))]
pub context: *mut PyObject,
#[cfg(not(PyPy))]
pub cause: *mut PyObject,
#[cfg(not(PyPy))]
pub suppress_context: char,
pub value: *mut PyObject,
}
// skipped _PyErr_ChainExceptions
// skipped PyNameErrorObject
// skipped PyAttributeErrorObject
// skipped PyEnvironmentErrorObject
// skipped PyWindowsErrorObject
// skipped _PyErr_SetKeyError
// skipped _PyErr_GetTopmostException
// skipped _PyErr_GetExcInfo
// skipped PyErr_SetFromErrnoWithUnicodeFilename
// skipped _PyErr_FormatFromCause
// skipped PyErr_SetFromWindowsErrWithUnicodeFilename
// skipped PyErr_SetExcFromWindowsErrWithUnicodeFilename
// skipped _PyErr_TrySetFromCause
// skipped PySignal_SetWakeupFd
// skipped _PyErr_CheckSignals
// skipped PyErr_SyntaxLocationObject
// skipped PyErr_RangedSyntaxLocationObject
// skipped PyErr_ProgramTextObject
// skipped _PyErr_ProgramDecodedTextObject
// skipped _PyUnicodeTranslateError_Create
// skipped _PyErr_WriteUnraisableMsg
// skipped _Py_FatalErrorFunc
// skipped _Py_FatalErrorFormat
// skipped Py_FatalError
+76
View File
@@ -0,0 +1,76 @@
#[cfg(any(Py_3_11, all(Py_3_9, not(PyPy))))]
use crate::PyFrameObject;
use crate::{PyObject, PyTypeObject, Py_IS_TYPE};
#[cfg(Py_3_12)]
use core::ffi::c_char;
use core::ffi::c_int;
#[cfg(all(Py_3_11, not(PyPy)))]
opaque_struct!(pub _PyInterpreterFrame);
#[cfg(Py_3_13)]
pub const PyUnstable_EXECUTABLE_KIND_SKIP: c_int = 0;
#[cfg(Py_3_13)]
pub const PyUnstable_EXECUTABLE_KIND_PY_FUNCTION: c_int = 1;
#[cfg(Py_3_13)]
pub const PyUnstable_EXECUTABLE_KIND_BUILTIN_FUNCTION: c_int = 3;
#[cfg(Py_3_13)]
pub const PyUnstable_EXECUTABLE_KIND_METHOD_DESCRIPTOR: c_int = 4;
#[cfg(Py_3_13)]
pub const PyUnstable_EXECUTABLE_KINDS: c_int = 5;
extern_libpython! {
pub static mut PyFrame_Type: PyTypeObject;
#[cfg(Py_3_13)]
pub static mut PyFrameLocalsProxy_Type: PyTypeObject;
#[cfg(Py_3_13)]
pub static PyUnstable_ExecutableKinds: [*const PyTypeObject; 6];
}
#[inline]
pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyFrame_Type)
}
#[cfg(Py_3_13)]
#[inline]
pub unsafe fn PyFrameLocalsProxy_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyFrameLocalsProxy_Type)
}
extern_libpython! {
#[cfg(all(Py_3_9, not(PyPy)))]
pub fn PyFrame_GetBack(frame: *mut PyFrameObject) -> *mut PyFrameObject;
#[cfg(Py_3_11)]
pub fn PyFrame_GetLocals(frame: *mut PyFrameObject) -> *mut PyObject;
#[cfg(Py_3_11)]
pub fn PyFrame_GetGlobals(frame: *mut PyFrameObject) -> *mut PyObject;
#[cfg(Py_3_11)]
pub fn PyFrame_GetBuiltins(frame: *mut PyFrameObject) -> *mut PyObject;
#[cfg(Py_3_11)]
pub fn PyFrame_GetGenerator(frame: *mut PyFrameObject) -> *mut PyObject;
#[cfg(Py_3_11)]
pub fn PyFrame_GetLasti(frame: *mut PyFrameObject) -> c_int;
#[cfg(Py_3_12)]
pub fn PyFrame_GetVar(frame: *mut PyFrameObject, name: *mut PyObject) -> *mut PyObject;
#[cfg(Py_3_12)]
pub fn PyFrame_GetVarString(frame: *mut PyFrameObject, name: *mut c_char) -> *mut PyObject;
#[cfg(Py_3_12)]
pub fn PyUnstable_InterpreterFrame_GetCode(frame: *mut _PyInterpreterFrame) -> *mut PyObject;
#[cfg(Py_3_12)]
pub fn PyUnstable_InterpreterFrame_GetLasti(frame: *mut _PyInterpreterFrame) -> c_int;
#[cfg(Py_3_12)]
pub fn PyUnstable_InterpreterFrame_GetLine(frame: *mut _PyInterpreterFrame) -> c_int;
}
+30
View File
@@ -0,0 +1,30 @@
#[cfg(Py_3_14)]
use crate::Py_ssize_t;
#[cfg(Py_3_13)]
use crate::{PyObject, Py_hash_t};
#[cfg(any(Py_3_13, not(PyPy)))]
use core::ffi::c_void;
#[cfg(not(PyPy))]
use core::ffi::{c_char, c_int};
#[cfg(not(PyPy))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyHash_FuncDef {
pub hash:
Option<extern "C" fn(arg1: *const c_void, arg2: crate::Py_ssize_t) -> crate::Py_hash_t>,
pub name: *const c_char,
pub hash_bits: c_int,
pub seed_bits: c_int,
}
extern_libpython! {
#[cfg(not(PyPy))]
pub fn PyHash_GetFuncDef() -> *mut PyHash_FuncDef;
#[cfg(Py_3_13)]
pub fn Py_HashPointer(ptr: *const c_void) -> Py_hash_t;
#[cfg(Py_3_13)]
pub fn PyObject_GenericHash(obj: *mut PyObject) -> Py_hash_t;
#[cfg(Py_3_14)]
pub fn Py_HashBuffer(ptr: *const c_void, len: Py_ssize_t) -> Py_hash_t;
}
+85
View File
@@ -0,0 +1,85 @@
use crate::{PyConfig, PyPreConfig, PyStatus, Py_ssize_t};
use core::ffi::{c_char, c_int};
use libc::wchar_t;
extern_libpython! {
// skipped Py_FrozenMain
pub fn Py_PreInitialize(src_config: *const PyPreConfig) -> PyStatus;
pub fn Py_PreInitializeFromBytesArgs(
src_config: *const PyPreConfig,
argc: Py_ssize_t,
argv: *mut *mut c_char,
) -> PyStatus;
pub fn Py_PreInitializeFromArgs(
src_config: *const PyPreConfig,
argc: Py_ssize_t,
argv: *mut *mut wchar_t,
) -> PyStatus;
pub fn Py_InitializeFromConfig(config: *const PyConfig) -> PyStatus;
pub fn Py_RunMain() -> c_int;
pub fn Py_ExitStatusException(status: PyStatus) -> !;
// skipped Py_FdIsInteractive
}
#[cfg(Py_3_12)]
pub const PyInterpreterConfig_DEFAULT_GIL: c_int = 0;
#[cfg(Py_3_12)]
pub const PyInterpreterConfig_SHARED_GIL: c_int = 1;
#[cfg(Py_3_12)]
pub const PyInterpreterConfig_OWN_GIL: c_int = 2;
#[cfg(Py_3_12)]
#[repr(C)]
pub struct PyInterpreterConfig {
pub use_main_obmalloc: c_int,
pub allow_fork: c_int,
pub allow_exec: c_int,
pub allow_threads: c_int,
pub allow_daemon_threads: c_int,
pub check_multi_interp_extensions: c_int,
pub gil: c_int,
}
#[cfg(Py_3_12)]
pub const _PyInterpreterConfig_INIT: PyInterpreterConfig = PyInterpreterConfig {
use_main_obmalloc: 0,
allow_fork: 0,
allow_exec: 0,
allow_threads: 1,
allow_daemon_threads: 0,
check_multi_interp_extensions: 1,
gil: PyInterpreterConfig_OWN_GIL,
};
// https://github.com/python/cpython/blob/902de283a8303177eb95bf5bc252d2421fcbd758/Include/cpython/pylifecycle.h#L63-L65
#[cfg(Py_3_12)]
const _PyInterpreterConfig_LEGACY_CHECK_MULTI_INTERP_EXTENSIONS: c_int =
if cfg!(Py_GIL_DISABLED) { 1 } else { 0 };
#[cfg(Py_3_12)]
pub const _PyInterpreterConfig_LEGACY_INIT: PyInterpreterConfig = PyInterpreterConfig {
use_main_obmalloc: 1,
allow_fork: 1,
allow_exec: 1,
allow_threads: 1,
allow_daemon_threads: 1,
check_multi_interp_extensions: _PyInterpreterConfig_LEGACY_CHECK_MULTI_INTERP_EXTENSIONS,
gil: PyInterpreterConfig_SHARED_GIL,
};
extern_libpython! {
#[cfg(Py_3_12)]
pub fn Py_NewInterpreterFromConfig(
tstate_p: *mut *mut crate::PyThreadState,
config: *const PyInterpreterConfig,
) -> PyStatus;
}
// skipped atexit_datacallbackfunc
// skipped PyUnstable_AtExit
+49
View File
@@ -0,0 +1,49 @@
use core::ffi::c_void;
use libc::size_t;
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyMem_RawMalloc")]
pub fn PyMem_RawMalloc(size: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyMem_RawCalloc")]
pub fn PyMem_RawCalloc(nelem: size_t, elsize: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyMem_RawRealloc")]
pub fn PyMem_RawRealloc(ptr: *mut c_void, new_size: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyMem_RawFree")]
pub fn PyMem_RawFree(ptr: *mut c_void);
// skipped _PyMem_GetCurrentAllocatorName
// skipped _PyMem_RawStrdup
// skipped _PyMem_Strdup
// skipped _PyMem_RawWcsdup
}
#[repr(C)]
#[derive(Copy, Clone)]
pub enum PyMemAllocatorDomain {
PYMEM_DOMAIN_RAW,
PYMEM_DOMAIN_MEM,
PYMEM_DOMAIN_OBJ,
}
// skipped PyMemAllocatorName
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyMemAllocatorEx {
pub ctx: *mut c_void,
pub malloc: Option<extern "C" fn(ctx: *mut c_void, size: size_t) -> *mut c_void>,
pub calloc:
Option<extern "C" fn(ctx: *mut c_void, nelem: size_t, elsize: size_t) -> *mut c_void>,
pub realloc:
Option<extern "C" fn(ctx: *mut c_void, ptr: *mut c_void, new_size: size_t) -> *mut c_void>,
pub free: Option<extern "C" fn(ctx: *mut c_void, ptr: *mut c_void)>,
}
extern_libpython! {
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyMem_GetAllocator(domain: PyMemAllocatorDomain, allocator: *mut PyMemAllocatorEx);
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyMem_SetAllocator(domain: PyMemAllocatorDomain, allocator: *mut PyMemAllocatorEx);
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyMem_SetupDebugHooks();
}
+85
View File
@@ -0,0 +1,85 @@
use crate::PyThreadState;
use crate::{PyFrameObject, PyInterpreterState, PyObject};
use core::ffi::c_int;
// skipped private _PyInterpreterState_RequiresIDRef
// skipped private _PyInterpreterState_RequireIDRef
pub type Py_tracefunc = unsafe extern "C" fn(
obj: *mut PyObject,
frame: *mut PyFrameObject,
what: c_int,
arg: *mut PyObject,
) -> c_int;
pub const PyTrace_CALL: c_int = 0;
pub const PyTrace_EXCEPTION: c_int = 1;
pub const PyTrace_LINE: c_int = 2;
pub const PyTrace_RETURN: c_int = 3;
pub const PyTrace_C_CALL: c_int = 4;
pub const PyTrace_C_EXCEPTION: c_int = 5;
pub const PyTrace_C_RETURN: c_int = 6;
pub const PyTrace_OPCODE: c_int = 7;
// skipped private _Py_MAX_SCRIPT_PATH_SIZE
// skipped private _PyRemoteDebuggerSupport
/// Private structure used inline in `PyGenObject`
///
/// `PyGenObject` was made opaque in Python 3.14, so we don't bother defining this
/// structure for that version and later.
#[cfg(not(any(PyPy, Py_3_14)))]
#[repr(C)]
#[derive(Clone, Copy)]
pub(crate) struct _PyErr_StackItem {
#[cfg(not(Py_3_11))]
exc_type: *mut PyObject,
exc_value: *mut PyObject,
#[cfg(not(Py_3_11))]
exc_traceback: *mut PyObject,
previous_item: *mut _PyErr_StackItem,
}
// skipped private _PyStackChunk
// skipped private _PY_DATA_STACK_CHUNK_SIZE
// skipped private _ts (aka PyThreadState)
extern_libpython! {
#[cfg(Py_3_13)]
pub fn PyThreadState_GetUnchecked() -> *mut PyThreadState;
#[cfg(not(Py_3_13))]
pub(crate) fn _PyThreadState_UncheckedGet() -> *mut PyThreadState;
#[cfg(Py_3_11)]
pub fn PyThreadState_EnterTracing(state: *mut PyThreadState);
#[cfg(Py_3_11)]
pub fn PyThreadState_LeaveTracing(state: *mut PyThreadState);
#[cfg_attr(PyPy, link_name = "PyPyGILState_Check")]
pub fn PyGILState_Check() -> c_int;
// skipped private _PyThread_CurrentFrames
// skipped PyUnstable_ThreadState_SetStackProtection
// skipped PyUnstable_ThreadState_ResetStackProtection
#[cfg(not(PyPy))]
pub fn PyInterpreterState_Main() -> *mut PyInterpreterState;
#[cfg_attr(PyPy, link_name = "PyPyInterpreterState_Head")]
pub fn PyInterpreterState_Head() -> *mut PyInterpreterState;
#[cfg_attr(PyPy, link_name = "PyPyInterpreterState_Next")]
pub fn PyInterpreterState_Next(interp: *mut PyInterpreterState) -> *mut PyInterpreterState;
#[cfg(not(PyPy))]
pub fn PyInterpreterState_ThreadHead(interp: *mut PyInterpreterState) -> *mut PyThreadState;
#[cfg(not(PyPy))]
pub fn PyThreadState_Next(tstate: *mut PyThreadState) -> *mut PyThreadState;
#[cfg_attr(PyPy, link_name = "PyPyThreadState_DeleteCurrent")]
pub fn PyThreadState_DeleteCurrent();
}
// skipped private _PyFrameEvalFunction
// skipped private _PyInterpreterState_GetEvalFrameFunc
// skipped private _PyInterpreterState_SetEvalFrameFunc
+229
View File
@@ -0,0 +1,229 @@
use crate::object::*;
#[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API, Py_3_10)))]
use crate::pyarena::PyArena;
use crate::PyCompilerFlags;
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
use crate::{_mod, _node};
use core::ffi::{c_char, c_int};
use libc::FILE;
extern_libpython! {
pub fn PyRun_SimpleStringFlags(arg1: *const c_char, arg2: *mut PyCompilerFlags) -> c_int;
pub fn PyRun_AnyFileExFlags(
fp: *mut FILE,
filename: *const c_char,
closeit: c_int,
flags: *mut PyCompilerFlags,
) -> c_int;
pub fn PyRun_SimpleFileExFlags(
fp: *mut FILE,
filename: *const c_char,
closeit: c_int,
flags: *mut PyCompilerFlags,
) -> c_int;
pub fn PyRun_InteractiveOneFlags(
fp: *mut FILE,
filename: *const c_char,
flags: *mut PyCompilerFlags,
) -> c_int;
pub fn PyRun_InteractiveOneObject(
fp: *mut FILE,
filename: *mut PyObject,
flags: *mut PyCompilerFlags,
) -> c_int;
pub fn PyRun_InteractiveLoopFlags(
fp: *mut FILE,
filename: *const c_char,
flags: *mut PyCompilerFlags,
) -> c_int;
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
pub fn PyParser_ASTFromString(
s: *const c_char,
filename: *const c_char,
start: c_int,
flags: *mut PyCompilerFlags,
arena: *mut PyArena,
) -> *mut _mod;
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
pub fn PyParser_ASTFromStringObject(
s: *const c_char,
filename: *mut PyObject,
start: c_int,
flags: *mut PyCompilerFlags,
arena: *mut PyArena,
) -> *mut _mod;
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
pub fn PyParser_ASTFromFile(
fp: *mut FILE,
filename: *const c_char,
enc: *const c_char,
start: c_int,
ps1: *const c_char,
ps2: *const c_char,
flags: *mut PyCompilerFlags,
errcode: *mut c_int,
arena: *mut PyArena,
) -> *mut _mod;
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
pub fn PyParser_ASTFromFileObject(
fp: *mut FILE,
filename: *mut PyObject,
enc: *const c_char,
start: c_int,
ps1: *const c_char,
ps2: *const c_char,
flags: *mut PyCompilerFlags,
errcode: *mut c_int,
arena: *mut PyArena,
) -> *mut _mod;
#[cfg_attr(PyPy, link_name = "PyPyRun_StringFlags")]
pub fn PyRun_StringFlags(
arg1: *const c_char,
arg2: c_int,
arg3: *mut PyObject,
arg4: *mut PyObject,
arg5: *mut PyCompilerFlags,
) -> *mut PyObject;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_FileExFlags(
fp: *mut FILE,
filename: *const c_char,
start: c_int,
globals: *mut PyObject,
locals: *mut PyObject,
closeit: c_int,
flags: *mut PyCompilerFlags,
) -> *mut PyObject;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn Py_CompileStringExFlags(
str: *const c_char,
filename: *const c_char,
start: c_int,
flags: *mut PyCompilerFlags,
optimize: c_int,
) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
pub fn Py_CompileStringObject(
str: *const c_char,
filename: *mut PyObject,
start: c_int,
flags: *mut PyCompilerFlags,
optimize: c_int,
) -> *mut PyObject;
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject {
Py_CompileStringExFlags(string, p, s, core::ptr::null_mut(), -1)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn Py_CompileStringFlags(
string: *const c_char,
p: *const c_char,
s: c_int,
f: *mut PyCompilerFlags,
) -> *mut PyObject {
Py_CompileStringExFlags(string, p, s, f, -1)
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyRun_String")]
pub fn PyRun_String(
string: *const c_char,
s: c_int,
g: *mut PyObject,
l: *mut PyObject,
) -> *mut PyObject;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_AnyFile(fp: *mut FILE, name: *const c_char) -> c_int;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_AnyFileEx(fp: *mut FILE, name: *const c_char, closeit: c_int) -> c_int;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_AnyFileFlags(
arg1: *mut FILE,
arg2: *const c_char,
arg3: *mut PyCompilerFlags,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyRun_SimpleString")]
pub fn PyRun_SimpleString(s: *const c_char) -> c_int;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_SimpleFile(f: *mut FILE, p: *const c_char) -> c_int;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_SimpleFileEx(f: *mut FILE, p: *const c_char, c: c_int) -> c_int;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_InteractiveOne(f: *mut FILE, p: *const c_char) -> c_int;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_InteractiveLoop(f: *mut FILE, p: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyRun_File")]
pub fn PyRun_File(
fp: *mut FILE,
p: *const c_char,
s: c_int,
g: *mut PyObject,
l: *mut PyObject,
) -> *mut PyObject;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_FileEx(
fp: *mut FILE,
p: *const c_char,
s: c_int,
g: *mut PyObject,
l: *mut PyObject,
c: c_int,
) -> *mut PyObject;
#[cfg(not(any(PyPy, GraalPy)))]
pub fn PyRun_FileFlags(
fp: *mut FILE,
p: *const c_char,
s: c_int,
g: *mut PyObject,
l: *mut PyObject,
flags: *mut PyCompilerFlags,
) -> *mut PyObject;
}
// skipped macro PyRun_String
// skipped macro PyRun_AnyFile
// skipped macro PyRun_AnyFileEx
// skipped macro PyRun_AnyFileFlags
extern_libpython! {
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
pub fn PyParser_SimpleParseStringFlags(
arg1: *const c_char,
arg2: c_int,
arg3: c_int,
) -> *mut _node;
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
pub fn PyParser_SimpleParseStringFlagsFilename(
arg1: *const c_char,
arg2: *const c_char,
arg3: c_int,
arg4: c_int,
) -> *mut _node;
#[cfg(not(any(PyPy, GraalPy, Py_3_10)))]
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
pub fn PyParser_SimpleParseFileFlags(
arg1: *mut FILE,
arg2: *const c_char,
arg3: c_int,
arg4: c_int,
) -> *mut _node;
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPy_CompileStringFlags")]
pub fn Py_CompileStringFlags(
string: *const c_char,
p: *const c_char,
s: c_int,
f: *mut PyCompilerFlags,
) -> *mut PyObject;
}
+50
View File
@@ -0,0 +1,50 @@
#[cfg(Py_GIL_DISABLED)]
use crate::pyatomic::_Py_atomic_load_ssize_relaxed;
#[cfg(not(any(PyPy, GraalPy)))]
use crate::{PyAnySet_Check, PyObject, Py_hash_t, Py_ssize_t};
pub const PySet_MINSIZE: usize = 8;
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
pub struct setentry {
pub key: *mut PyObject,
pub hash: Py_hash_t,
}
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
pub struct PySetObject {
pub ob_base: PyObject,
pub fill: Py_ssize_t,
pub used: Py_ssize_t,
pub mask: Py_ssize_t,
pub table: *mut setentry,
pub hash: Py_hash_t,
pub finger: Py_ssize_t,
pub smalltable: [setentry; PySet_MINSIZE],
pub weakreflist: *mut PyObject,
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub(crate) unsafe fn _PySet_CAST(so: *mut PyObject) -> *mut PySetObject {
debug_assert_eq!(PyAnySet_Check(so), 1);
so.cast()
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PySet_GET_SIZE(so: *mut PyObject) -> Py_ssize_t {
let so = _PySet_CAST(so);
#[cfg(Py_GIL_DISABLED)]
{
_Py_atomic_load_ssize_relaxed(&raw const (*so).used)
}
#[cfg(not(Py_GIL_DISABLED))]
{
(*so).used
}
}
+12
View File
@@ -0,0 +1,12 @@
use crate::object::PyObject;
use crate::PyFrameObject;
use core::ffi::c_int;
#[repr(C)]
pub struct PyTracebackObject {
pub ob_base: PyObject,
pub tb_next: *mut PyTracebackObject,
pub tb_frame: *mut PyFrameObject,
pub tb_lasti: c_int,
pub tb_lineno: c_int,
}
+40
View File
@@ -0,0 +1,40 @@
use crate::object::*;
#[cfg(Py_3_14)]
use crate::pyport::Py_hash_t;
#[cfg(not(PyPy))]
use crate::pyport::Py_ssize_t;
#[repr(C)]
pub struct PyTupleObject {
pub ob_base: PyVarObject,
#[cfg(Py_3_14)]
pub ob_hash: Py_hash_t,
pub ob_item: [*mut PyObject; 1],
}
// skipped _PyTuple_Resize
// skipped _PyTuple_MaybeUntrack
// skipped _PyTuple_CAST
/// Macro, trading safety for speed
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyTuple_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
Py_SIZE(op)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PyTuple_GET_ITEM(op: *mut PyObject, i: Py_ssize_t) -> *mut PyObject {
*(*(op as *mut PyTupleObject)).ob_item.as_ptr().offset(i)
}
/// Macro, *only* to be used to fill in brand new tuples
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn PyTuple_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject) {
*(*(op as *mut PyTupleObject)).ob_item.as_mut_ptr().offset(i) = v;
}
// skipped _PyTuple_DebugMallocStats
+888
View File
@@ -0,0 +1,888 @@
#[cfg(any(Py_3_11, not(PyPy)))]
use crate::Py_hash_t;
use crate::{PyObject, Py_UCS1, Py_UCS2, Py_UCS4, Py_ssize_t};
use core::ffi::{c_char, c_int, c_uint, c_void};
use libc::wchar_t;
// skipped PY_UNICODE_TYPE
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(
Py_3_13,
deprecated(note = "Deprecated since Python 3.13. Use `libc::wchar_t` instead.")
)]
pub type Py_UNICODE = wchar_t;
// skipped Py_UNICODE_IS_SURROGATE
// skipped Py_UNICODE_IS_HIGH_SURROGATE
// skipped Py_UNICODE_IS_LOW_SURROGATE
// skipped Py_UNICODE_JOIN_SURROGATES
// skipped Py_UNICODE_HIGH_SURROGATE
// skipped Py_UNICODE_LOW_SURROGATE
// generated by bindgen v0.63.0 (with small adaptations)
#[cfg(not(Py_3_14))]
#[repr(C)]
struct BitfieldUnit<Storage> {
storage: Storage,
}
#[cfg(not(Py_3_14))]
impl<Storage> BitfieldUnit<Storage> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage }
}
}
#[cfg(not(any(GraalPy, Py_3_14)))]
impl<Storage> BitfieldUnit<Storage>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
let byte_index = index / 8;
let byte = self.storage.as_ref()[byte_index];
let bit_index = if cfg!(target_endian = "big") {
7 - (index % 8)
} else {
index % 8
};
let mask = 1 << bit_index;
byte & mask == mask
}
#[inline]
fn set_bit(&mut self, index: usize, val: bool) {
debug_assert!(index / 8 < self.storage.as_ref().len());
let byte_index = index / 8;
let byte = &mut self.storage.as_mut()[byte_index];
let bit_index = if cfg!(target_endian = "big") {
7 - (index % 8)
} else {
index % 8
};
let mask = 1 << bit_index;
if val {
*byte |= mask;
} else {
*byte &= !mask;
}
}
#[inline]
fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
debug_assert!(bit_width <= 64);
debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
let mut val = 0;
for i in 0..(bit_width as usize) {
if self.get_bit(i + bit_offset) {
let index = if cfg!(target_endian = "big") {
bit_width as usize - 1 - i
} else {
i
};
val |= 1 << index;
}
}
val
}
#[inline]
fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
debug_assert!(bit_width <= 64);
debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
for i in 0..(bit_width as usize) {
let mask = 1 << i;
let val_bit_is_set = val & mask == mask;
let index = if cfg!(target_endian = "big") {
bit_width as usize - 1 - i
} else {
i
};
self.set_bit(index + bit_offset, val_bit_is_set);
}
}
}
#[cfg(not(any(GraalPy, Py_3_14)))]
const STATE_INTERNED_INDEX: usize = 0;
#[cfg(not(any(GraalPy, Py_3_14)))]
const STATE_INTERNED_WIDTH: u8 = 2;
#[cfg(not(any(GraalPy, Py_3_14)))]
const STATE_KIND_INDEX: usize = STATE_INTERNED_WIDTH as usize;
#[cfg(not(any(GraalPy, Py_3_14)))]
const STATE_KIND_WIDTH: u8 = 3;
#[cfg(not(any(GraalPy, Py_3_14)))]
const STATE_COMPACT_INDEX: usize = (STATE_INTERNED_WIDTH + STATE_KIND_WIDTH) as usize;
#[cfg(not(any(GraalPy, Py_3_14)))]
const STATE_COMPACT_WIDTH: u8 = 1;
#[cfg(not(any(GraalPy, Py_3_14)))]
const STATE_ASCII_INDEX: usize =
(STATE_INTERNED_WIDTH + STATE_KIND_WIDTH + STATE_COMPACT_WIDTH) as usize;
#[cfg(not(any(GraalPy, Py_3_14)))]
const STATE_ASCII_WIDTH: u8 = 1;
#[cfg(all(not(any(GraalPy, Py_3_14)), Py_3_12))]
const STATE_STATICALLY_ALLOCATED_INDEX: usize =
(STATE_INTERNED_WIDTH + STATE_KIND_WIDTH + STATE_COMPACT_WIDTH + STATE_ASCII_WIDTH) as usize;
#[cfg(all(not(any(GraalPy, Py_3_14)), Py_3_12))]
const STATE_STATICALLY_ALLOCATED_WIDTH: u8 = 1;
#[cfg(not(any(Py_3_12, GraalPy)))]
const STATE_READY_INDEX: usize =
(STATE_INTERNED_WIDTH + STATE_KIND_WIDTH + STATE_COMPACT_WIDTH + STATE_ASCII_WIDTH) as usize;
#[cfg(not(any(Py_3_12, GraalPy)))]
const STATE_READY_WIDTH: u8 = 1;
// generated by bindgen v0.63.0 (with small adaptations)
// The same code is generated for Python 3.8, 3.9, 3.10, and 3.11, but the "ready" field
// has been removed from Python 3.12.
/// Wrapper around the `PyASCIIObject.state` bitfield with getters and setters that work
/// on most little- and big-endian architectures.
///
/// Memory layout of C bitfields is implementation defined, so these functions are still
/// unsafe. Users must verify that they work as expected on the architectures they target.
#[cfg(not(Py_3_14))]
#[repr(C)]
struct PyASCIIObjectState {
bitfield_align: [u8; 0],
bitfield: BitfieldUnit<[u8; 4usize]>,
}
// c_uint and u32 are not necessarily the same type on all targets / architectures
#[cfg(not(any(GraalPy, Py_3_14)))]
#[allow(clippy::useless_transmute)]
impl PyASCIIObjectState {
#[inline]
unsafe fn interned(&self) -> c_uint {
core::mem::transmute(
self.bitfield
.get(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH) as u32,
)
}
#[inline]
unsafe fn set_interned(&mut self, val: c_uint) {
let val: u32 = core::mem::transmute(val);
self.bitfield
.set(STATE_INTERNED_INDEX, STATE_INTERNED_WIDTH, val as u64)
}
#[inline]
unsafe fn kind(&self) -> c_uint {
core::mem::transmute(self.bitfield.get(STATE_KIND_INDEX, STATE_KIND_WIDTH) as u32)
}
#[inline]
unsafe fn set_kind(&mut self, val: c_uint) {
let val: u32 = core::mem::transmute(val);
self.bitfield
.set(STATE_KIND_INDEX, STATE_KIND_WIDTH, val as u64)
}
#[inline]
unsafe fn compact(&self) -> c_uint {
core::mem::transmute(self.bitfield.get(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH) as u32)
}
#[inline]
unsafe fn set_compact(&mut self, val: c_uint) {
let val: u32 = core::mem::transmute(val);
self.bitfield
.set(STATE_COMPACT_INDEX, STATE_COMPACT_WIDTH, val as u64)
}
#[inline]
unsafe fn ascii(&self) -> c_uint {
core::mem::transmute(self.bitfield.get(STATE_ASCII_INDEX, STATE_ASCII_WIDTH) as u32)
}
#[inline]
unsafe fn set_ascii(&mut self, val: c_uint) {
let val: u32 = core::mem::transmute(val);
self.bitfield
.set(STATE_ASCII_INDEX, STATE_ASCII_WIDTH, val as u64)
}
#[cfg(Py_3_12)]
#[inline]
unsafe fn statically_allocated(&self) -> c_uint {
core::mem::transmute(self.bitfield.get(
STATE_STATICALLY_ALLOCATED_INDEX,
STATE_STATICALLY_ALLOCATED_WIDTH,
) as u32)
}
#[cfg(Py_3_12)]
#[inline]
unsafe fn set_statically_allocated(&mut self, val: c_uint) {
let val: u32 = core::mem::transmute(val);
self.bitfield.set(
STATE_STATICALLY_ALLOCATED_INDEX,
STATE_STATICALLY_ALLOCATED_WIDTH,
val as u64,
)
}
#[cfg(not(Py_3_12))]
#[inline]
unsafe fn ready(&self) -> c_uint {
core::mem::transmute(self.bitfield.get(STATE_READY_INDEX, STATE_READY_WIDTH) as u32)
}
#[cfg(not(Py_3_12))]
#[inline]
unsafe fn set_ready(&mut self, val: c_uint) {
let val: u32 = core::mem::transmute(val);
self.bitfield
.set(STATE_READY_INDEX, STATE_READY_WIDTH, val as u64)
}
}
#[cfg(not(Py_3_14))]
impl From<u32> for PyASCIIObjectState {
#[inline]
fn from(value: u32) -> Self {
PyASCIIObjectState {
bitfield_align: [],
bitfield: BitfieldUnit::new(value.to_ne_bytes()),
}
}
}
#[cfg(not(Py_3_14))]
impl From<PyASCIIObjectState> for u32 {
#[inline]
fn from(value: PyASCIIObjectState) -> Self {
u32::from_ne_bytes(value.bitfield.storage)
}
}
#[repr(C)]
pub struct PyASCIIObject {
pub ob_base: PyObject,
pub length: Py_ssize_t,
#[cfg(any(Py_3_11, not(PyPy)))]
pub hash: Py_hash_t,
/// A bit field with various properties.
///
/// Rust doesn't expose bitfields. So we have accessor functions for
/// retrieving values.
///
/// Before 3.12:
/// unsigned int interned:2; // SSTATE_* constants.
/// unsigned int kind:3; // PyUnicode_*_KIND constants.
/// unsigned int compact:1;
/// unsigned int ascii:1;
/// unsigned int ready:1;
/// unsigned int :24;
///
/// 3.12, and 3.13
/// unsigned int interned:2; // SSTATE_* constants.
/// unsigned int kind:3; // PyUnicode_*_KIND constants.
/// unsigned int compact:1;
/// unsigned int ascii:1;
/// unsigned int statically_allocated:1;
/// unsigned int :24;
/// on 3.14 and higher PyO3 doesn't access the internal state
pub state: u32,
#[cfg(not(Py_3_12))]
pub wstr: *mut wchar_t,
}
/// Interacting with the bitfield is not actually well-defined, so we mark these APIs unsafe.
#[cfg(not(any(GraalPy, Py_3_14)))]
impl PyASCIIObject {
#[cfg_attr(not(Py_3_12), allow(rustdoc::broken_intra_doc_links))] // SSTATE_INTERNED_IMMORTAL_STATIC requires 3.12
/// Get the `interned` field of the [`PyASCIIObject`] state bitfield.
///
/// Returns one of: [`SSTATE_NOT_INTERNED`], [`SSTATE_INTERNED_MORTAL`],
/// [`SSTATE_INTERNED_IMMORTAL`], or [`SSTATE_INTERNED_IMMORTAL_STATIC`].
#[inline]
pub unsafe fn interned(&self) -> c_uint {
PyASCIIObjectState::from(self.state).interned()
}
#[cfg_attr(not(Py_3_12), allow(rustdoc::broken_intra_doc_links))] // SSTATE_INTERNED_IMMORTAL_STATIC requires 3.12
/// Set the `interned` field of the [`PyASCIIObject`] state bitfield.
///
/// Calling this function with an argument that is not [`SSTATE_NOT_INTERNED`],
/// [`SSTATE_INTERNED_MORTAL`], [`SSTATE_INTERNED_IMMORTAL`], or
/// [`SSTATE_INTERNED_IMMORTAL_STATIC`] is invalid.
#[inline]
pub unsafe fn set_interned(&mut self, val: c_uint) {
let mut state = PyASCIIObjectState::from(self.state);
state.set_interned(val);
self.state = u32::from(state);
}
/// Get the `kind` field of the [`PyASCIIObject`] state bitfield.
///
/// Returns one of:
#[cfg_attr(not(Py_3_12), doc = "[`PyUnicode_WCHAR_KIND`], ")]
/// [`PyUnicode_1BYTE_KIND`], [`PyUnicode_2BYTE_KIND`], or [`PyUnicode_4BYTE_KIND`].
#[inline]
pub unsafe fn kind(&self) -> c_uint {
PyASCIIObjectState::from(self.state).kind()
}
/// Set the `kind` field of the [`PyASCIIObject`] state bitfield.
///
/// Calling this function with an argument that is not
#[cfg_attr(not(Py_3_12), doc = "[`PyUnicode_WCHAR_KIND`], ")]
/// [`PyUnicode_1BYTE_KIND`], [`PyUnicode_2BYTE_KIND`], or [`PyUnicode_4BYTE_KIND`] is invalid.
#[inline]
pub unsafe fn set_kind(&mut self, val: c_uint) {
let mut state = PyASCIIObjectState::from(self.state);
state.set_kind(val);
self.state = u32::from(state);
}
/// Get the `compact` field of the [`PyASCIIObject`] state bitfield.
///
/// Returns either `0` or `1`.
#[inline]
pub unsafe fn compact(&self) -> c_uint {
PyASCIIObjectState::from(self.state).compact()
}
/// Set the `compact` flag of the [`PyASCIIObject`] state bitfield.
///
/// Calling this function with an argument that is neither `0` nor `1` is invalid.
#[inline]
pub unsafe fn set_compact(&mut self, val: c_uint) {
let mut state = PyASCIIObjectState::from(self.state);
state.set_compact(val);
self.state = u32::from(state);
}
/// Get the `ascii` field of the [`PyASCIIObject`] state bitfield.
///
/// Returns either `0` or `1`.
#[inline]
pub unsafe fn ascii(&self) -> c_uint {
PyASCIIObjectState::from(self.state).ascii()
}
/// Set the `ascii` flag of the [`PyASCIIObject`] state bitfield.
///
/// Calling this function with an argument that is neither `0` nor `1` is invalid.
#[inline]
#[cfg(not(all(Py_3_14, Py_GIL_DISABLED)))]
pub unsafe fn set_ascii(&mut self, val: c_uint) {
let mut state = PyASCIIObjectState::from(self.state);
state.set_ascii(val);
self.state = u32::from(state);
}
/// Get the `ready` field of the [`PyASCIIObject`] state bitfield.
///
/// Returns either `0` or `1`.
#[cfg(not(Py_3_12))]
#[inline]
pub unsafe fn ready(&self) -> c_uint {
PyASCIIObjectState::from(self.state).ready()
}
/// Set the `ready` flag of the [`PyASCIIObject`] state bitfield.
///
/// Calling this function with an argument that is neither `0` nor `1` is invalid.
#[cfg(not(Py_3_12))]
#[inline]
pub unsafe fn set_ready(&mut self, val: c_uint) {
let mut state = PyASCIIObjectState::from(self.state);
state.set_ready(val);
self.state = u32::from(state);
}
/// Get the `statically_allocated` field of the [`PyASCIIObject`] state bitfield.
///
/// Returns either `0` or `1`.
#[inline]
#[cfg(Py_3_12)]
pub unsafe fn statically_allocated(&self) -> c_uint {
PyASCIIObjectState::from(self.state).statically_allocated()
}
/// Set the `statically_allocated` flag of the [`PyASCIIObject`] state bitfield.
///
/// Calling this function with an argument that is neither `0` nor `1` is invalid.
#[inline]
#[cfg(Py_3_12)]
pub unsafe fn set_statically_allocated(&mut self, val: c_uint) {
let mut state = PyASCIIObjectState::from(self.state);
state.set_statically_allocated(val);
self.state = u32::from(state);
}
}
#[repr(C)]
pub struct PyCompactUnicodeObject {
pub _base: PyASCIIObject,
pub utf8_length: Py_ssize_t,
pub utf8: *mut c_char,
#[cfg(not(Py_3_12))]
pub wstr_length: Py_ssize_t,
}
#[repr(C)]
pub union PyUnicodeObjectData {
pub any: *mut c_void,
pub latin1: *mut Py_UCS1,
pub ucs2: *mut Py_UCS2,
pub ucs4: *mut Py_UCS4,
}
#[repr(C)]
pub struct PyUnicodeObject {
pub _base: PyCompactUnicodeObject,
pub data: PyUnicodeObjectData,
}
// skipped private _PyASCIIObject_CAST
// skipped private _PyCompactUnicodeObject_CAST
// skipped private _PyUnicodeObject_CAST
pub const SSTATE_NOT_INTERNED: c_uint = 0;
pub const SSTATE_INTERNED_MORTAL: c_uint = 1;
pub const SSTATE_INTERNED_IMMORTAL: c_uint = 2;
#[cfg(Py_3_12)]
pub const SSTATE_INTERNED_IMMORTAL_STATIC: c_uint = 3;
// skipped PyUnicode_CHECK_INTERNED
#[cfg(any(Py_3_12, GraalPy))]
#[cfg_attr(
Py_3_14,
deprecated(note = "Deprecated since Python 3.14. This API does nothing since Python 3.12.")
)]
#[inline]
pub unsafe fn PyUnicode_IS_READY(_op: *mut PyObject) -> c_uint {
// kept in CPython for backwards compatibility
1
}
#[cfg(not(any(GraalPy, Py_3_12)))]
#[inline]
pub unsafe fn PyUnicode_IS_READY(op: *mut PyObject) -> c_uint {
(*(op as *mut PyASCIIObject)).ready()
}
// The following functions depend on the bitfield, which we don't support
// from 3.14 onwards
#[cfg(not(any(GraalPy, Py_3_14)))]
#[inline]
pub unsafe fn PyUnicode_IS_ASCII(op: *mut PyObject) -> c_uint {
debug_assert!(crate::PyUnicode_Check(op) != 0);
#[cfg(not(Py_3_12))]
debug_assert!(PyUnicode_IS_READY(op) != 0);
(*(op as *mut PyASCIIObject)).ascii()
}
#[cfg(not(any(GraalPy, Py_3_14)))]
#[inline]
pub unsafe fn PyUnicode_IS_COMPACT(op: *mut PyObject) -> c_uint {
(*(op as *mut PyASCIIObject)).compact()
}
#[cfg(not(any(GraalPy, Py_3_14)))]
#[inline]
pub unsafe fn PyUnicode_IS_COMPACT_ASCII(op: *mut PyObject) -> c_uint {
((*(op as *mut PyASCIIObject)).ascii() != 0 && PyUnicode_IS_COMPACT(op) != 0).into()
}
#[cfg(not(Py_3_12))]
#[deprecated(note = "Removed in Python 3.12")]
pub const PyUnicode_WCHAR_KIND: c_uint = 0;
pub const PyUnicode_1BYTE_KIND: c_uint = 1;
pub const PyUnicode_2BYTE_KIND: c_uint = 2;
pub const PyUnicode_4BYTE_KIND: c_uint = 4;
#[cfg(all(not(GraalPy), Py_3_14))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyUnicode_KIND")]
pub fn PyUnicode_KIND(op: *mut PyObject) -> c_uint;
}
#[cfg(all(not(GraalPy), not(Py_3_14)))]
#[inline]
pub unsafe fn PyUnicode_KIND(op: *mut PyObject) -> c_uint {
debug_assert!(crate::PyUnicode_Check(op) != 0);
#[cfg(not(Py_3_12))]
debug_assert!(PyUnicode_IS_READY(op) != 0);
(*(op as *mut PyASCIIObject)).kind()
}
#[cfg(not(any(GraalPy, Py_3_14)))]
#[inline]
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
} else {
(op as *mut PyCompactUnicodeObject).offset(1) as *mut c_void
}
}
#[cfg(not(any(GraalPy, PyPy)))]
#[inline]
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
}
#[cfg(not(any(GraalPy, PyPy, Py_3_14)))]
#[inline]
pub unsafe fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void {
debug_assert!(crate::PyUnicode_Check(op) != 0);
if PyUnicode_IS_COMPACT(op) != 0 {
_PyUnicode_COMPACT_DATA(op)
} else {
_PyUnicode_NONCOMPACT_DATA(op)
}
}
#[cfg(Py_3_14)]
#[cfg(all(not(GraalPy), Py_3_14))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DATA")]
pub fn PyUnicode_DATA(op: *mut PyObject) -> *mut c_void;
}
#[cfg(not(any(GraalPy, PyPy)))]
#[inline]
pub unsafe fn PyUnicode_1BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS1 {
PyUnicode_DATA(op) as *mut Py_UCS1
}
#[cfg(not(any(GraalPy, PyPy)))]
#[inline]
pub unsafe fn PyUnicode_2BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS2 {
PyUnicode_DATA(op) as *mut Py_UCS2
}
#[cfg(not(any(GraalPy, PyPy)))]
#[inline]
pub unsafe fn PyUnicode_4BYTE_DATA(op: *mut PyObject) -> *mut Py_UCS4 {
PyUnicode_DATA(op) as *mut Py_UCS4
}
#[cfg(not(GraalPy))]
#[inline]
pub unsafe fn PyUnicode_GET_LENGTH(op: *mut PyObject) -> Py_ssize_t {
debug_assert!(crate::PyUnicode_Check(op) != 0);
#[cfg(not(Py_3_12))]
debug_assert!(PyUnicode_IS_READY(op) != 0);
(*(op as *mut PyASCIIObject)).length
}
// skipped PyUnstable_Unicode_GET_CACHED_HASH
// skipped PyUnicode_WRITE
// skipped PyUnicode_READ
// skipped PyUnicode_READ_CHAR
// skipped PyUnicode_MAX_CHAR_VALUE
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyUnicode_New")]
pub fn PyUnicode_New(size: Py_ssize_t, maxchar: Py_UCS4) -> *mut PyObject;
}
#[cfg(any(Py_3_12, GraalPy))]
#[inline]
pub unsafe fn PyUnicode_READY(_op: *mut PyObject) -> c_int {
0
}
#[cfg(not(any(Py_3_12, GraalPy)))]
#[inline]
pub unsafe fn PyUnicode_READY(op: *mut PyObject) -> c_int {
debug_assert!(crate::PyUnicode_Check(op) != 0);
if PyUnicode_IS_READY(op) != 0 {
0
} else {
_PyUnicode_Ready(op)
}
}
extern_libpython! {
#[cfg(not(any(Py_3_12, GraalPy)))]
#[cfg_attr(PyPy, link_name = "_PyPyUnicode_Ready")]
fn _PyUnicode_Ready(unicode: *mut PyObject) -> c_int;
#[cfg(not(PyPy))]
pub fn PyUnicode_CopyCharacters(
to: *mut PyObject,
to_start: Py_ssize_t,
from: *mut PyObject,
from_start: Py_ssize_t,
how_many: Py_ssize_t,
) -> Py_ssize_t;
#[cfg(not(PyPy))]
pub fn PyUnicode_Fill(
unicode: *mut PyObject,
start: Py_ssize_t,
length: Py_ssize_t,
fill_char: Py_UCS4,
) -> Py_ssize_t;
#[cfg(not(Py_3_12))]
#[deprecated]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromUnicode")]
pub fn PyUnicode_FromUnicode(u: *const wchar_t, size: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromKindAndData")]
pub fn PyUnicode_FromKindAndData(
kind: c_int,
buffer: *const c_void,
size: Py_ssize_t,
) -> *mut PyObject;
#[cfg(not(Py_3_12))]
#[deprecated]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUnicode")]
pub fn PyUnicode_AsUnicode(unicode: *mut PyObject) -> *mut wchar_t;
#[cfg(not(Py_3_12))]
#[deprecated]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUnicodeAndSize")]
pub fn PyUnicode_AsUnicodeAndSize(
unicode: *mut PyObject,
size: *mut Py_ssize_t,
) -> *mut wchar_t;
}
#[cfg(Py_3_14)]
opaque_struct!(pub PyUnicodeWriter);
extern_libpython! {
#[cfg(Py_3_14)]
pub fn PyUnicodeWriter_Create(length: Py_ssize_t) -> *mut PyUnicodeWriter;
#[cfg(Py_3_14)]
pub fn PyUnicodeWriter_Discard(writer: *mut PyUnicodeWriter);
#[cfg(Py_3_14)]
pub fn PyUnicodeWriter_Finish(writer: *mut PyUnicodeWriter) -> *mut PyObject;
#[cfg(Py_3_14)]
pub fn PyUnicodeWriter_WriteChar(writer: *mut PyUnicodeWriter, ch: Py_UCS4) -> c_int;
#[cfg(Py_3_14)]
pub fn PyUnicodeWriter_WriteUTF8(
writer: *mut PyUnicodeWriter,
str: *const c_char,
size: Py_ssize_t,
) -> c_int;
// skipped PyUnicodeWriter_WriteASCII
// skipped PyUnicodeWriter_WriteWideChar
// skipped PyUnicodeWriter_WriteUCS4
// skipped PyUnicodeWriter_WriteStr
// skipped PyUnicodeWriter_WriteRepr
// skipped PyUnicodeWriter_WriteSubstring
// skipped PyUnicodeWriter_Format
// skipped PyUnicodeWriter_DecodeUTF8Stateful
}
// skipped private _PyUnicodeWriter
// skipped private _PyUnicodeWriter_Init
// skipped private _PyUnicodeWriter_Prepare
// skipped private _PyUnicodeWriter_PrepareInternal
// skipped private _PyUnicodeWriter_PrepareKind
// skipped private _PyUnicodeWriter_PrepareKindInternal
// skipped private _PyUnicodeWriter_WriteChar
// skipped private _PyUnicodeWriter_WriteStr
// skipped private _PyUnicodeWriter_WriteSubstring
// skipped private _PyUnicodeWriter_WriteASCIIString
// skipped private _PyUnicodeWriter_WriteLatin1String
// skipped private _PyUnicodeWriter_Finish
// skipped private _PyUnicodeWriter_Dealloc
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8")]
pub fn PyUnicode_AsUTF8(unicode: *mut PyObject) -> *const c_char;
// skipped _PyUnicode_AsString
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsEncodedString` instead")]
pub fn PyUnicode_Encode(
s: *const wchar_t,
size: Py_ssize_t,
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsEncodedString` instead")]
pub fn PyUnicode_EncodeUTF7(
data: *const wchar_t,
length: Py_ssize_t,
base64SetO: c_int,
base64WhiteSpace: c_int,
errors: *const c_char,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsUTF8String` instead")]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeUTF8")]
pub fn PyUnicode_EncodeUTF8(
data: *const wchar_t,
length: Py_ssize_t,
errors: *const c_char,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsUTF32String` instead")]
pub fn PyUnicode_EncodeUTF32(
data: *const wchar_t,
length: Py_ssize_t,
errors: *const c_char,
byteorder: c_int,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsUTF16String` instead")]
pub fn PyUnicode_EncodeUTF16(
data: *const wchar_t,
length: Py_ssize_t,
errors: *const c_char,
byteorder: c_int,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsUnicodeEscapeString` instead")]
pub fn PyUnicode_EncodeUnicodeEscape(data: *const wchar_t, length: Py_ssize_t)
-> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsRawUnicodeEscapeString` instead")]
pub fn PyUnicode_EncodeRawUnicodeEscape(
data: *const wchar_t,
length: Py_ssize_t,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsLatin1String` instead")]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeLatin1")]
pub fn PyUnicode_EncodeLatin1(
data: *const wchar_t,
length: Py_ssize_t,
errors: *const c_char,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsASCIIString` instead")]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeASCII")]
pub fn PyUnicode_EncodeASCII(
data: *const wchar_t,
length: Py_ssize_t,
errors: *const c_char,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_AsCharmapString` instead")]
pub fn PyUnicode_EncodeCharmap(
data: *const wchar_t,
length: Py_ssize_t,
mapping: *mut PyObject,
errors: *const c_char,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `PyUnicode_Translate` instead")]
pub fn PyUnicode_TranslateCharmap(
data: *const wchar_t,
length: Py_ssize_t,
table: *mut PyObject,
errors: *const c_char,
) -> *mut PyObject;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `Py_UNICODE_TODECIMAL` instead")]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeDecimal")]
pub fn PyUnicode_EncodeDecimal(
s: *mut wchar_t,
length: Py_ssize_t,
output: *mut c_char,
errors: *const c_char,
) -> c_int;
#[cfg(not(Py_3_11))]
#[deprecated(note = "use `Py_UNICODE_TODECIMAL` instead")]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_TransformDecimalToASCII")]
pub fn PyUnicode_TransformDecimalToASCII(s: *mut wchar_t, length: Py_ssize_t) -> *mut PyObject;
// skipped _PyUnicode_IsLowercase
// skipped _PyUnicode_IsUppercase
// skipped _PyUnicode_IsTitlecase
// skipped _PyUnicode_IsWhitespace
// skipped _PyUnicode_IsLinebreak
// skipped _PyUnicode_ToLowercase
// skipped _PyUnicode_ToUppercase
// skipped _PyUnicode_ToTitlecase
#[cfg(not(PyPy))]
fn _PyUnicode_ToDecimalDigit(ch: Py_UCS4) -> c_int;
// skipped _PyUnicode_ToDigit
// skipped _PyUnicode_ToNumeric
// skipped _PyUnicode_IsDecimalDigit
// skipped _PyUnicode_IsDigit
// skipped _PyUnicode_IsNumeric
// skipped _PyUnicode_IsPrintable
// skipped _PyUnicode_IsAlpha
}
// skipped _Py_ascii_whitespace
// skipped Py_UNICODE_ISSPACE
// skipped Py_UNICODE_ISLOWER
// skipped Py_UNICODE_ISUPPER
// skipped Py_UNICODE_ISTITLE
// skipped Py_UNICODE_ISLINEBREAK
// skipped Py_UNICODE_TOLOWER
// skipped Py_UNICODE_TOUPPER
// skipped Py_UNICODE_TOTITLE
// skipped Py_UNICODE_ISDECIMAL
// skipped Py_UNICODE_ISDIGIT
// skipped Py_UNICODE_ISNUMERIC
// skipped Py_UNICODE_ISPRINTABLE
#[cfg(not(PyPy))]
pub unsafe extern "C" fn Py_UNICODE_TODECIMAL(ch: Py_UCS4) -> c_int {
_PyUnicode_ToDecimalDigit(ch)
}
#[cfg(PyPy)]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPy_UNICODE_TODECIMAL")]
pub fn Py_UNICODE_TODECIMAL(ch: Py_UCS4) -> c_int;
}
// skipped Py_UNICODE_TODIGIT
// skipped Py_UNICODE_TONUMERIC
// skipped Py_UNICODE_ISALPHA
// skipped Py_UNICODE_ISALNUM
// skipped private _PyUnicode_FromId
+13
View File
@@ -0,0 +1,13 @@
use crate::object::PyObject;
use core::ffi::c_int;
extern_libpython! {
pub fn PyErr_WarnExplicitObject(
category: *mut PyObject,
message: *mut PyObject,
filename: *mut PyObject,
lineno: c_int,
module: *mut PyObject,
registry: *mut PyObject,
) -> c_int;
}
+18
View File
@@ -0,0 +1,18 @@
// NB publicly re-exported in `src/weakrefobject.rs`
#[cfg(not(any(PyPy, GraalPy)))]
pub struct _PyWeakReference {
pub ob_base: crate::PyObject,
pub wr_object: *mut crate::PyObject,
pub wr_callback: *mut crate::PyObject,
pub hash: crate::Py_hash_t,
pub wr_prev: *mut crate::PyWeakReference,
pub wr_next: *mut crate::PyWeakReference,
#[cfg(Py_3_11)]
pub vectorcall: Option<crate::vectorcallfunc>,
#[cfg(all(Py_3_13, Py_GIL_DISABLED))]
pub weakrefs_lock: *mut crate::PyMutex,
}
// skipped _PyWeakref_GetWeakrefCount
// skipped _PyWeakref_ClearRef
// skipped PyWeakRef_GET_OBJECT
+37
View File
@@ -0,0 +1,37 @@
#[cfg(any(
all(Py_GIL_DISABLED, Py_3_13, not(Py_LIMITED_API)),
all(Py_3_15, not(Py_LIMITED_API))
))]
use crate::PyMutex;
#[cfg(any(all(Py_GIL_DISABLED, Py_3_13), Py_3_15))]
use crate::PyObject;
#[cfg(all(Py_LIMITED_API, Py_3_13))]
opaque_struct!(pub PyMutex);
#[cfg(any(all(Py_GIL_DISABLED, Py_3_13, not(Py_LIMITED_API)), Py_3_15,))]
#[repr(C)]
pub struct PyCriticalSection {
_cs_prev: usize,
_cs_mutex: *mut PyMutex,
}
#[cfg(any(all(Py_GIL_DISABLED, Py_3_13, not(Py_LIMITED_API)), Py_3_15,))]
#[repr(C)]
pub struct PyCriticalSection2 {
_cs_base: PyCriticalSection,
_cs_mutex2: *mut PyMutex,
}
#[cfg(all(not(Py_GIL_DISABLED), Py_3_13, not(Py_3_15), not(Py_LIMITED_API)))]
opaque_struct!(pub PyCriticalSection);
#[cfg(all(not(Py_GIL_DISABLED), Py_3_13, not(Py_3_15), not(Py_LIMITED_API)))]
opaque_struct!(pub PyCriticalSection2);
#[cfg(any(all(Py_GIL_DISABLED, Py_3_13), Py_3_15))]
extern_libpython! {
pub fn PyCriticalSection_Begin(c: *mut PyCriticalSection, op: *mut PyObject);
pub fn PyCriticalSection_End(c: *mut PyCriticalSection);
pub fn PyCriticalSection2_Begin(c: *mut PyCriticalSection2, a: *mut PyObject, b: *mut PyObject);
pub fn PyCriticalSection2_End(c: *mut PyCriticalSection2);
}
+844
View File
@@ -0,0 +1,844 @@
//! FFI bindings to the functions and structs defined in `datetime.h`
//!
//! This is the unsafe thin wrapper around the [CPython C API](https://docs.python.org/3/c-api/datetime.html),
//! and covers the various date and time related objects in the Python `datetime`
//! standard library module.
#[cfg(not(PyPy))]
use crate::PyCapsule_Import;
#[cfg(GraalPy)]
use crate::{PyLong_AsLong, PyLong_Check, PyObject_GetAttrString, Py_DecRef};
use crate::{PyObject, PyObject_TypeCheck, PyTypeObject, Py_IS_TYPE, Py_None};
use core::ffi::c_char;
use core::ffi::c_int;
use core::ffi::CStr;
use core::ptr;
use core::sync::atomic::{AtomicPtr, Ordering};
#[cfg(not(PyPy))]
use {crate::Py_hash_t, core::ffi::c_uchar};
// Type struct wrappers
const _PyDateTime_DATE_DATASIZE: usize = 4;
const _PyDateTime_TIME_DATASIZE: usize = 6;
const _PyDateTime_DATETIME_DATASIZE: usize = 10;
#[repr(C)]
#[derive(Debug)]
/// Structure representing a `datetime.timedelta`.
pub struct PyDateTime_Delta {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
pub days: c_int,
pub seconds: c_int,
pub microseconds: c_int,
}
#[repr(C)]
#[derive(Debug)]
pub struct PyDateTime_TZInfo {
pub ob_base: PyObject,
}
// skipped non-limited _PyDateTime_BaseTZInfo
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
/// Structure representing a `datetime.time` without a `tzinfo` member.
pub struct _PyDateTime_BaseTime {
pub ob_base: PyObject,
pub hashcode: Py_hash_t,
pub hastzinfo: c_char,
pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
}
#[repr(C)]
#[derive(Debug)]
/// Structure representing a `datetime.time`.
pub struct PyDateTime_Time {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
pub hastzinfo: c_char,
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
#[cfg(not(PyPy))]
pub fold: c_uchar,
/// # Safety
///
/// Care should be taken when reading this field. If the time does not have a
/// tzinfo then CPython may allocate as a `_PyDateTime_BaseTime` without this field.
pub tzinfo: *mut PyObject,
}
#[repr(C)]
#[derive(Debug)]
/// Structure representing a `datetime.date`
pub struct PyDateTime_Date {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
#[cfg(not(PyPy))]
pub hastzinfo: c_char,
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_DATE_DATASIZE],
}
#[cfg(not(any(PyPy, GraalPy)))]
#[repr(C)]
#[derive(Debug)]
/// Structure representing a `datetime.datetime` without a `tzinfo` member.
pub struct _PyDateTime_BaseDateTime {
pub ob_base: PyObject,
pub hashcode: Py_hash_t,
pub hastzinfo: c_char,
pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE],
}
#[repr(C)]
#[derive(Debug)]
/// Structure representing a `datetime.datetime`.
pub struct PyDateTime_DateTime {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
pub hastzinfo: c_char,
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE],
#[cfg(not(PyPy))]
pub fold: c_uchar,
/// # Safety
///
/// Care should be taken when reading this field. If the time does not have a
/// tzinfo then CPython may allocate as a `_PyDateTime_BaseDateTime` without this field.
pub tzinfo: *mut PyObject,
}
// skipped non-limited _PyDateTime_HAS_TZINFO
// Accessor functions for PyDateTime_Date and PyDateTime_DateTime
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the year component of a `PyDateTime_Date` or `PyDateTime_DateTime`.
/// Returns a signed integer greater than 0.
pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int {
// This should work for Date or DateTime
let data = (*(o as *mut PyDateTime_Date)).data;
(c_int::from(data[0]) << 8) | c_int::from(data[1])
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the month component of a `PyDateTime_Date` or `PyDateTime_DateTime`.
/// Returns a signed integer in the range `[1, 12]`.
pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int {
let data = (*(o as *mut PyDateTime_Date)).data;
c_int::from(data[2])
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the day component of a `PyDateTime_Date` or `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[1, 31]`.
pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int {
let data = (*(o as *mut PyDateTime_Date)).data;
c_int::from(data[3])
}
// Accessor macros for times
#[cfg(not(any(PyPy, GraalPy)))]
macro_rules! _PyDateTime_GET_HOUR {
($o: expr, $offset:expr) => {
c_int::from((*$o).data[$offset + 0])
};
}
#[cfg(not(any(PyPy, GraalPy)))]
macro_rules! _PyDateTime_GET_MINUTE {
($o: expr, $offset:expr) => {
c_int::from((*$o).data[$offset + 1])
};
}
#[cfg(not(any(PyPy, GraalPy)))]
macro_rules! _PyDateTime_GET_SECOND {
($o: expr, $offset:expr) => {
c_int::from((*$o).data[$offset + 2])
};
}
#[cfg(not(any(PyPy, GraalPy)))]
macro_rules! _PyDateTime_GET_MICROSECOND {
($o: expr, $offset:expr) => {
(c_int::from((*$o).data[$offset + 3]) << 16)
| (c_int::from((*$o).data[$offset + 4]) << 8)
| (c_int::from((*$o).data[$offset + 5]))
};
}
#[cfg(not(any(PyPy, GraalPy)))]
macro_rules! _PyDateTime_GET_FOLD {
($o: expr) => {
(*$o).fold
};
}
#[cfg(not(any(PyPy, GraalPy)))]
macro_rules! _PyDateTime_GET_TZINFO {
($o: expr) => {
if (*$o).hastzinfo != 0 {
(*$o).tzinfo
} else {
$crate::Py_None()
}
};
}
// Accessor functions for DateTime
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the hour component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 23]`
pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int {
_PyDateTime_GET_HOUR!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the minute component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 59]`
pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int {
_PyDateTime_GET_MINUTE!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the second component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 59]`
pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int {
_PyDateTime_GET_SECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the microsecond component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 999999]`
pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int {
_PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the fold component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 1]`
pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_uchar {
_PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the tzinfo component of a `PyDateTime_DateTime`.
/// Returns a pointer to a `PyObject` that should be either NULL or an instance
/// of a `datetime.tzinfo` subclass.
pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
_PyDateTime_GET_TZINFO!(o as *mut PyDateTime_DateTime)
}
// Accessor functions for Time
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the hour component of a `PyDateTime_Time`.
/// Returns a signed integer in the interval `[0, 23]`
pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int {
_PyDateTime_GET_HOUR!((o as *mut PyDateTime_Time), 0)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the minute component of a `PyDateTime_Time`.
/// Returns a signed integer in the interval `[0, 59]`
pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int {
_PyDateTime_GET_MINUTE!((o as *mut PyDateTime_Time), 0)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the second component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 59]`
pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int {
_PyDateTime_GET_SECOND!((o as *mut PyDateTime_Time), 0)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the microsecond component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 999999]`
pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int {
_PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0)
}
#[cfg(not(any(PyPy, GraalPy)))]
#[inline]
/// Retrieve the fold component of a `PyDateTime_Time`.
/// Returns a signed integer in the interval `[0, 1]`
pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar {
_PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the tzinfo component of a `PyDateTime_Time`.
/// Returns a pointer to a `PyObject` that should be either NULL or an instance
/// of a `datetime.tzinfo` subclass.
pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
_PyDateTime_GET_TZINFO!(o as *mut PyDateTime_Time)
}
// Accessor functions
#[cfg(not(any(PyPy, GraalPy)))]
macro_rules! _access_field {
($obj:expr, $type: ident, $field:ident) => {
(*($obj as *mut $type)).$field
};
}
// Accessor functions for PyDateTime_Delta
#[cfg(not(any(PyPy, GraalPy)))]
macro_rules! _access_delta_field {
($obj:expr, $field:ident) => {
_access_field!($obj, PyDateTime_Delta, $field)
};
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the days component of a `PyDateTime_Delta`.
///
/// Returns a signed integer in the interval [-999999999, 999999999].
///
/// Note: This retrieves a component from the underlying structure, it is *not*
/// a representation of the total duration of the structure.
pub unsafe fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int {
_access_delta_field!(o, days)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the seconds component of a `PyDateTime_Delta`.
///
/// Returns a signed integer in the interval [0, 86399].
///
/// Note: This retrieves a component from the underlying structure, it is *not*
/// a representation of the total duration of the structure.
pub unsafe fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int {
_access_delta_field!(o, seconds)
}
#[inline]
#[cfg(not(any(PyPy, GraalPy)))]
/// Retrieve the seconds component of a `PyDateTime_Delta`.
///
/// Returns a signed integer in the interval [0, 999999].
///
/// Note: This retrieves a component from the underlying structure, it is *not*
/// a representation of the total duration of the structure.
pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int {
_access_delta_field!(o, microseconds)
}
// Accessor functions for GraalPy. The macros on GraalPy work differently,
// but copying them seems suboptimal
#[inline]
#[cfg(GraalPy)]
pub unsafe fn _get_attr(obj: *mut PyObject, field: &core::ffi::CStr) -> c_int {
let result = PyObject_GetAttrString(obj, field.as_ptr());
Py_DecRef(result); // the original macros are borrowing
if PyLong_Check(result) == 1 {
PyLong_AsLong(result) as c_int
} else {
0
}
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int {
_get_attr(o, c"year")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int {
_get_attr(o, c"month")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int {
_get_attr(o, c"day")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int {
_get_attr(o, c"hour")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int {
_get_attr(o, c"minute")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int {
_get_attr(o, c"second")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int {
_get_attr(o, c"microsecond")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_int {
_get_attr(o, c"fold")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
let res = PyObject_GetAttrString(o, c"tzinfo".as_ptr().cast());
Py_DecRef(res); // the original macros are borrowing
res
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int {
_get_attr(o, c"hour")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int {
_get_attr(o, c"minute")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int {
_get_attr(o, c"second")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int {
_get_attr(o, c"microsecond")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_int {
_get_attr(o, c"fold")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
let res = PyObject_GetAttrString(o, c"tzinfo".as_ptr().cast());
Py_DecRef(res); // the original macros are borrowing
res
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int {
_get_attr(o, c"days")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int {
_get_attr(o, c"seconds")
}
#[inline]
#[cfg(GraalPy)]
pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int {
_get_attr(o, c"microseconds")
}
#[cfg(PyPy)]
extern_libpython! {
// skipped _PyDateTime_HAS_TZINFO (not in PyPy)
#[link_name = "PyPyDateTime_GET_YEAR"]
pub fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_GET_MONTH"]
pub fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_GET_DAY"]
pub fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_HOUR"]
pub fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_MINUTE"]
pub fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_SECOND"]
pub fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_MICROSECOND"]
pub fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_GET_FOLD"]
pub fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_TZINFO"]
#[cfg(Py_3_10)]
pub fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject;
#[link_name = "PyPyDateTime_TIME_GET_HOUR"]
pub fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_MINUTE"]
pub fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_SECOND"]
pub fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_MICROSECOND"]
pub fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_FOLD"]
pub fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_TZINFO"]
#[cfg(Py_3_10)]
pub fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject;
#[link_name = "PyPyDateTime_DELTA_GET_DAYS"]
pub fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DELTA_GET_SECONDS"]
pub fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DELTA_GET_MICROSECONDS"]
pub fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct PyDateTime_CAPI {
pub DateType: *mut PyTypeObject,
pub DateTimeType: *mut PyTypeObject,
pub TimeType: *mut PyTypeObject,
pub DeltaType: *mut PyTypeObject,
pub TZInfoType: *mut PyTypeObject,
pub TimeZone_UTC: *mut PyObject,
pub Date_FromDate: unsafe extern "C" fn(
year: c_int,
month: c_int,
day: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
pub DateTime_FromDateAndTime: unsafe extern "C" fn(
year: c_int,
month: c_int,
day: c_int,
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
tzinfo: *mut PyObject,
cls: *mut PyTypeObject,
) -> *mut PyObject,
pub Time_FromTime: unsafe extern "C" fn(
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
tzinfo: *mut PyObject,
cls: *mut PyTypeObject,
) -> *mut PyObject,
pub Delta_FromDelta: unsafe extern "C" fn(
days: c_int,
seconds: c_int,
microseconds: c_int,
normalize: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
pub TimeZone_FromTimeZone:
unsafe extern "C" fn(offset: *mut PyObject, name: *mut PyObject) -> *mut PyObject,
pub DateTime_FromTimestamp: unsafe extern "C" fn(
cls: *mut PyTypeObject,
args: *mut PyObject,
kwargs: *mut PyObject,
) -> *mut PyObject,
pub Date_FromTimestamp:
unsafe extern "C" fn(cls: *mut PyTypeObject, args: *mut PyObject) -> *mut PyObject,
pub DateTime_FromDateAndTimeAndFold: unsafe extern "C" fn(
year: c_int,
month: c_int,
day: c_int,
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
tzinfo: *mut PyObject,
fold: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
pub Time_FromTimeAndFold: unsafe extern "C" fn(
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
tzinfo: *mut PyObject,
fold: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
}
// SAFETY: Python already shares this object between threads, so it's no more evil for us to do it too!
unsafe impl Sync for PyDateTime_CAPI {}
pub const PyDateTime_CAPSULE_NAME: &CStr = c"datetime.datetime_CAPI";
/// Returns a pointer to a `PyDateTime_CAPI` instance
///
/// # Note
/// This function will return a null pointer until
/// `PyDateTime_IMPORT` is called
#[inline]
pub unsafe fn PyDateTimeAPI() -> *mut PyDateTime_CAPI {
PyDateTimeAPI_impl.load(Ordering::Acquire)
}
/// Populates the `PyDateTimeAPI` object
pub unsafe fn PyDateTime_IMPORT() {
if PyDateTimeAPI_impl.load(Ordering::Relaxed).is_null() {
// PyPy expects the C-API to be initialized via PyDateTime_Import, so trying to use
// `PyCapsule_Import` will behave unexpectedly in pypy.
#[cfg(PyPy)]
let py_datetime_c_api = PyDateTime_Import();
#[cfg(not(PyPy))]
let py_datetime_c_api =
PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *mut PyDateTime_CAPI;
if py_datetime_c_api.is_null() {
return;
}
// Protect against race conditions when the datetime API is concurrently
// initialized in multiple threads.
let _ = PyDateTimeAPI_impl.compare_exchange(
ptr::null_mut(),
py_datetime_c_api,
Ordering::Release,
Ordering::Relaxed,
);
}
}
#[inline]
pub unsafe fn PyDateTime_TimeZone_UTC() -> *mut PyObject {
(*PyDateTimeAPI()).TimeZone_UTC
}
/// Type Check macros
///
/// These are bindings around the C API typecheck macros, all of them return
/// `1` if True and `0` if False. In all type check macros, the argument (`op`)
/// must not be `NULL`.
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DateType` or subtype.
pub unsafe fn PyDate_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DateType`.
pub unsafe fn PyDate_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, (*PyDateTimeAPI()).DateType)
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DateTimeType` or subtype.
pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, (*PyDateTimeAPI()).DateTimeType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DateTimeType`.
pub unsafe fn PyDateTime_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, (*PyDateTimeAPI()).DateTimeType)
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.TimeType` or subtype.
pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, (*PyDateTimeAPI()).TimeType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.TimeType`.
pub unsafe fn PyTime_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, (*PyDateTimeAPI()).TimeType)
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DetaType` or subtype.
pub unsafe fn PyDelta_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, (*PyDateTimeAPI()).DeltaType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DeltaType`.
pub unsafe fn PyDelta_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, (*PyDateTimeAPI()).DeltaType)
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.TZInfoType` or subtype.
pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, (*PyDateTimeAPI()).TZInfoType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.TZInfoType`.
pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, (*PyDateTimeAPI()).TZInfoType)
}
pub unsafe fn PyDate_FromDate(year: c_int, month: c_int, day: c_int) -> *mut PyObject {
((*PyDateTimeAPI()).Date_FromDate)(year, month, day, (*PyDateTimeAPI()).DateType)
}
#[allow(clippy::too_many_arguments)]
/// See <https://github.com/python/cpython/blob/3.10/Include/datetime.h#L226-L228>
pub unsafe fn PyDateTime_FromDateAndTime(
year: c_int,
month: c_int,
day: c_int,
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
) -> *mut PyObject {
((*PyDateTimeAPI()).DateTime_FromDateAndTime)(
year,
month,
day,
hour,
minute,
second,
microsecond,
Py_None(),
(*PyDateTimeAPI()).DateTimeType,
)
}
#[allow(clippy::too_many_arguments)]
/// See <https://github.com/python/cpython/blob/3.10/Include/datetime.h#L230-L232>
pub unsafe fn PyDateTime_FromDateAndTimeAndFold(
year: c_int,
month: c_int,
day: c_int,
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
fold: c_int,
) -> *mut PyObject {
((*PyDateTimeAPI()).DateTime_FromDateAndTimeAndFold)(
year,
month,
day,
hour,
minute,
second,
microsecond,
Py_None(),
fold,
(*PyDateTimeAPI()).DateTimeType,
)
}
pub unsafe fn PyTime_FromTime(
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
) -> *mut PyObject {
((*PyDateTimeAPI()).Time_FromTime)(
hour,
minute,
second,
microsecond,
Py_None(),
(*PyDateTimeAPI()).TimeType,
)
}
pub unsafe fn PyTime_FromTimeAndFold(
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
fold: c_int,
) -> *mut PyObject {
((*PyDateTimeAPI()).Time_FromTimeAndFold)(
hour,
minute,
second,
microsecond,
Py_None(),
fold,
(*PyDateTimeAPI()).TimeType,
)
}
pub unsafe fn PyDelta_FromDSU(days: c_int, seconds: c_int, microseconds: c_int) -> *mut PyObject {
((*PyDateTimeAPI()).Delta_FromDelta)(
days,
seconds,
microseconds,
1,
(*PyDateTimeAPI()).DeltaType,
)
}
pub unsafe fn PyTimeZone_FromOffset(offset: *mut PyObject) -> *mut PyObject {
((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, core::ptr::null_mut())
}
pub unsafe fn PyTimeZone_FromOffsetAndName(
offset: *mut PyObject,
name: *mut PyObject,
) -> *mut PyObject {
((*PyDateTimeAPI()).TimeZone_FromTimeZone)(offset, name)
}
#[cfg(not(PyPy))]
pub unsafe fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject {
let f = (*PyDateTimeAPI()).DateTime_FromTimestamp;
f((*PyDateTimeAPI()).DateTimeType, args, core::ptr::null_mut())
}
#[cfg(not(PyPy))]
pub unsafe fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject {
let f = (*PyDateTimeAPI()).Date_FromTimestamp;
f((*PyDateTimeAPI()).DateType, args)
}
#[cfg(PyPy)]
extern_libpython! {
#[link_name = "PyPyDate_FromTimestamp"]
pub fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject;
#[link_name = "PyPyDateTime_FromTimestamp"]
pub fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject;
}
#[cfg(PyPy)]
extern_libpython! {
#[link_name = "_PyPyDateTime_Import"]
pub fn PyDateTime_Import() -> *mut PyDateTime_CAPI;
}
// Rust specific implementation details
static PyDateTimeAPI_impl: AtomicPtr<PyDateTime_CAPI> = AtomicPtr::new(ptr::null_mut());
+133
View File
@@ -0,0 +1,133 @@
use crate::methodobject::PyMethodDef;
use crate::object::{PyObject, PyTypeObject};
use crate::Py_ssize_t;
use core::ffi::{c_char, c_int, c_void};
use core::ptr;
pub type getter = unsafe extern "C" fn(slf: *mut PyObject, closure: *mut c_void) -> *mut PyObject;
pub type setter =
unsafe extern "C" fn(slf: *mut PyObject, value: *mut PyObject, closure: *mut c_void) -> c_int;
/// Represents the [PyGetSetDef](https://docs.python.org/3/c-api/structures.html#c.PyGetSetDef)
/// structure.
///
/// Note that CPython may leave fields uninitialized. You must ensure that
/// `name` != NULL before dereferencing or reading other fields.
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct PyGetSetDef {
pub name: *const c_char,
pub get: Option<getter>,
pub set: Option<setter>,
pub doc: *const c_char,
pub closure: *mut c_void,
}
impl Default for PyGetSetDef {
fn default() -> PyGetSetDef {
PyGetSetDef {
name: ptr::null(),
get: None,
set: None,
doc: ptr::null(),
closure: ptr::null_mut(),
}
}
}
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyClassMethodDescr_Type")]
pub static mut PyClassMethodDescr_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyGetSetDescr_Type")]
pub static mut PyGetSetDescr_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyMemberDescr_Type")]
pub static mut PyMemberDescr_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyMethodDescr_Type")]
pub static mut PyMethodDescr_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyWrapperDescr_Type")]
pub static mut PyWrapperDescr_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyDictProxy_Type")]
pub static mut PyDictProxy_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyProperty_Type")]
pub static mut PyProperty_Type: PyTypeObject;
}
extern_libpython! {
pub fn PyDescr_NewMethod(arg1: *mut PyTypeObject, arg2: *mut PyMethodDef) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDescr_NewClassMethod")]
pub fn PyDescr_NewClassMethod(arg1: *mut PyTypeObject, arg2: *mut PyMethodDef)
-> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDescr_NewMember")]
pub fn PyDescr_NewMember(arg1: *mut PyTypeObject, arg2: *mut PyMemberDef) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDescr_NewGetSet")]
pub fn PyDescr_NewGetSet(arg1: *mut PyTypeObject, arg2: *mut PyGetSetDef) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDictProxy_New")]
pub fn PyDictProxy_New(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyWrapper_New(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
}
/// Represents the [PyMemberDef](https://docs.python.org/3/c-api/structures.html#c.PyMemberDef)
/// structure.
///
/// Note that CPython may leave fields uninitialized. You must always ensure that
/// `name` != NULL before dereferencing or reading other fields.
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct PyMemberDef {
pub name: *const c_char,
pub type_code: c_int,
pub offset: Py_ssize_t,
pub flags: c_int,
pub doc: *const c_char,
}
impl Default for PyMemberDef {
fn default() -> PyMemberDef {
PyMemberDef {
name: ptr::null_mut(),
type_code: 0,
offset: 0,
flags: 0,
doc: ptr::null_mut(),
}
}
}
/* Types */
pub const Py_T_SHORT: c_int = 0;
pub const Py_T_INT: c_int = 1;
pub const Py_T_LONG: c_int = 2;
pub const Py_T_FLOAT: c_int = 3;
pub const Py_T_DOUBLE: c_int = 4;
pub const Py_T_STRING: c_int = 5;
#[deprecated(note = "Use Py_T_OBJECT_EX instead")]
pub const _Py_T_OBJECT: c_int = 6;
pub const Py_T_CHAR: c_int = 7;
pub const Py_T_BYTE: c_int = 8;
pub const Py_T_UBYTE: c_int = 9;
pub const Py_T_USHORT: c_int = 10;
pub const Py_T_UINT: c_int = 11;
pub const Py_T_ULONG: c_int = 12;
pub const Py_T_STRING_INPLACE: c_int = 13;
pub const Py_T_BOOL: c_int = 14;
pub const Py_T_OBJECT_EX: c_int = 16;
pub const Py_T_LONGLONG: c_int = 17;
pub const Py_T_ULONGLONG: c_int = 18;
pub const Py_T_PYSSIZET: c_int = 19;
#[deprecated(note = "Value is always none")]
pub const _Py_T_NONE: c_int = 20;
/* Flags */
pub const Py_READONLY: c_int = 1;
#[cfg(Py_3_10)]
pub const Py_AUDIT_READ: c_int = 2; // Added in 3.10, harmless no-op before that
#[deprecated]
pub const _Py_WRITE_RESTRICTED: c_int = 4; // Deprecated, no-op. Do not reuse the value.
pub const Py_RELATIVE_OFFSET: c_int = 8;
extern_libpython! {
pub fn PyMember_GetOne(addr: *const c_char, l: *mut PyMemberDef) -> *mut PyObject;
pub fn PyMember_SetOne(addr: *mut c_char, l: *mut PyMemberDef, value: *mut PyObject) -> c_int;
}
+150
View File
@@ -0,0 +1,150 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_int};
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyDict_Type")]
pub static mut PyDict_Type: PyTypeObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyDict_Check(op: *mut PyObject) -> c_int {
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyDict_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyDict_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyDict_CheckExact(op: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_New")]
pub fn PyDict_New() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDict_GetItem")]
pub fn PyDict_GetItem(mp: *mut PyObject, key: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDict_GetItemWithError")]
pub fn PyDict_GetItemWithError(mp: *mut PyObject, key: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDict_SetItem")]
pub fn PyDict_SetItem(mp: *mut PyObject, key: *mut PyObject, item: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_DelItem")]
pub fn PyDict_DelItem(mp: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_Clear")]
pub fn PyDict_Clear(mp: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyDict_Next")]
pub fn PyDict_Next(
mp: *mut PyObject,
pos: *mut Py_ssize_t,
key: *mut *mut PyObject,
value: *mut *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_Keys")]
pub fn PyDict_Keys(mp: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDict_Values")]
pub fn PyDict_Values(mp: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDict_Items")]
pub fn PyDict_Items(mp: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDict_Size")]
pub fn PyDict_Size(mp: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyDict_Copy")]
pub fn PyDict_Copy(mp: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDict_Contains")]
pub fn PyDict_Contains(mp: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_Update")]
pub fn PyDict_Update(mp: *mut PyObject, other: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_Merge")]
pub fn PyDict_Merge(mp: *mut PyObject, other: *mut PyObject, _override: c_int) -> c_int;
pub fn PyDict_MergeFromSeq2(d: *mut PyObject, seq2: *mut PyObject, _override: c_int) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_GetItemString")]
pub fn PyDict_GetItemString(dp: *mut PyObject, key: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyDict_SetItemString")]
pub fn PyDict_SetItemString(
dp: *mut PyObject,
key: *const c_char,
item: *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_DelItemString")]
pub fn PyDict_DelItemString(dp: *mut PyObject, key: *const c_char) -> c_int;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyDict_GetItemRef")]
pub fn PyDict_GetItemRef(
dp: *mut PyObject,
key: *mut PyObject,
result: *mut *mut PyObject,
) -> c_int;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyDict_GetItemStringRef")]
pub fn PyDict_GetItemStringRef(
dp: *mut PyObject,
key: *const c_char,
result: *mut *mut PyObject,
) -> c_int;
#[cfg(all(Py_3_13, any(not(Py_LIMITED_API), Py_3_15)))]
pub fn PyDict_SetDefaultRef(
mp: *mut PyObject,
key: *mut PyObject,
default_value: *mut PyObject,
result: *mut *mut PyObject,
) -> c_int;
// skipped 3.10 / ex-non-limited PyObject_GenericGetDict
}
#[cfg(not(RustPython))]
extern_libpython! {
pub static mut PyDictKeys_Type: PyTypeObject;
pub static mut PyDictValues_Type: PyTypeObject;
pub static mut PyDictItems_Type: PyTypeObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyDictKeys_Type)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyDictValues_Type)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyDictItems_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyDictKeys_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyDictValues_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyDictItems_Check(op: *mut PyObject) -> c_int;
}
#[inline]
pub unsafe fn PyDictViewSet_Check(op: *mut PyObject) -> c_int {
(PyDictKeys_Check(op) != 0 || PyDictItems_Check(op) != 0) as c_int
}
#[cfg(not(RustPython))]
extern_libpython! {
pub static mut PyDictIterKey_Type: PyTypeObject;
pub static mut PyDictIterValue_Type: PyTypeObject;
pub static mut PyDictIterItem_Type: PyTypeObject;
pub static mut PyDictRevIterKey_Type: PyTypeObject;
pub static mut PyDictRevIterValue_Type: PyTypeObject;
pub static mut PyDictRevIterItem_Type: PyTypeObject;
}
#[cfg(any(GraalPy, Py_LIMITED_API))]
// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985)
opaque_struct!(pub PyDictObject);
+6
View File
@@ -0,0 +1,6 @@
use crate::object::PyTypeObject;
extern_libpython! {
pub static mut PyEnum_Type: PyTypeObject;
pub static mut PyReversed_Type: PyTypeObject;
}
+37
View File
@@ -0,0 +1,37 @@
use crate::object::PyObject;
use core::ffi::{c_char, c_int};
pub const PY_STDIOTEXTMODE: &str = "b";
extern_libpython! {
pub fn PyFile_FromFd(
arg1: c_int,
arg2: *const c_char,
arg3: *const c_char,
arg4: c_int,
arg5: *const c_char,
arg6: *const c_char,
arg7: *const c_char,
arg8: c_int,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyFile_GetLine")]
pub fn PyFile_GetLine(arg1: *mut PyObject, arg2: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyFile_WriteObject")]
pub fn PyFile_WriteObject(arg1: *mut PyObject, arg2: *mut PyObject, arg3: c_int) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyFile_WriteString")]
pub fn PyFile_WriteString(arg1: *const c_char, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyFile_AsFileDescriptor")]
pub fn PyObject_AsFileDescriptor(arg1: *mut PyObject) -> c_int;
}
extern_libpython! {
#[deprecated(note = "Python 3.12")]
pub static mut Py_FileSystemDefaultEncoding: *const c_char;
#[deprecated(note = "Python 3.12")]
pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char;
#[deprecated(note = "Python 3.12")]
pub static mut Py_HasFileSystemDefaultEncoding: c_int;
// skipped 3.12-deprecated Py_UTF8Mode
}
// skipped _PyIsSelectable_fd
+9
View File
@@ -0,0 +1,9 @@
use crate::pyport::Py_ssize_t;
use core::ffi::c_char;
use libc::wchar_t;
extern_libpython! {
pub fn Py_DecodeLocale(arg1: *const c_char, size: *mut Py_ssize_t) -> *mut wchar_t;
pub fn Py_EncodeLocale(text: *const wchar_t, error_pos: *mut Py_ssize_t) -> *mut c_char;
}
+53
View File
@@ -0,0 +1,53 @@
use crate::object::*;
use core::ffi::{c_double, c_int};
#[cfg(Py_LIMITED_API)]
// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985)
opaque_struct!(pub PyFloatObject);
extern_libpython! {
#[cfg(not(RustPython))]
#[cfg_attr(PyPy, link_name = "PyPyFloat_Type")]
pub static mut PyFloat_Type: PyTypeObject;
#[cfg(RustPython)]
pub fn PyFloat_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyFloat_CheckExact(op: *mut PyObject) -> c_int;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyFloat_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyFloat_Type)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyFloat_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyFloat_Type)
}
// skipped Py_RETURN_NAN
// skipped Py_RETURN_INF
extern_libpython! {
pub fn PyFloat_GetMax() -> c_double;
pub fn PyFloat_GetMin() -> c_double;
pub fn PyFloat_GetInfo() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyFloat_FromString")]
pub fn PyFloat_FromString(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyFloat_FromDouble")]
pub fn PyFloat_FromDouble(arg1: c_double) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyFloat_AsDouble")]
pub fn PyFloat_AsDouble(arg1: *mut PyObject) -> c_double;
}
// skipped non-limited _PyFloat_Pack2
// skipped non-limited _PyFloat_Pack4
// skipped non-limited _PyFloat_Pack8
// skipped non-limited _PyFloat_Unpack2
// skipped non-limited _PyFloat_Unpack4
// skipped non-limited _PyFloat_Unpack8
// skipped non-limited _PyFloat_DebugMallocStats
// skipped non-limited _PyFloat_FormatAdvancedWriter
+13
View File
@@ -0,0 +1,13 @@
#[cfg(Py_3_9)]
use crate::PyObject;
#[cfg(all(Py_3_9, not(RustPython)))]
use crate::PyTypeObject;
extern_libpython! {
#[cfg(Py_3_9)]
#[cfg_attr(PyPy, link_name = "PyPy_GenericAlias")]
pub fn Py_GenericAlias(origin: *mut PyObject, args: *mut PyObject) -> *mut PyObject;
#[cfg(all(Py_3_9, not(RustPython)))]
pub static mut Py_GenericAliasType: PyTypeObject;
}
+306
View File
@@ -0,0 +1,306 @@
// On x86 Windows, `raw-dylib` with `import_name_type = "undecorated"` removes the
// leading cdecl underscore from function names. This is expected behavior for
// `import_name_type = "undecorated"` (not a rustc bug): it strips the cdecl `_`
// prefix, which collides with symbols whose real names start with `_Py`.
// See https://doc.rust-lang.org/reference/items/external-blocks.html#the-import_name_type-key
//
// That matches ordinary `Py_*` exports, but it breaks CPython's internal `_Py*`
// function exports whose real DLL names already start with an underscore. For
// those functions, ask rustc for one extra underscore so that x86 undecoration
// lands back on CPython's export.
//
// Variables are intentionally excluded here: `import_name_type` does not affect
// variable imports, so `_Py_*` statics continue to work without any rewriting.
#[allow(unused_macros, reason = "used indirectly by extern_libpython_item!")]
macro_rules! extern_libpython_cpython_private_fn {
($(#[$attrs:meta])* $vis:vis $name:ident($($args:tt)*) $(-> $ret:ty)?) => {
#[cfg_attr(
all(windows, target_arch = "x86", not(any(PyPy, GraalPy))),
link_name = concat!("_", stringify!($name))
)]
$(#[$attrs])*
$vis fn $name($($args)*) $(-> $ret)?;
};
}
// Keep this list in sync with `_Py*` function imports declared through
// `extern_libpython!`. The x86 workaround only needs to apply to functions:
// statics keep their original names even when `import_name_type` is set. Match
// by name only here so the function signature stays in a single generic arm.
//
// TODO: reduce the number of `_Py*` exports from pyo3-ffi over time — the fewer
// CPython-private functions we expose, the smaller this workaround list becomes.
#[allow(unused_macros, reason = "used indirectly by extern_libpython_item!")]
macro_rules! extern_libpython_maybe_private_fn {
(
[_PyObject_CallFunction_SizeT]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyObject_MakeTpCall]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_Py_CheckFunctionResult]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyBytes_Resize]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyLong_AsByteArray]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyLong_FromByteArray]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyUnicode_Ready]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyUnicode_ToDecimalDigit]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyThreadState_UncheckedGet]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyObject_GC_New]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyObject_GC_NewVar]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyObject_GC_Resize]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyObject_New]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyObject_NewVar]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_Py_HashBytes]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_Py_DECREF_DecRefTotal]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_Py_Dealloc]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_Py_DecRef]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_Py_INCREF_IncRefTotal]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_Py_IncRef]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_Py_NegativeRefcount]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[_PyErr_BadInternalCall]
$(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
extern_libpython_cpython_private_fn! { $(#[$attrs])* $vis $name($($args)*) $(-> $ret)? }
};
(
[$name:ident]
$(#[$attrs:meta])* $vis:vis fn $fn_name:ident($($args:tt)*) $(-> $ret:ty)?
) => {
$(#[$attrs])*
$vis fn $fn_name($($args)*) $(-> $ret)?;
};
}
macro_rules! extern_libpython_item {
($(#[$attrs:meta])* $vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?) => {
extern_libpython_maybe_private_fn! {
[$name]
$(#[$attrs])*
$vis fn $name($($args)*) $(-> $ret)?
}
};
($(#[$attrs:meta])* $vis:vis static mut $name:ident: $ty:ty) => {
$(#[$attrs])*
$vis static mut $name: $ty;
};
($(#[$attrs:meta])* $vis:vis static $name:ident: $ty:ty) => {
$(#[$attrs])*
$vis static $name: $ty;
};
}
macro_rules! extern_libpython_items {
() => {};
(
$(#[$attrs:meta])*
$vis:vis fn $name:ident($($args:tt)*) $(-> $ret:ty)?;
$($rest:tt)*
) => {
extern_libpython_item! {
$(#[$attrs])*
$vis fn $name($($args)*) $(-> $ret)?
}
extern_libpython_items! { $($rest)* }
};
(
$(#[$attrs:meta])*
$vis:vis static mut $name:ident: $ty:ty;
$($rest:tt)*
) => {
extern_libpython_item! {
$(#[$attrs])*
$vis static mut $name: $ty
}
extern_libpython_items! { $($rest)* }
};
(
$(#[$attrs:meta])*
$vis:vis static $name:ident: $ty:ty;
$($rest:tt)*
) => {
extern_libpython_item! {
$(#[$attrs])*
$vis static $name: $ty
}
extern_libpython_items! { $($rest)* }
};
}
/// Helper macro to declare `extern` blocks that link against libpython on Windows
/// using `raw-dylib`, eliminating the need for import libraries.
///
/// The build script sets a `pyo3_dll` cfg value to the target DLL name (e.g. `python312`),
/// and this macro expands to the appropriate `#[link(name = "...", kind = "raw-dylib")]`
/// attribute for that DLL.
///
/// # Usage
///
/// ```rust,ignore
/// // Default ABI "C" (most common):
/// extern_libpython! {
/// pub fn PyObject_Call(
/// callable: *mut PyObject,
/// args: *mut PyObject,
/// kwargs: *mut PyObject,
/// ) -> *mut PyObject;
/// }
///
/// // Explicit ABI:
/// extern_libpython! { "C-unwind" {
/// pub fn PyGILState_Ensure() -> PyGILState_STATE;
/// }}
/// ```
macro_rules! extern_libpython {
// Explicit ABI
($abi:literal { $($body:tt)* }) => {
extern_libpython!(@impl $abi { $($body)* }
// abi3
"python3", "python3_d",
// abi3t
"python3t", "python3t_d",
// Python 3.8 - 3.15
"python38", "python38_d",
"python39", "python39_d",
"python310", "python310_d",
"python311", "python311_d",
"python312", "python312_d",
"python313", "python313_d",
"python314", "python314_d",
"python315", "python315_d",
"python316", "python316_d",
// free-threaded builds (3.13+)
"python313t", "python313t_d",
"python314t", "python314t_d",
"python315t", "python315t_d",
"python316t", "python316t_d",
// PyPy (DLL is libpypy3.X-c.dll, not pythonXY.dll)
"libpypy3.11-c",
);
};
// Internal: generate cfg_attr for each DLL name. One of these will be selected
// by `pyo3-ffi`'s `build.rs`.
//
// On x86 Windows, Python DLLs export undecorated symbol names (no leading
// underscore), but the default for raw-dylib on x86 is fully-decorated
// (cdecl adds a `_` prefix). We use `import_name_type = "undecorated"` to
// match. The `import_name_type` key is only valid on x86, so we need
// separate cfg_attr arms per architecture.
(@impl $abi:literal { $($body:tt)* } $($dll:literal),* $(,)?) => {
$(
#[cfg_attr(all(windows, pyo3_use_raw_dylib, target_arch = "x86", pyo3_dll = $dll),
link(name = $dll, kind = "raw-dylib", import_name_type = "undecorated"))]
#[cfg_attr(all(windows, pyo3_use_raw_dylib, not(target_arch = "x86"), pyo3_dll = $dll),
link(name = $dll, kind = "raw-dylib"))]
)*
#[cfg_attr(all(windows, not(pyo3_use_raw_dylib)), link(name = "pythonXY"))]
extern $abi {
extern_libpython_items! { $($body)* }
}
};
// Default ABI: "C"
($($body:tt)*) => {
extern_libpython!("C" { $($body)* });
};
}
+35
View File
@@ -0,0 +1,35 @@
#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))]
mod atomic_c_ulong {
pub struct GetAtomicCULong<const WIDTH: usize>();
pub trait AtomicCULongType {
type Type;
}
impl AtomicCULongType for GetAtomicCULong<32> {
type Type = core::sync::atomic::AtomicU32;
}
impl AtomicCULongType for GetAtomicCULong<64> {
type Type = core::sync::atomic::AtomicU64;
}
pub type TYPE =
<GetAtomicCULong<{ core::mem::size_of::<core::ffi::c_ulong>() * 8 }> as AtomicCULongType>::Type;
}
/// Typedef for an atomic integer to match the platform-dependent c_ulong type.
#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))]
#[doc(hidden)]
pub type AtomicCULong = atomic_c_ulong::TYPE;
/// Guard to hang the current thread indefinitely when dropped.
#[cfg(not(any(Py_3_14, target_arch = "wasm32")))]
pub struct HangThread;
#[cfg(not(any(Py_3_14, target_arch = "wasm32")))]
impl Drop for HangThread {
fn drop(&mut self) {
loop {
std::thread::park(); // Block forever.
}
}
}
+87
View File
@@ -0,0 +1,87 @@
use crate::object::PyObject;
use core::ffi::{c_char, c_int, c_long};
extern_libpython! {
pub fn PyImport_GetMagicNumber() -> c_long;
pub fn PyImport_GetMagicTag() -> *const c_char;
#[cfg_attr(PyPy, link_name = "PyPyImport_ExecCodeModule")]
pub fn PyImport_ExecCodeModule(name: *const c_char, co: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_ExecCodeModuleEx")]
pub fn PyImport_ExecCodeModuleEx(
name: *const c_char,
co: *mut PyObject,
pathname: *const c_char,
) -> *mut PyObject;
pub fn PyImport_ExecCodeModuleWithPathnames(
name: *const c_char,
co: *mut PyObject,
pathname: *const c_char,
cpathname: *const c_char,
) -> *mut PyObject;
pub fn PyImport_ExecCodeModuleObject(
name: *mut PyObject,
co: *mut PyObject,
pathname: *mut PyObject,
cpathname: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_GetModuleDict")]
pub fn PyImport_GetModuleDict() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_GetModule")]
pub fn PyImport_GetModule(name: *mut PyObject) -> *mut PyObject;
pub fn PyImport_AddModuleObject(name: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_AddModule")]
pub fn PyImport_AddModule(name: *const c_char) -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyImport_AddModuleRef")]
pub fn PyImport_AddModuleRef(name: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_ImportModule")]
pub fn PyImport_ImportModule(name: *const c_char) -> *mut PyObject;
#[cfg(not(Py_3_15))]
#[deprecated(note = "Python 3.13")]
#[cfg_attr(PyPy, link_name = "PyPyImport_ImportModuleNoBlock")]
pub fn PyImport_ImportModuleNoBlock(name: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_ImportModuleLevel")]
pub fn PyImport_ImportModuleLevel(
name: *const c_char,
globals: *mut PyObject,
locals: *mut PyObject,
fromlist: *mut PyObject,
level: c_int,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_ImportModuleLevelObject")]
pub fn PyImport_ImportModuleLevelObject(
name: *mut PyObject,
globals: *mut PyObject,
locals: *mut PyObject,
fromlist: *mut PyObject,
level: c_int,
) -> *mut PyObject;
}
#[inline]
pub unsafe fn PyImport_ImportModuleEx(
name: *const c_char,
globals: *mut PyObject,
locals: *mut PyObject,
fromlist: *mut PyObject,
) -> *mut PyObject {
PyImport_ImportModuleLevel(name, globals, locals, fromlist, 0)
}
extern_libpython! {
pub fn PyImport_GetImporter(path: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_Import")]
pub fn PyImport_Import(name: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_ReloadModule")]
pub fn PyImport_ReloadModule(m: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_3_9))]
#[deprecated(note = "Removed in Python 3.9 as it was \"For internal use only\".")]
pub fn PyImport_Cleanup();
pub fn PyImport_ImportFrozenModuleObject(name: *mut PyObject) -> c_int;
pub fn PyImport_ImportFrozenModule(name: *const c_char) -> c_int;
pub fn PyImport_AppendInittab(
name: *const c_char,
initfunc: Option<unsafe extern "C" fn() -> *mut PyObject>,
) -> c_int;
}
+19
View File
@@ -0,0 +1,19 @@
use core::ffi::c_int;
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyOS_InterruptOccurred")]
pub fn PyOS_InterruptOccurred() -> c_int;
#[cfg(not(Py_3_10))]
#[deprecated(note = "Not documented in Python API; see Python 3.10 release notes")]
pub fn PyOS_InitInterrupts();
pub fn PyOS_BeforeFork();
pub fn PyOS_AfterFork_Parent();
pub fn PyOS_AfterFork_Child();
#[deprecated(note = "use PyOS_AfterFork_Child instead")]
#[cfg_attr(PyPy, link_name = "PyPyOS_AfterFork")]
pub fn PyOS_AfterFork();
// skipped non-limited _PyOS_IsMainThread
// skipped non-limited Windows _PyOS_SigintEvent
}
+36
View File
@@ -0,0 +1,36 @@
use crate::object::*;
use core::ffi::c_int;
#[cfg(not(RustPython))]
extern_libpython! {
pub static mut PySeqIter_Type: PyTypeObject;
pub static mut PyCallIter_Type: PyTypeObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PySeqIter_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PySeqIter_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PySeqIter_Check(op: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySeqIter_New")]
pub fn PySeqIter_New(arg1: *mut PyObject) -> *mut PyObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyCallIter_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyCallIter_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyCallIter_Check(op: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCallIter_New")]
pub fn PyCallIter_New(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
}
+609
View File
@@ -0,0 +1,609 @@
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
//! Raw FFI declarations for Python's C API.
//!
//! PyO3 can be used to write native Python modules or run Python code and modules from Rust.
//!
//! This crate just provides low level bindings to the Python interpreter.
//! It is meant for advanced users only - regular PyO3 users shouldn't
//! need to interact with this crate at all.
//!
//! The contents of this crate are not documented here, as it would entail
//! basically copying the documentation from CPython. Consult the [Python/C API Reference
//! Manual][capi] for up-to-date documentation.
//!
//! # Safety
//!
//! The functions in this crate lack individual safety documentation, but
//! generally the following apply:
//! - Pointer arguments have to point to a valid Python object of the correct type,
//! although null pointers are sometimes valid input.
//! - The vast majority can only be used safely while the thread is attached to the Python interpreter.
//! - Some functions have additional safety requirements, consult the
//! [Python/C API Reference Manual][capi]
//! for more information.
//!
//!
//! # Feature flags
//!
//! PyO3 uses [feature flags] to enable you to opt-in to additional functionality. For a detailed
//! description, see the [Features chapter of the guide].
//!
//! ## Optional feature flags
//!
//! The following features customize PyO3's behavior:
//!
//! - `abi3`: Restricts PyO3's API to a subset of the full Python API which is guaranteed by
//! [PEP 384] to be forward-compatible with future Python versions.
//!
//! ## `rustc` environment flags
//!
//! PyO3 uses `rustc`'s `--cfg` flags to enable or disable code used for different Python versions.
//! If you want to do this for your own crate, you can do so with the [`pyo3-build-config`] crate.
//!
//! - `Py_3_8`, `Py_3_9`, `Py_3_10`, `Py_3_11`, `Py_3_12`, `Py_3_13`, `Py_3_14`, `Py_3_15`: Marks code that is
//! only enabled when compiling for a given minimum Python version.
//! - `Py_LIMITED_API`: Marks code enabled when the `abi3` feature flag is enabled.
//! - `Py_GIL_DISABLED`: Marks code that runs only in the free-threaded build of CPython.
//! - `PyPy` - Marks code enabled when compiling for PyPy.
//! - `GraalPy` - Marks code enabled when compiling for GraalPy.
//!
//! Additionally, you can query for the values `Py_DEBUG`, `Py_REF_DEBUG`,
//! `Py_TRACE_REFS`, and `COUNT_ALLOCS` from `py_sys_config` to query for the
//! corresponding C build-time defines. For example, to conditionally define
//! debug code using `Py_DEBUG`, you could do:
//!
//! ```rust,ignore
//! #[cfg(py_sys_config = "Py_DEBUG")]
//! println!("only runs if python was compiled with Py_DEBUG")
//! ```
//!
//! To use these attributes, add [`pyo3-build-config`] as a build dependency in
//! your `Cargo.toml`:
//!
//! ```toml
//! [build-dependencies]
#![doc = concat!("pyo3-build-config =\"", env!("CARGO_PKG_VERSION"), "\"")]
//! ```
//!
//! And then either create a new `build.rs` file in the project root or modify
//! the existing `build.rs` file to call `use_pyo3_cfgs()`:
//!
//! ```rust,ignore
//! fn main() {
//! pyo3_build_config::use_pyo3_cfgs();
//! }
//! ```
//!
//! # Minimum supported Rust and Python versions
//!
//! `pyo3-ffi` supports the following Python distributions:
//! - CPython 3.8 or greater
//! - PyPy 7.3 (Python 3.11+)
//! - GraalPy 24.0 or greater (Python 3.10+)
//!
//! # Example: Building Python Native modules
//!
//! PyO3 can be used to generate a native Python module. The easiest way to try this out for the
//! first time is to use [`maturin`]. `maturin` is a tool for building and publishing Rust-based
//! Python packages with minimal configuration. The following steps set up some files for an example
//! Python module, install `maturin`, and then show how to build and import the Python module.
//!
//! First, create a new folder (let's call it `string_sum`) containing the following two files:
//!
//! **`Cargo.toml`**
//!
//! ```toml
//! [lib]
//! name = "string_sum"
//! # "cdylib" is necessary to produce a shared library for Python to import from.
//! #
//! # Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
//! # to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
//! # crate-type = ["cdylib", "rlib"]
//! crate-type = ["cdylib"]
//!
//! [dependencies]
#![doc = concat!("pyo3-ffi = \"", env!("CARGO_PKG_VERSION"), "\"")]
//!
//! [build-dependencies]
//! # This is only necessary if you need to configure your build based on
//! # the Python version or the compile-time configuration for the interpreter.
#![doc = concat!("pyo3_build_config = \"", env!("CARGO_PKG_VERSION"), "\"")]
//! ```
//!
//! If you need to use conditional compilation based on Python version or how
//! Python was compiled, you need to add `pyo3-build-config` as a
//! `build-dependency` in your `Cargo.toml` as in the example above and either
//! create a new `build.rs` file or modify an existing one so that
//! `pyo3_build_config::use_pyo3_cfgs()` gets called at build time:
//!
//! **`build.rs`**
//! ```rust,ignore
//! fn main() {
//! pyo3_build_config::use_pyo3_cfgs()
//! }
//! ```
//!
//! **`src/lib.rs`**
//! ```rust,no_run
//! #[cfg(Py_3_15)]
//! use core::ffi::c_void;
//! #[cfg(not(Py_3_15))]
//! use core::ffi::c_int;
//! use core::ffi::{c_char, c_long};
//! use core::ptr;
//!
//! use pyo3_ffi::*;
//!
//! #[cfg(not(Py_3_15))]
//! static mut MODULE_DEF: PyModuleDef = PyModuleDef {
//! m_base: PyModuleDef_HEAD_INIT,
//! m_name: c"string_sum".as_ptr(),
//! m_doc: c"A Python module written in Rust.".as_ptr(),
//! m_size: 0,
//! m_methods: (&raw mut METHODS).cast(),
//! m_slots: (&raw mut SLOTS).cast(),
//! m_traverse: None,
//! m_clear: None,
//! m_free: None,
//! };
//!
//! static mut METHODS: [PyMethodDef; 2] = [
//! PyMethodDef {
//! ml_name: c"sum_as_string".as_ptr(),
//! ml_meth: PyMethodDefPointer {
//! PyCFunctionFast: sum_as_string,
//! },
//! ml_flags: METH_FASTCALL,
//! ml_doc: c"returns the sum of two integers as a string".as_ptr(),
//! },
//! // A zeroed PyMethodDef to mark the end of the array.
//! PyMethodDef::zeroed(),
//! ];
//!
//! const SLOTS_LEN: usize =
//! 1 + cfg!(Py_3_12) as usize + cfg!(Py_GIL_DISABLED) as usize + 4 * (cfg!(Py_3_15) as usize);
//!
//! #[cfg(not(Py_3_15))]
//! static mut SLOTS: [PyModuleDef_Slot; SLOTS_LEN] = [
//! #[cfg(Py_3_12)]
//! PyModuleDef_Slot {
//! slot: Py_mod_multiple_interpreters,
//! value: Py_MOD_PER_INTERPRETER_GIL_SUPPORTED,
//! },
//! #[cfg(Py_GIL_DISABLED)]
//! PyModuleDef_Slot {
//! slot: Py_mod_gil,
//! value: Py_MOD_GIL_NOT_USED,
//! },
//! PyModuleDef_Slot {
//! slot: 0,
//! value: ptr::null_mut(),
//! },
//! ];
//!
//! #[cfg(Py_3_15)]
//! PyABIInfo_VAR!(ABI_INFO);
//!
//! #[cfg(Py_3_15)]
//! static mut SLOTS: [PySlot; SLOTS_LEN] = [
//! PySlot_STATIC_DATA(Py_mod_abi, core::ptr::addr_of_mut!(ABI_INFO).cast()),
//! PySlot_STATIC_DATA(Py_mod_name, c"string_sum".as_ptr() as *mut c_void),
//! PySlot_STATIC_DATA(Py_mod_doc, c"A Python module written in Rust.".as_ptr() as *mut c_void),
//! PySlot_STATIC_DATA(Py_mod_methods, (&raw mut METHODS).cast()),
//! PySlot_DATA(Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED),
//! #[cfg(Py_GIL_DISABLED)]
//! PySlot_DATA(Py_mod_gil, Py_MOD_GIL_NOT_USED),
//! PySlot_END(),
//! ];
//!
//! // The module initialization function
//! #[cfg(not(Py_3_15))]
//! #[allow(non_snake_case, reason = "must be named `PyInit_<your_module>`")]
//! #[no_mangle]
//! pub unsafe extern "C" fn PyInit_string_sum() -> *mut PyObject {
//! PyModuleDef_Init(&raw mut MODULE_DEF)
//! }
//!
//! #[cfg(Py_3_15)]
//! #[allow(non_snake_case, reason = "must be named `PyModExport_<your_module>`")]
//! #[no_mangle]
//! pub unsafe extern "C" fn PyModExport_string_sum() -> *mut PySlot {
//! (&raw mut SLOTS).cast()
//! }
//!
//! /// A helper to parse function arguments
//! /// If we used PyO3's proc macros they'd handle all of this boilerplate for us :)
//! unsafe fn parse_arg_as_i32(obj: *mut PyObject, n_arg: usize) -> Option<i32> {
//! if PyLong_Check(obj) == 0 {
//! let msg = format!(
//! "sum_as_string expected an int for positional argument {}\0",
//! n_arg
//! );
//! PyErr_SetString(PyExc_TypeError, msg.as_ptr().cast::<c_char>());
//! return None;
//! }
//!
//! // Let's keep the behaviour consistent on platforms where `c_long` is bigger than 32 bits.
//! // In particular, it is an i32 on Windows but i64 on most Linux systems
//! let mut overflow = 0;
//! let i_long: c_long = PyLong_AsLongAndOverflow(obj, &mut overflow);
//!
//! #[allow(
//! irrefutable_let_patterns,
//! reason = "some platforms have c_long equal to i32"
//! )]
//! if overflow != 0 {
//! raise_overflowerror(obj);
//! None
//! } else if let Ok(i) = i_long.try_into() {
//! Some(i)
//! } else {
//! raise_overflowerror(obj);
//! None
//! }
//! }
//!
//! unsafe fn raise_overflowerror(obj: *mut PyObject) {
//! let obj_repr = PyObject_Str(obj);
//! if !obj_repr.is_null() {
//! let mut size = 0;
//! let p = PyUnicode_AsUTF8AndSize(obj_repr, &mut size);
//! if !p.is_null() {
//! let s = core::str::from_utf8_unchecked(core::slice::from_raw_parts(
//! p.cast::<u8>(),
//! size as usize,
//! ));
//! let msg = format!("cannot fit {} in 32 bits\0", s);
//!
//! PyErr_SetString(PyExc_OverflowError, msg.as_ptr().cast::<c_char>());
//! }
//! Py_DECREF(obj_repr);
//! }
//! }
//!
//! pub unsafe extern "C" fn sum_as_string(
//! _self: *mut PyObject,
//! args: *mut *mut PyObject,
//! nargs: Py_ssize_t,
//! ) -> *mut PyObject {
//! if nargs != 2 {
//! PyErr_SetString(
//! PyExc_TypeError,
//! c"sum_as_string expected 2 positional arguments".as_ptr(),
//! );
//! return core::ptr::null_mut();
//! }
//!
//! let (first, second) = (*args, *args.add(1));
//!
//! let first = match parse_arg_as_i32(first, 1) {
//! Some(x) => x,
//! None => return core::ptr::null_mut(),
//! };
//! let second = match parse_arg_as_i32(second, 2) {
//! Some(x) => x,
//! None => return core::ptr::null_mut(),
//! };
//!
//! match first.checked_add(second) {
//! Some(sum) => {
//! let string = sum.to_string();
//! PyUnicode_FromStringAndSize(string.as_ptr().cast::<c_char>(), string.len() as isize)
//! }
//! None => {
//! PyErr_SetString(PyExc_OverflowError, c"arguments too large to add".as_ptr());
//! core::ptr::null_mut()
//! }
//! }
//! }
//! ```
//!
//! With those two files in place, now `maturin` needs to be installed. This can be done using
//! Python's package manager `pip`. First, load up a new Python `virtualenv`, and install `maturin`
//! into it:
//! ```bash
//! $ cd string_sum
//! $ python -m venv .env
//! $ source .env/bin/activate
//! $ pip install maturin
//! ```
//!
//! Now build and execute the module:
//! ```bash
//! $ maturin develop
//! # lots of progress output as maturin runs the compilation...
//! $ python
//! >>> import string_sum
//! >>> string_sum.sum_as_string(5, 20)
//! '25'
//! ```
//!
//! As well as with `maturin`, it is possible to build using [setuptools-rust] or
//! [manually][manual_builds]. Both offer more flexibility than `maturin` but require further
//! configuration.
//!
//! This example stores the module definition statically and uses the `PyModule_Create` function
//! in the CPython C API to register the module. This is the "old" style for registering modules
//! and has the limitation that it cannot support subinterpreters. You can also create a module
//! using the new multi-phase initialization API that does support subinterpreters. See the
//! `sequential` project located in the `examples` directory at the root of the `pyo3-ffi` crate
//! for a worked example of how to this using `pyo3-ffi`.
//!
//! # Using Python from Rust
//!
//! To embed Python into a Rust binary, you need to ensure that your Python installation contains a
//! shared library. The following steps demonstrate how to ensure this (for Ubuntu).
//!
//! To install the Python shared library on Ubuntu:
//! ```bash
//! sudo apt install python3-dev
//! ```
//!
//! While most projects use the safe wrapper provided by pyo3,
//! you can take a look at the [`orjson`] library as an example on how to use `pyo3-ffi` directly.
//! For those well versed in C and Rust the [tutorials] from the CPython documentation
//! can be easily converted to rust as well.
//!
//! [tutorials]: https://docs.python.org/3/extending/
//! [`orjson`]: https://github.com/ijl/orjson
//! [capi]: https://docs.python.org/3/c-api/index.html
//! [`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"
//! [`pyo3-build-config`]: https://docs.rs/pyo3-build-config
//! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book"
#![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\"")]
//! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions"
//! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI"
#![doc = concat!("[Features chapter of the guide]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/features.html#features-reference \"Features reference - PyO3 user guide\"")]
#![allow(
missing_docs,
non_camel_case_types,
non_snake_case,
non_upper_case_globals,
clippy::upper_case_acronyms,
clippy::missing_safety_doc,
clippy::ptr_eq
)]
#![warn(
clippy::alloc_instead_of_core,
clippy::std_instead_of_alloc,
clippy::std_instead_of_core
)]
#![warn(elided_lifetimes_in_paths, unused_lifetimes)]
// This crate is a hand-maintained translation of CPython's headers, so requiring "unsafe"
// blocks within those translations increases maintenance burden without providing any
// additional safety. The safety of the functions in this crate is determined by the
// original CPython headers
#![allow(unsafe_op_in_unsafe_fn)]
#[cfg(not(PyPy))]
extern crate alloc;
#[cfg(not(any(Py_3_14, target_arch = "wasm32")))]
extern crate std;
// Until `extern type` is stabilized, use the recommended approach to
// model opaque types:
// https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
macro_rules! opaque_struct {
($(#[$attrs:meta])* $pub:vis $name:ident) => {
$(#[$attrs])*
#[repr(C)]
$pub struct $name {
_data: (),
_marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
}
};
}
/// This is a helper macro to create a `&'static CStr`.
///
/// It can be used on all Rust versions supported by PyO3, unlike c"" literals which
/// were stabilised in Rust 1.77.
///
/// Due to the nature of PyO3 making heavy use of C FFI interop with Python, it is
/// common for PyO3 to use CStr.
///
/// Examples:
///
/// ```rust,no_run
/// use core::ffi::CStr;
///
/// const HELLO: &CStr = pyo3_ffi::c_str!("hello");
/// static WORLD: &CStr = pyo3_ffi::c_str!("world");
/// ```
#[macro_export]
macro_rules! c_str {
// TODO: deprecate this now MSRV is above 1.77
($s:expr) => {
$crate::_cstr_from_utf8_with_nul_checked(concat!($s, "\0"))
};
}
/// Private helper for `c_str!` macro.
#[doc(hidden)]
pub const fn _cstr_from_utf8_with_nul_checked(s: &str) -> &core::ffi::CStr {
match core::ffi::CStr::from_bytes_with_nul(s.as_bytes()) {
Ok(cstr) => cstr,
Err(_) => panic!("string contains nul bytes"),
}
}
// Macros for declaring `extern` blocks that link against libpython.
// See `impl_/macros.rs` for the implementation.
include!("impl_/macros.rs");
pub mod compat;
mod impl_;
pub use self::abstract_::*;
#[cfg(not(RustPython))]
pub use self::bltinmodule::*;
pub use self::boolobject::*;
pub use self::bytearrayobject::*;
pub use self::bytesobject::*;
pub use self::ceval::*;
pub use self::codecs::*;
pub use self::compile::*;
pub use self::complexobject::*;
#[cfg(not(Py_LIMITED_API))]
pub use self::context::*;
#[cfg(Py_3_13)]
pub use self::critical_section::*;
#[cfg(not(Py_LIMITED_API))]
pub use self::datetime::*;
pub use self::descrobject::*;
pub use self::dictobject::*;
#[cfg(not(RustPython))]
pub use self::enumobject::*;
pub use self::fileobject::*;
pub use self::fileutils::*;
pub use self::floatobject::*;
#[cfg(Py_3_9)]
pub use self::genericaliasobject::*;
pub use self::import::*;
pub use self::intrcheck::*;
pub use self::iterobject::*;
pub use self::listobject::*;
pub use self::longobject::*;
pub use self::memoryobject::*;
pub use self::methodobject::*;
pub use self::modsupport::*;
pub use self::moduleobject::*;
pub use self::object::*;
pub use self::objimpl::*;
pub use self::osmodule::*;
#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))]
pub use self::pyarena::*;
#[cfg(Py_3_11)]
pub use self::pybuffer::*;
pub use self::pycapsule::*;
pub use self::pyerrors::*;
pub use self::pyframe::*;
pub use self::pyhash::*;
pub use self::pylifecycle::*;
pub use self::pymem::*;
pub use self::pyport::*;
pub use self::pystate::*;
pub use self::pystrtod::*;
pub use self::pythonrun::*;
pub use self::pytypedefs::*;
pub use self::rangeobject::*;
pub use self::refcount::*;
pub use self::setobject::*;
pub use self::sliceobject::*;
#[cfg(Py_3_15)]
pub use self::slots::*;
pub use self::slots_generated::*;
pub use self::structseq::*;
pub use self::sysmodule::*;
pub use self::traceback::*;
pub use self::tupleobject::*;
pub use self::unicodeobject::*;
pub use self::warnings::*;
pub use self::weakrefobject::*;
mod abstract_;
// skipped asdl.h
// skipped ast.h
#[cfg(not(RustPython))]
mod bltinmodule;
mod boolobject;
mod bytearrayobject;
mod bytesobject;
// skipped cellobject.h
mod ceval;
// skipped classobject.h
mod codecs;
mod compile;
mod complexobject;
#[cfg(not(Py_LIMITED_API))]
mod context;
mod critical_section;
#[cfg(not(Py_LIMITED_API))]
pub(crate) mod datetime;
mod descrobject;
mod dictobject;
// skipped dynamic_annotations.h
#[cfg(not(RustPython))]
mod enumobject;
// skipped errcode.h
// skipped exports.h
mod fileobject;
mod fileutils;
mod floatobject;
// skipped empty frameobject.h
mod genericaliasobject;
mod import;
// skipped interpreteridobject.h
mod intrcheck;
mod iterobject;
mod listobject;
mod longobject;
mod memoryobject;
mod methodobject;
mod modsupport;
mod moduleobject;
// skipped namespaceobject.h
mod object;
mod objimpl;
// skipped odictobject.h
// skipped opcode.h
// skipped osdefs.h
mod osmodule;
// skipped parser_interface.h
// skipped patchlevel.h
// skipped picklebufobject.h
// skipped pyctype.h
// skipped py_curses.h
#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))]
mod pyarena;
#[cfg(Py_3_11)]
mod pybuffer;
mod pycapsule;
// skipped pydtrace.h
mod pyerrors;
// skipped pyexpat.h
// skipped pyfpe.h
mod pyframe;
mod pyhash;
mod pylifecycle;
// skipped pymacconfig.h
// skipped pymacro.h
// skipped pymath.h
mod pymem;
mod pyport;
mod pystate;
// skipped pystats.h
mod pythonrun;
// skipped pystrhex.h
// skipped pystrcmp.h
mod pystrtod;
// skipped pythread.h
// skipped pytime.h
mod pytypedefs;
mod rangeobject;
mod refcount;
mod setobject;
mod sliceobject;
mod slots;
mod slots_generated;
mod structseq;
mod sysmodule;
mod traceback;
// skipped tracemalloc.h
mod tupleobject;
mod unicodeobject;
mod warnings;
mod weakrefobject;
// Additional headers that are not exported by Python.h
#[deprecated(note = "Python 3.12")]
pub mod structmember;
// "Limited API" definitions matching Python's `include/cpython` directory.
#[cfg(not(any(Py_LIMITED_API, RustPython)))]
mod cpython;
#[cfg(not(any(Py_LIMITED_API, RustPython)))]
pub use self::cpython::*;
+82
View File
@@ -0,0 +1,82 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use core::ffi::c_int;
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyList_Type")]
pub static mut PyList_Type: PyTypeObject;
pub static mut PyListIter_Type: PyTypeObject;
pub static mut PyListRevIter_Type: PyTypeObject;
}
#[cfg(not(RustPython))]
#[inline]
pub unsafe fn PyList_Check(op: *mut PyObject) -> c_int {
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyList_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyList_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyList_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyList_CheckExact(op: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_New")]
pub fn PyList_New(size: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyList_Size")]
pub fn PyList_Size(arg1: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyList_GetItem")]
pub fn PyList_GetItem(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyList_GetItemRef")]
pub fn PyList_GetItemRef(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyList_SetItem")]
pub fn PyList_SetItem(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_Insert")]
pub fn PyList_Insert(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_Append")]
pub fn PyList_Append(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_GetSlice")]
pub fn PyList_GetSlice(
arg1: *mut PyObject,
arg2: Py_ssize_t,
arg3: Py_ssize_t,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyList_SetSlice")]
pub fn PyList_SetSlice(
arg1: *mut PyObject,
arg2: Py_ssize_t,
arg3: Py_ssize_t,
arg4: *mut PyObject,
) -> c_int;
#[cfg(Py_3_13)]
pub fn PyList_Extend(list: *mut PyObject, iterable: *mut PyObject) -> c_int;
#[cfg(Py_3_13)]
pub fn PyList_Clear(list: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_Sort")]
pub fn PyList_Sort(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_Reverse")]
pub fn PyList_Reverse(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyList_AsTuple")]
pub fn PyList_AsTuple(arg1: *mut PyObject) -> *mut PyObject;
// CPython macros exported as functions on PyPy or GraalPy
#[cfg(any(PyPy, GraalPy))]
#[cfg_attr(PyPy, link_name = "PyPyList_GET_ITEM")]
#[cfg_attr(GraalPy, link_name = "PyList_GetItem")]
pub fn PyList_GET_ITEM(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject;
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPyList_GET_SIZE")]
pub fn PyList_GET_SIZE(arg1: *mut PyObject) -> Py_ssize_t;
#[cfg(any(PyPy, GraalPy))]
#[cfg_attr(PyPy, link_name = "PyPyList_SET_ITEM")]
#[cfg_attr(GraalPy, link_name = "_PyList_SET_ITEM")]
pub fn PyList_SET_ITEM(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject);
}
+145
View File
@@ -0,0 +1,145 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_double, c_int, c_long, c_longlong, c_ulong, c_ulonglong, c_void};
use libc::size_t;
opaque_struct!(pub PyLongObject);
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyLong_Check(op: *mut PyObject) -> c_int {
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyLong_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyLong_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyLong_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyLong_CheckExact(op: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromLong")]
pub fn PyLong_FromLong(arg1: c_long) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromUnsignedLong")]
pub fn PyLong_FromUnsignedLong(arg1: c_ulong) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromSize_t")]
pub fn PyLong_FromSize_t(arg1: size_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromSsize_t")]
pub fn PyLong_FromSsize_t(arg1: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromDouble")]
pub fn PyLong_FromDouble(arg1: c_double) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsLong")]
pub fn PyLong_AsLong(arg1: *mut PyObject) -> c_long;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsLongAndOverflow")]
pub fn PyLong_AsLongAndOverflow(arg1: *mut PyObject, arg2: *mut c_int) -> c_long;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsSsize_t")]
pub fn PyLong_AsSsize_t(arg1: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsSize_t")]
pub fn PyLong_AsSize_t(arg1: *mut PyObject) -> size_t;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLong")]
pub fn PyLong_AsUnsignedLong(arg1: *mut PyObject) -> c_ulong;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLongMask")]
pub fn PyLong_AsUnsignedLongMask(arg1: *mut PyObject) -> c_ulong;
// skipped non-limited PyLong_AsInt
#[cfg(Py_3_14)]
pub fn PyLong_FromInt32(arg1: i32) -> *mut PyObject;
#[cfg(Py_3_14)]
pub fn PyLong_FromUInt32(arg1: u32) -> *mut PyObject;
#[cfg(Py_3_14)]
pub fn PyLong_FromInt64(arg1: i64) -> *mut PyObject;
#[cfg(Py_3_14)]
pub fn PyLong_FromUInt64(arg1: u64) -> *mut PyObject;
#[cfg(Py_3_14)]
pub fn PyLong_AsInt32(arg1: *mut PyObject, arg2: *mut i32) -> c_int;
#[cfg(Py_3_14)]
pub fn PyLong_AsUInt32(arg1: *mut PyObject, arg2: *mut u32) -> c_int;
#[cfg(Py_3_14)]
pub fn PyLong_AsInt64(arg1: *mut PyObject, arg2: *mut i64) -> c_int;
#[cfg(Py_3_14)]
pub fn PyLong_AsUInt64(arg1: *mut PyObject, arg2: *mut u64) -> c_int;
}
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub const Py_ASNATIVEBYTES_DEFAULTS: c_int = -1;
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub const Py_ASNATIVEBYTES_BIG_ENDIAN: c_int = 0;
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub const Py_ASNATIVEBYTES_LITTLE_ENDIAN: c_int = 1;
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub const Py_ASNATIVEBYTES_NATIVE_ENDIAN: c_int = 3;
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub const Py_ASNATIVEBYTES_UNSIGNED_BUFFER: c_int = 4;
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub const Py_ASNATIVEBYTES_REJECT_NEGATIVE: c_int = 8;
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub const Py_ASNATIVEBYTES_ALLOW_INDEX: c_int = 16;
extern_libpython! {
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub fn PyLong_AsNativeBytes(
v: *mut PyObject,
buffer: *mut c_void,
n_bytes: Py_ssize_t,
flags: c_int,
) -> Py_ssize_t;
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub fn PyLong_FromNativeBytes(
buffer: *const c_void,
n_bytes: size_t,
flags: c_int,
) -> *mut PyObject;
#[cfg(any(Py_3_14, all(Py_3_13, not(Py_LIMITED_API))))]
pub fn PyLong_FromUnsignedNativeBytes(
buffer: *const c_void,
n_bytes: size_t,
flags: c_int,
) -> *mut PyObject;
pub fn PyLong_GetInfo() -> *mut PyObject;
// skipped PyLong_AS_LONG
// skipped PyLong_FromPid
// skipped PyLong_AsPid
// skipped _Py_PARSE_INTPTR
// skipped _Py_PARSE_UINTPTR
#[cfg_attr(PyPy, link_name = "PyPyLong_AsDouble")]
pub fn PyLong_AsDouble(arg1: *mut PyObject) -> c_double;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromVoidPtr")]
pub fn PyLong_FromVoidPtr(arg1: *mut c_void) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsVoidPtr")]
pub fn PyLong_AsVoidPtr(arg1: *mut PyObject) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromLongLong")]
pub fn PyLong_FromLongLong(arg1: c_longlong) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromUnsignedLongLong")]
pub fn PyLong_FromUnsignedLongLong(arg1: c_ulonglong) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsLongLong")]
pub fn PyLong_AsLongLong(arg1: *mut PyObject) -> c_longlong;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLongLong")]
pub fn PyLong_AsUnsignedLongLong(arg1: *mut PyObject) -> c_ulonglong;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsUnsignedLongLongMask")]
pub fn PyLong_AsUnsignedLongLongMask(arg1: *mut PyObject) -> c_ulonglong;
#[cfg_attr(PyPy, link_name = "PyPyLong_AsLongLongAndOverflow")]
pub fn PyLong_AsLongLongAndOverflow(arg1: *mut PyObject, arg2: *mut c_int) -> c_longlong;
#[cfg_attr(PyPy, link_name = "PyPyLong_FromString")]
pub fn PyLong_FromString(
arg1: *const c_char,
arg2: *mut *mut c_char,
arg3: c_int,
) -> *mut PyObject;
}
extern_libpython! {
pub fn PyOS_strtoul(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_ulong;
pub fn PyOS_strtol(arg1: *const c_char, arg2: *mut *mut c_char, arg3: c_int) -> c_long;
}
+48
View File
@@ -0,0 +1,48 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_int};
// skipped _PyManagedBuffer_Type
extern_libpython! {
#[cfg(not(RustPython))]
#[cfg_attr(PyPy, link_name = "PyPyMemoryView_Type")]
pub static mut PyMemoryView_Type: PyTypeObject;
#[cfg(RustPython)]
pub fn PyMemoryView_Check(op: *mut PyObject) -> c_int;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyMemoryView_Type)
}
// skipped non-limited PyMemoryView_GET_BUFFER
// skipped non-limited PyMemoryView_GET_BASE
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyMemoryView_FromObject")]
pub fn PyMemoryView_FromObject(base: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyMemoryView_FromMemory")]
pub fn PyMemoryView_FromMemory(
mem: *mut c_char,
size: Py_ssize_t,
flags: c_int,
) -> *mut PyObject;
#[cfg(any(Py_3_11, not(Py_LIMITED_API)))]
#[cfg_attr(PyPy, link_name = "PyPyMemoryView_FromBuffer")]
pub fn PyMemoryView_FromBuffer(view: *const crate::Py_buffer) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyMemoryView_GetContiguous")]
pub fn PyMemoryView_GetContiguous(
base: *mut PyObject,
buffertype: c_int,
order: c_char,
) -> *mut PyObject;
}
// skipped remainder of file with comment:
/* The structs are declared here so that macros can work, but they shouldn't
be considered public. Don't access their fields directly, use the macros
and functions instead! */
+293
View File
@@ -0,0 +1,293 @@
use crate::object::{PyObject, PyTypeObject};
#[cfg(Py_3_9)]
#[cfg(not(RustPython))]
use crate::PyObject_TypeCheck;
#[cfg(not(RustPython))]
use crate::Py_IS_TYPE;
use core::ffi::{c_char, c_int, c_void};
use core::{mem, ptr};
#[cfg(all(Py_3_9, not(Py_LIMITED_API), not(GraalPy)))]
pub struct PyCFunctionObject {
pub ob_base: PyObject,
pub m_ml: *mut PyMethodDef,
pub m_self: *mut PyObject,
pub m_module: *mut PyObject,
pub m_weakreflist: *mut PyObject,
#[cfg(not(PyPy))]
pub vectorcall: Option<crate::vectorcallfunc>,
}
extern_libpython! {
#[cfg(not(RustPython))]
#[cfg_attr(PyPy, link_name = "PyPyCFunction_Type")]
pub static mut PyCFunction_Type: PyTypeObject;
#[cfg(RustPython)]
pub fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyCFunction_Check(op: *mut PyObject) -> c_int;
}
#[cfg(all(Py_3_9, not(RustPython)))]
#[inline]
pub unsafe fn PyCFunction_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyCFunction_Type)
}
#[cfg(all(Py_3_9, not(RustPython)))]
#[inline]
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyCFunction_Type)
}
#[cfg(not(any(Py_3_9, RustPython)))]
#[inline]
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyCFunction_Type)
}
pub type PyCFunction =
unsafe extern "C" fn(slf: *mut PyObject, args: *mut PyObject) -> *mut PyObject;
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
pub type PyCFunctionFast = unsafe extern "C" fn(
slf: *mut PyObject,
args: *mut *mut PyObject,
nargs: crate::pyport::Py_ssize_t,
) -> *mut PyObject;
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
#[deprecated(note = "renamed to `PyCFunctionFast`")]
pub type _PyCFunctionFast = PyCFunctionFast;
pub type PyCFunctionWithKeywords = unsafe extern "C" fn(
slf: *mut PyObject,
args: *mut PyObject,
kwds: *mut PyObject,
) -> *mut PyObject;
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
pub type PyCFunctionFastWithKeywords = unsafe extern "C" fn(
slf: *mut PyObject,
args: *const *mut PyObject,
nargs: crate::pyport::Py_ssize_t,
kwnames: *mut PyObject,
) -> *mut PyObject;
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
#[deprecated(note = "renamed to `PyCFunctionFastWithKeywords`")]
pub type _PyCFunctionFastWithKeywords = PyCFunctionFastWithKeywords;
#[cfg(all(Py_3_9, not(Py_LIMITED_API)))]
pub type PyCMethod = unsafe extern "C" fn(
slf: *mut PyObject,
defining_class: *mut PyTypeObject,
args: *const *mut PyObject,
nargs: crate::pyport::Py_ssize_t,
kwnames: *mut PyObject,
) -> *mut PyObject;
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyCFunction_GetFunction")]
pub fn PyCFunction_GetFunction(f: *mut PyObject) -> Option<PyCFunction>;
pub fn PyCFunction_GetSelf(f: *mut PyObject) -> *mut PyObject;
pub fn PyCFunction_GetFlags(f: *mut PyObject) -> c_int;
#[cfg(not(Py_3_13))]
#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))]
pub fn PyCFunction_Call(
f: *mut PyObject,
args: *mut PyObject,
kwds: *mut PyObject,
) -> *mut PyObject;
}
/// Represents the [PyMethodDef](https://docs.python.org/3/c-api/structures.html#c.PyMethodDef)
/// structure.
///
/// Note that CPython may leave fields uninitialized. You must ensure that
/// `ml_name` != NULL before dereferencing or reading other fields.
#[repr(C)]
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct PyMethodDef {
pub ml_name: *const c_char,
pub ml_meth: PyMethodDefPointer,
pub ml_flags: c_int,
pub ml_doc: *const c_char,
}
impl PyMethodDef {
pub const fn zeroed() -> PyMethodDef {
PyMethodDef {
ml_name: ptr::null(),
ml_meth: PyMethodDefPointer {
Void: ptr::null_mut(),
},
ml_flags: 0,
ml_doc: ptr::null(),
}
}
}
impl Default for PyMethodDef {
fn default() -> PyMethodDef {
PyMethodDef {
ml_name: ptr::null(),
ml_meth: PyMethodDefPointer {
Void: ptr::null_mut(),
},
ml_flags: 0,
ml_doc: ptr::null(),
}
}
}
/// Function types used to implement Python callables.
///
/// This function pointer must be accompanied by the correct [ml_flags](PyMethodDef::ml_flags),
/// otherwise the behavior is undefined.
///
/// See the [Python C API documentation][1] for more information.
///
/// [1]: https://docs.python.org/3/c-api/structures.html#implementing-functions-and-methods
#[repr(C)]
#[derive(Copy, Clone, Eq)]
pub union PyMethodDefPointer {
/// This variant corresponds with [`METH_VARARGS`] *or* [`METH_NOARGS`] *or* [`METH_O`].
pub PyCFunction: PyCFunction,
/// This variant corresponds with [`METH_VARARGS`] | [`METH_KEYWORDS`].
pub PyCFunctionWithKeywords: PyCFunctionWithKeywords,
/// This variant corresponds with [`METH_FASTCALL`].
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
#[deprecated(note = "renamed to `PyCFunctionFast`")]
pub _PyCFunctionFast: PyCFunctionFast,
/// This variant corresponds with [`METH_FASTCALL`].
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
pub PyCFunctionFast: PyCFunctionFast,
/// This variant corresponds with [`METH_FASTCALL`] | [`METH_KEYWORDS`].
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
#[deprecated(note = "renamed to `PyCFunctionFastWithKeywords`")]
pub _PyCFunctionFastWithKeywords: PyCFunctionFastWithKeywords,
/// This variant corresponds with [`METH_FASTCALL`] | [`METH_KEYWORDS`].
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
pub PyCFunctionFastWithKeywords: PyCFunctionFastWithKeywords,
/// This variant corresponds with [`METH_METHOD`] | [`METH_FASTCALL`] | [`METH_KEYWORDS`].
#[cfg(all(Py_3_9, not(Py_LIMITED_API)))]
pub PyCMethod: PyCMethod,
Void: *mut c_void,
}
impl PyMethodDefPointer {
pub fn as_ptr(&self) -> *mut c_void {
// SAFETY: self is pointer sized
unsafe { self.Void }
}
pub fn is_null(&self) -> bool {
self.as_ptr().is_null()
}
pub const fn zeroed() -> PyMethodDefPointer {
PyMethodDefPointer {
Void: ptr::null_mut(),
}
}
}
impl PartialEq for PyMethodDefPointer {
fn eq(&self, other: &Self) -> bool {
self.as_ptr() == other.as_ptr()
}
}
impl core::fmt::Pointer for PyMethodDefPointer {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let ptr = self.as_ptr();
core::fmt::Pointer::fmt(&ptr, f)
}
}
const _: () =
assert!(mem::size_of::<PyMethodDefPointer>() == mem::size_of::<Option<extern "C" fn()>>());
#[cfg(not(Py_3_9))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyCFunction_New")]
pub fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyCFunction_NewEx")]
pub fn PyCFunction_NewEx(
ml: *mut PyMethodDef,
slf: *mut PyObject,
module: *mut PyObject,
) -> *mut PyObject;
}
#[cfg(Py_3_9)]
#[inline]
pub unsafe fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject {
PyCFunction_NewEx(ml, slf, core::ptr::null_mut())
}
#[cfg(Py_3_9)]
#[inline]
pub unsafe fn PyCFunction_NewEx(
ml: *mut PyMethodDef,
slf: *mut PyObject,
module: *mut PyObject,
) -> *mut PyObject {
PyCMethod_New(ml, slf, module, core::ptr::null_mut())
}
#[cfg(Py_3_9)]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyCMethod_New")]
pub fn PyCMethod_New(
ml: *mut PyMethodDef,
slf: *mut PyObject,
module: *mut PyObject,
cls: *mut PyTypeObject,
) -> *mut PyObject;
}
/* Flag passed to newmethodobject */
pub const METH_VARARGS: c_int = 0x0001;
pub const METH_KEYWORDS: c_int = 0x0002;
/* METH_NOARGS and METH_O must not be combined with the flags above. */
pub const METH_NOARGS: c_int = 0x0004;
pub const METH_O: c_int = 0x0008;
/* METH_CLASS and METH_STATIC are a little different; these control
the construction of methods for a class. These cannot be used for
functions in modules. */
pub const METH_CLASS: c_int = 0x0010;
pub const METH_STATIC: c_int = 0x0020;
/* METH_COEXIST allows a method to be entered eventhough a slot has
already filled the entry. When defined, the flag allows a separate
method, "__contains__" for example, to coexist with a defined
slot like sq_contains. */
pub const METH_COEXIST: c_int = 0x0040;
/* METH_FASTCALL indicates the PEP 590 Vectorcall calling format. It may
be specified alone or with METH_KEYWORDS. */
#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
pub const METH_FASTCALL: c_int = 0x0080;
// skipped METH_STACKLESS
#[cfg(all(Py_3_9, not(Py_LIMITED_API)))]
pub const METH_METHOD: c_int = 0x0200;
extern_libpython! {
#[cfg(not(Py_3_9))]
pub fn PyCFunction_ClearFreeList() -> c_int;
}
+191
View File
@@ -0,0 +1,191 @@
use crate::methodobject::PyMethodDef;
use crate::moduleobject::PyModuleDef;
use crate::object::PyObject;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_int, c_long};
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyArg_Parse")]
pub fn PyArg_Parse(arg1: *mut PyObject, arg2: *const c_char, ...) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyArg_ParseTuple")]
pub fn PyArg_ParseTuple(arg1: *mut PyObject, arg2: *const c_char, ...) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyArg_ParseTupleAndKeywords")]
pub fn PyArg_ParseTupleAndKeywords(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *const c_char,
#[cfg(not(Py_3_13))] arg4: *mut *mut c_char,
#[cfg(Py_3_13)] arg4: *const *const c_char,
...
) -> c_int;
// skipped PyArg_VaParse
// skipped PyArg_VaParseTupleAndKeywords
pub fn PyArg_ValidateKeywordArguments(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyArg_UnpackTuple")]
pub fn PyArg_UnpackTuple(
arg1: *mut PyObject,
arg2: *const c_char,
arg3: Py_ssize_t,
arg4: Py_ssize_t,
...
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPy_BuildValue")]
pub fn Py_BuildValue(arg1: *const c_char, ...) -> *mut PyObject;
// skipped Py_VaBuildValue
#[cfg(Py_3_13)]
pub fn PyModule_Add(module: *mut PyObject, name: *const c_char, value: *mut PyObject) -> c_int;
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyModule_AddObjectRef")]
pub fn PyModule_AddObjectRef(
module: *mut PyObject,
name: *const c_char,
value: *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyModule_AddObject")]
pub fn PyModule_AddObject(
module: *mut PyObject,
name: *const c_char,
value: *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyModule_AddIntConstant")]
pub fn PyModule_AddIntConstant(
module: *mut PyObject,
name: *const c_char,
value: c_long,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyModule_AddStringConstant")]
pub fn PyModule_AddStringConstant(
module: *mut PyObject,
name: *const c_char,
value: *const c_char,
) -> c_int;
#[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "PyPyModule_AddType")]
pub fn PyModule_AddType(
module: *mut PyObject,
type_: *mut crate::object::PyTypeObject,
) -> c_int;
// skipped PyModule_AddIntMacro
// skipped PyModule_AddStringMacro
pub fn PyModule_SetDocString(arg1: *mut PyObject, arg2: *const c_char) -> c_int;
pub fn PyModule_AddFunctions(arg1: *mut PyObject, arg2: *mut PyMethodDef) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyModule_ExecDef")]
pub fn PyModule_ExecDef(module: *mut PyObject, def: *mut PyModuleDef) -> c_int;
}
pub const Py_CLEANUP_SUPPORTED: i32 = 0x2_0000;
pub const PYTHON_API_VERSION: i32 = 1013;
pub const PYTHON_ABI_VERSION: i32 = 3;
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyModule_Create2")]
pub fn PyModule_Create2(module: *mut PyModuleDef, apiver: c_int) -> *mut PyObject;
}
#[inline]
pub unsafe fn PyModule_Create(module: *mut PyModuleDef) -> *mut PyObject {
PyModule_Create2(
module,
if cfg!(Py_LIMITED_API) {
PYTHON_ABI_VERSION
} else {
PYTHON_API_VERSION
},
)
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyModule_FromDefAndSpec2")]
pub fn PyModule_FromDefAndSpec2(
def: *mut PyModuleDef,
spec: *mut PyObject,
module_api_version: c_int,
) -> *mut PyObject;
}
#[inline]
pub unsafe fn PyModule_FromDefAndSpec(def: *mut PyModuleDef, spec: *mut PyObject) -> *mut PyObject {
PyModule_FromDefAndSpec2(
def,
spec,
if cfg!(Py_LIMITED_API) {
PYTHON_ABI_VERSION
} else {
PYTHON_API_VERSION
},
)
}
#[cfg(Py_3_15)]
#[repr(C)]
pub struct PyABIInfo {
pub abiinfo_major_version: u8,
pub abiinfo_minor_version: u8,
pub flags: u16,
pub build_version: u32,
pub abi_version: u32,
}
#[cfg(Py_3_15)]
pub const PyABIInfo_STABLE: u16 = 0x0001;
#[cfg(Py_3_15)]
pub const PyABIInfo_GIL: u16 = 0x0002;
#[cfg(Py_3_15)]
pub const PyABIInfo_FREETHREADED: u16 = 0x0004;
#[cfg(Py_3_15)]
pub const PyABIInfo_INTERNAL: u16 = 0x0008;
#[cfg(Py_3_15)]
pub const PyABIInfo_FREETHREADING_AGNOSTIC: u16 = PyABIInfo_GIL | PyABIInfo_FREETHREADED;
#[cfg(Py_3_15)]
extern_libpython! {
pub fn PyABIInfo_Check(info: *mut PyABIInfo, module_name: *const c_char) -> c_int;
}
#[cfg(all(Py_LIMITED_API, Py_3_15))]
const _PyABIInfo_DEFAULT_FLAG_STABLE: u16 = PyABIInfo_STABLE;
#[cfg(all(Py_3_15, not(Py_LIMITED_API)))]
const _PyABIInfo_DEFAULT_FLAG_STABLE: u16 = 0;
// skipped PyABIInfo_DEFAULT_ABI_VERSION: depends on Py_VERSION_HEX
#[cfg(all(Py_3_15, all(Py_LIMITED_API, Py_GIL_DISABLED)))]
const _PyABIInfo_DEFAULT_FLAG_FT: u16 = PyABIInfo_FREETHREADING_AGNOSTIC;
#[cfg(all(Py_3_15, Py_GIL_DISABLED, not(Py_LIMITED_API)))]
const _PyABIInfo_DEFAULT_FLAG_FT: u16 = PyABIInfo_FREETHREADED;
#[cfg(all(Py_3_15, not(Py_GIL_DISABLED)))]
const _PyABIInfo_DEFAULT_FLAG_FT: u16 = PyABIInfo_GIL;
#[cfg(Py_3_15)]
// has an alternate definition if Py_BUILD_CORE is set, ignore that
const _PyABIInfo_DEFAULT_FLAG_INTERNAL: u16 = 0;
#[cfg(Py_3_15)]
pub const PyABIInfo_DEFAULT_FLAGS: u16 =
_PyABIInfo_DEFAULT_FLAG_STABLE | _PyABIInfo_DEFAULT_FLAG_FT | _PyABIInfo_DEFAULT_FLAG_INTERNAL;
#[cfg(Py_3_15)]
// must be pub because it is used by PyABIInfo_VAR
pub const _PyABIInfo_DEFAULT: PyABIInfo = PyABIInfo {
abiinfo_major_version: 1,
abiinfo_minor_version: 0,
flags: PyABIInfo_DEFAULT_FLAGS,
build_version: 0,
abi_version: 0,
};
#[cfg(Py_3_15)]
#[macro_export]
macro_rules! PyABIInfo_VAR {
($name:ident) => {
static mut $name: pyo3_ffi::PyABIInfo = pyo3_ffi::_PyABIInfo_DEFAULT;
};
}
+149
View File
@@ -0,0 +1,149 @@
#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
use crate::methodobject::PyMethodDef;
use crate::object::*;
use crate::pyport::Py_ssize_t;
// this is pub to avoid unnecessary churn elsewhere
#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))]
pub use crate::pytypedefs::PyModuleDef;
#[cfg(Py_3_15)]
use crate::slots::PySlot;
use core::ffi::{c_char, c_int, c_void};
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyModule_Type")]
pub static mut PyModule_Type: PyTypeObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyModule_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &raw mut PyModule_Type)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyModule_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyModule_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyModule_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyModule_CheckExact(op: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyModule_NewObject")]
pub fn PyModule_NewObject(name: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyModule_New")]
pub fn PyModule_New(name: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyModule_GetDict")]
pub fn PyModule_GetDict(arg1: *mut PyObject) -> *mut PyObject;
#[cfg(not(PyPy))]
pub fn PyModule_GetNameObject(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyModule_GetName")]
pub fn PyModule_GetName(arg1: *mut PyObject) -> *const c_char;
#[cfg(not(all(windows, PyPy)))]
#[deprecated(note = "Python 3.2")]
pub fn PyModule_GetFilename(arg1: *mut PyObject) -> *const c_char;
#[cfg(not(PyPy))]
pub fn PyModule_GetFilenameObject(arg1: *mut PyObject) -> *mut PyObject;
// skipped non-limited _PyModule_Clear
// skipped non-limited _PyModule_ClearDict
// skipped non-limited _PyModuleSpec_IsInitializing
#[cfg_attr(PyPy, link_name = "PyPyModule_GetDef")]
pub fn PyModule_GetDef(arg1: *mut PyObject) -> *mut PyModuleDef;
#[cfg_attr(PyPy, link_name = "PyPyModule_GetState")]
pub fn PyModule_GetState(arg1: *mut PyObject) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyModuleDef_Init")]
pub fn PyModuleDef_Init(arg1: *mut PyModuleDef) -> *mut PyObject;
#[cfg(not(RustPython))]
pub static mut PyModuleDef_Type: PyTypeObject;
}
#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
#[repr(C)]
pub struct PyModuleDef_Base {
pub ob_base: PyObject,
// Rust function pointers are non-null so an Option is needed here.
pub m_init: Option<extern "C" fn() -> *mut PyObject>,
pub m_index: Py_ssize_t,
pub m_copy: *mut PyObject,
}
#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
#[allow(
clippy::declare_interior_mutable_const,
reason = "contains atomic refcount on free-threaded builds"
)]
pub const PyModuleDef_HEAD_INIT: PyModuleDef_Base = PyModuleDef_Base {
ob_base: PyObject_HEAD_INIT,
m_init: None,
m_index: 0,
m_copy: core::ptr::null_mut(),
};
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct PyModuleDef_Slot {
pub slot: c_int,
pub value: *mut c_void,
}
impl Default for PyModuleDef_Slot {
fn default() -> PyModuleDef_Slot {
PyModuleDef_Slot {
slot: 0,
value: core::ptr::null_mut(),
}
}
}
#[cfg(Py_3_12)]
#[allow(
clippy::zero_ptr,
reason = "matches the way that the rest of these constants are defined"
)]
pub const Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED: *mut c_void = 0 as *mut c_void;
#[cfg(Py_3_12)]
pub const Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED: *mut c_void = 1 as *mut c_void;
#[cfg(Py_3_12)]
pub const Py_MOD_PER_INTERPRETER_GIL_SUPPORTED: *mut c_void = 2 as *mut c_void;
#[cfg(Py_3_13)]
#[allow(
clippy::zero_ptr,
reason = "matches the way that the rest of these constants are defined"
)]
pub const Py_MOD_GIL_USED: *mut c_void = 0 as *mut c_void;
#[cfg(Py_3_13)]
pub const Py_MOD_GIL_NOT_USED: *mut c_void = 1 as *mut c_void;
extern_libpython! {
#[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))]
pub fn PyUnstable_Module_SetGIL(module: *mut PyObject, gil: *mut c_void) -> c_int;
}
#[cfg(Py_3_15)]
extern_libpython! {
pub fn PyModule_FromSlotsAndSpec(slots: *const PySlot, spec: *mut PyObject) -> *mut PyObject;
pub fn PyModule_Exec(_mod: *mut PyObject) -> c_int;
pub fn PyModule_GetStateSize(_mod: *mut PyObject, result: *mut Py_ssize_t) -> c_int;
pub fn PyModule_GetToken(module: *mut PyObject, result: *mut *mut c_void) -> c_int;
}
#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
#[repr(C)]
pub struct PyModuleDef {
pub m_base: PyModuleDef_Base,
pub m_name: *const c_char,
pub m_doc: *const c_char,
pub m_size: Py_ssize_t,
pub m_methods: *mut PyMethodDef,
pub m_slots: *mut PyModuleDef_Slot,
// Rust function pointers are non-null so an Option is needed here.
pub m_traverse: Option<traverseproc>,
pub m_clear: Option<inquiry>,
pub m_free: Option<freefunc>,
}
+774
View File
@@ -0,0 +1,774 @@
use crate::pyport::{Py_hash_t, Py_ssize_t};
// these re-exports are pub because it would be awkward to
// thread the different origins for these types on this build
// everywhere else
#[cfg(Py_LIMITED_API)]
pub use crate::pytypedefs::PyTypeObject;
#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))]
pub use crate::pytypedefs::{PyObject, PyVarObject};
#[cfg(Py_3_15)]
use crate::PySlot;
#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))]
use crate::{refcount, PyMutex};
use core::ffi::{c_char, c_int, c_uint, c_ulong, c_void};
use core::mem;
#[cfg(all(Py_GIL_DISABLED, not(Py_LIMITED_API)))]
use core::sync::atomic::{AtomicIsize, AtomicU32};
#[cfg(not(Py_LIMITED_API))]
pub use crate::cpython::object::PyTypeObject;
// skip PyObject_HEAD
#[repr(C)]
#[derive(Copy, Clone)]
#[cfg(all(
target_pointer_width = "64",
Py_3_14,
not(Py_GIL_DISABLED),
target_endian = "big"
))]
/// This struct is anonymous in CPython, so the name was given by PyO3 because
/// Rust structs need a name.
pub struct PyObjectObFlagsAndRefcnt {
pub ob_flags: u16,
pub ob_overflow: u16,
pub ob_refcnt: u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[cfg(all(
target_pointer_width = "64",
Py_3_14,
not(Py_GIL_DISABLED),
target_endian = "little"
))]
/// This struct is anonymous in CPython, so the name was given by PyO3 because
/// Rust structs need a name.
pub struct PyObjectObFlagsAndRefcnt {
pub ob_refcnt: u32,
pub ob_overflow: u16,
pub ob_flags: u16,
}
// 4-byte alignment comes from value of _PyObject_MIN_ALIGNMENT
#[cfg(all(not(Py_GIL_DISABLED), Py_3_15))]
#[repr(C, align(4))]
#[derive(Copy, Clone)]
struct Aligner(c_char);
#[repr(C)]
#[derive(Copy, Clone)]
#[cfg(all(Py_3_12, not(Py_GIL_DISABLED)))]
/// This union is anonymous in CPython, so the name was given by PyO3 because
/// Rust union need a name.
pub union PyObjectObRefcnt {
#[cfg(all(target_pointer_width = "64", Py_3_14))]
pub ob_refcnt_full: crate::PY_INT64_T,
#[cfg(all(target_pointer_width = "64", Py_3_14))]
pub refcnt_and_flags: PyObjectObFlagsAndRefcnt,
pub ob_refcnt: Py_ssize_t,
#[cfg(all(target_pointer_width = "64", not(Py_3_14)))]
pub ob_refcnt_split: [crate::PY_UINT32_T; 2],
#[cfg(all(not(Py_GIL_DISABLED), Py_3_15))]
_aligner: Aligner,
}
#[cfg(all(Py_3_12, not(Py_GIL_DISABLED)))]
impl core::fmt::Debug for PyObjectObRefcnt {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
// SAFETY: always valid to print `ob_refcnt` as a number
write!(f, "{}", unsafe { self.ob_refcnt })
}
}
#[cfg(all(not(Py_3_12), not(Py_GIL_DISABLED)))]
pub type PyObjectObRefcnt = Py_ssize_t;
const _PyObject_MIN_ALIGNMENT: usize = 4;
// PyObject_HEAD_INIT comes before the PyObject definition in object.h
// but we put it after PyObject because HEAD_INIT uses PyObject
// repr(align(4)) corresponds to the use of _Py_ALIGNED_DEF in object.h. It is
// not currently possible to use constant variables with repr(align()), see
// https://github.com/rust-lang/rust/issues/52840
#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
#[cfg_attr(not(all(Py_3_15, Py_GIL_DISABLED)), repr(C))]
#[cfg_attr(all(Py_3_15, Py_GIL_DISABLED), repr(C, align(4)))]
#[derive(Debug)]
pub struct PyObject {
#[cfg(Py_GIL_DISABLED)]
pub ob_tid: libc::uintptr_t,
#[cfg(all(Py_GIL_DISABLED, not(Py_3_14)))]
pub _padding: u16,
#[cfg(all(Py_GIL_DISABLED, Py_3_14))]
pub ob_flags: u16,
#[cfg(Py_GIL_DISABLED)]
pub ob_mutex: PyMutex, // per-object lock
#[cfg(Py_GIL_DISABLED)]
pub ob_gc_bits: u8, // gc-related state
#[cfg(Py_GIL_DISABLED)]
pub ob_ref_local: AtomicU32, // local reference count
#[cfg(Py_GIL_DISABLED)]
pub ob_ref_shared: AtomicIsize, // shared reference count
#[cfg(not(Py_GIL_DISABLED))]
pub ob_refcnt: PyObjectObRefcnt,
#[cfg(PyPy)]
pub ob_pypy_link: Py_ssize_t,
pub ob_type: *mut PyTypeObject,
}
#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
const _: () = assert!(core::mem::align_of::<PyObject>() >= _PyObject_MIN_ALIGNMENT);
#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
#[allow(
clippy::declare_interior_mutable_const,
reason = "contains atomic refcount on free-threaded builds"
)]
pub const PyObject_HEAD_INIT: PyObject = PyObject {
#[cfg(Py_GIL_DISABLED)]
ob_tid: 0,
#[cfg(all(Py_GIL_DISABLED, Py_3_15))]
ob_flags: refcount::_Py_STATICALLY_ALLOCATED_FLAG as u16,
#[cfg(all(Py_GIL_DISABLED, all(Py_3_14, not(Py_3_15))))]
ob_flags: 0,
#[cfg(all(Py_GIL_DISABLED, not(Py_3_14)))]
_padding: 0,
#[cfg(Py_GIL_DISABLED)]
ob_mutex: PyMutex::new(),
#[cfg(Py_GIL_DISABLED)]
ob_gc_bits: 0,
#[cfg(Py_GIL_DISABLED)]
ob_ref_local: AtomicU32::new(refcount::_Py_IMMORTAL_REFCNT_LOCAL),
#[cfg(Py_GIL_DISABLED)]
ob_ref_shared: AtomicIsize::new(0),
#[cfg(all(not(Py_GIL_DISABLED), Py_3_12))]
ob_refcnt: PyObjectObRefcnt { ob_refcnt: 1 },
#[cfg(not(Py_3_12))]
ob_refcnt: 1,
#[cfg(PyPy)]
ob_pypy_link: 0,
ob_type: core::ptr::null_mut(),
};
// skipped _Py_UNOWNED_TID
// skipped _PyObject_CAST
#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
#[repr(C)]
#[derive(Debug)]
pub struct PyVarObject {
pub ob_base: PyObject,
#[cfg(not(GraalPy))]
pub ob_size: Py_ssize_t,
// On GraalPy the field is physically there, but not always populated. We hide it to prevent accidental misuse
#[cfg(GraalPy)]
pub _ob_size_graalpy: Py_ssize_t,
}
#[inline]
pub(crate) unsafe fn _PyVarObject_CAST(op: *mut PyObject) -> *mut PyVarObject {
op.cast()
}
#[inline]
#[cfg(not(any(GraalPy, PyPy, RustPython)))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub unsafe fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int {
(x == y).into()
}
#[cfg(any(GraalPy, PyPy, RustPython))]
#[cfg_attr(docsrs, doc(cfg(all())))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPy_Is")]
pub fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int;
}
// skipped _Py_GetThreadLocal_Addr
// skipped _Py_ThreadID
// skipped _Py_IsOwnedByCurrentThread
#[cfg(GraalPy)]
extern_libpython! {
#[cfg(GraalPy)]
fn _Py_TYPE(arg1: *const PyObject) -> *mut PyTypeObject;
#[cfg(GraalPy)]
fn _Py_SIZE(arg1: *const PyObject) -> Py_ssize_t;
}
#[inline]
#[cfg(not(all(Py_LIMITED_API, Py_3_14)))]
pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject {
#[cfg(not(GraalPy))]
return (*ob).ob_type;
#[cfg(GraalPy)]
return _Py_TYPE(ob);
}
#[cfg(all(Py_LIMITED_API, Py_3_14))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPy_TYPE")]
pub fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject;
}
// skip _Py_TYPE compat shim
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyLong_Type")]
pub static mut PyLong_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyBool_Type")]
pub static mut PyBool_Type: PyTypeObject;
}
#[cfg(not(all(Py_LIMITED_API, Py_3_15)))]
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn Py_SIZE(ob: *mut PyObject) -> Py_ssize_t {
#[cfg(not(GraalPy))]
{
debug_assert_ne!((*ob).ob_type, &raw mut crate::PyLong_Type);
debug_assert_ne!((*ob).ob_type, &raw mut crate::PyBool_Type);
(*ob.cast::<PyVarObject>()).ob_size
}
#[cfg(GraalPy)]
_Py_SIZE(ob)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn Py_SIZE(ob: *mut PyObject) -> Py_ssize_t;
#[cfg(any(all(Py_LIMITED_API, Py_3_15), RustPython))]
pub fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int;
}
#[inline]
#[cfg(not(any(all(Py_LIMITED_API, Py_3_15), RustPython)))]
pub unsafe fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int {
(Py_TYPE(ob) == tp) as c_int
}
// skipped Py_SET_TYPE
// skipped Py_SET_SIZE
pub type unaryfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
pub type binaryfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> *mut PyObject;
pub type ternaryfunc =
unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
pub type inquiry = unsafe extern "C" fn(*mut PyObject) -> c_int;
pub type lenfunc = unsafe extern "C" fn(*mut PyObject) -> Py_ssize_t;
pub type ssizeargfunc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t) -> *mut PyObject;
pub type ssizessizeargfunc =
unsafe extern "C" fn(*mut PyObject, Py_ssize_t, Py_ssize_t) -> *mut PyObject;
pub type ssizeobjargproc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t, *mut PyObject) -> c_int;
pub type ssizessizeobjargproc =
unsafe extern "C" fn(*mut PyObject, Py_ssize_t, Py_ssize_t, arg4: *mut PyObject) -> c_int;
pub type objobjargproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
pub type objobjproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> c_int;
pub type visitproc = unsafe extern "C" fn(object: *mut PyObject, arg: *mut c_void) -> c_int;
pub type traverseproc =
unsafe extern "C" fn(slf: *mut PyObject, visit: visitproc, arg: *mut c_void) -> c_int;
pub type freefunc = unsafe extern "C" fn(*mut c_void);
pub type destructor = unsafe extern "C" fn(*mut PyObject);
pub type getattrfunc = unsafe extern "C" fn(*mut PyObject, *mut c_char) -> *mut PyObject;
pub type getattrofunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> *mut PyObject;
pub type setattrfunc = unsafe extern "C" fn(*mut PyObject, *mut c_char, *mut PyObject) -> c_int;
pub type setattrofunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
pub type reprfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
pub type hashfunc = unsafe extern "C" fn(*mut PyObject) -> Py_hash_t;
pub type richcmpfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, c_int) -> *mut PyObject;
pub type getiterfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
pub type iternextfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
#[cfg(Py_3_15)]
#[repr(C)]
pub struct _PyObjectIndexPair {
pub object: *mut PyObject,
pub index: Py_ssize_t,
}
#[cfg(Py_3_15)]
pub type _Py_iteritemfunc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t) -> _PyObjectIndexPair;
pub type descrgetfunc =
unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
pub type descrsetfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
pub type initproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
pub type newfunc =
unsafe extern "C" fn(*mut PyTypeObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
pub type allocfunc = unsafe extern "C" fn(*mut PyTypeObject, Py_ssize_t) -> *mut PyObject;
pub type vectorcallfunc = unsafe extern "C" fn(
callable: *mut PyObject,
args: *const *mut PyObject,
nargsf: libc::size_t,
kwnames: *mut PyObject,
) -> *mut PyObject;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyType_Slot {
pub slot: c_int,
pub pfunc: *mut c_void,
}
impl Default for PyType_Slot {
fn default() -> PyType_Slot {
// SAFETY: CPython treats a zeroed slot as a sentinel value to mean the end of the slots array.
unsafe { mem::zeroed() }
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyType_Spec {
pub name: *const c_char,
pub basicsize: c_int,
pub itemsize: c_int,
pub flags: c_uint,
pub slots: *mut PyType_Slot,
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyType_FromSpec")]
pub fn PyType_FromSpec(arg1: *mut PyType_Spec) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyType_FromSpecWithBases")]
pub fn PyType_FromSpecWithBases(arg1: *mut PyType_Spec, arg2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyType_GetSlot")]
pub fn PyType_GetSlot(arg1: *mut PyTypeObject, arg2: c_int) -> *mut c_void;
#[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "PyPyType_FromModuleAndSpec")]
pub fn PyType_FromModuleAndSpec(
module: *mut PyObject,
spec: *mut PyType_Spec,
bases: *mut PyObject,
) -> *mut PyObject;
#[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "PyPyType_GetModule")]
pub fn PyType_GetModule(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "PyPyType_GetModuleState")]
pub fn PyType_GetModuleState(arg1: *mut PyTypeObject) -> *mut c_void;
#[cfg(Py_3_11)]
#[cfg_attr(PyPy, link_name = "PyPyType_GetName")]
pub fn PyType_GetName(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg(Py_3_11)]
#[cfg_attr(PyPy, link_name = "PyPyType_GetQualName")]
pub fn PyType_GetQualName(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyType_GetFullyQualifiedName")]
pub fn PyType_GetFullyQualifiedName(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyType_GetModuleName")]
pub fn PyType_GetModuleName(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg(Py_3_12)]
#[cfg_attr(PyPy, link_name = "PyPyType_FromMetaclass")]
pub fn PyType_FromMetaclass(
metaclass: *mut PyTypeObject,
module: *mut PyObject,
spec: *mut PyType_Spec,
bases: *mut PyObject,
) -> *mut PyObject;
#[cfg(Py_3_12)]
#[cfg_attr(PyPy, link_name = "PyPyObject_GetTypeData")]
pub fn PyObject_GetTypeData(obj: *mut PyObject, cls: *mut PyTypeObject) -> *mut c_void;
#[cfg(Py_3_12)]
#[cfg_attr(PyPy, link_name = "PyPyType_GetTypeDataSize")]
pub fn PyType_GetTypeDataSize(cls: *mut PyTypeObject) -> Py_ssize_t;
#[cfg(Py_3_14)]
#[cfg_attr(PyPy, link_name = "PyPyType_GetBaseByToken")]
pub fn PyType_GetBaseByToken(
type_: *mut PyTypeObject,
token: *mut c_void,
result: *mut *mut PyTypeObject,
) -> c_int;
#[cfg(Py_3_15)]
#[cfg_attr(PyPy, link_name = "PyPyType_FromSlot")]
pub fn PyType_FromSlots(slots: *mut PySlot) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyType_IsSubtype")]
pub fn PyType_IsSubtype(a: *mut PyTypeObject, b: *mut PyTypeObject) -> c_int;
}
#[inline]
pub unsafe fn PyObject_TypeCheck(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int {
(Py_IS_TYPE(ob, tp) != 0 || PyType_IsSubtype(Py_TYPE(ob), tp) != 0) as c_int
}
extern_libpython! {
/// built-in 'type'
#[cfg(not(RustPython))]
#[cfg_attr(PyPy, link_name = "PyPyType_Type")]
pub static mut PyType_Type: PyTypeObject;
/// built-in 'object'
#[cfg(not(RustPython))]
#[cfg_attr(PyPy, link_name = "PyPyBaseObject_Type")]
pub static mut PyBaseObject_Type: PyTypeObject;
/// built-in 'super'
#[cfg(not(RustPython))]
pub static mut PySuper_Type: PyTypeObject;
pub fn PyType_GetFlags(arg1: *mut PyTypeObject) -> c_ulong;
#[cfg_attr(PyPy, link_name = "PyPyType_Ready")]
pub fn PyType_Ready(t: *mut PyTypeObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyType_GenericAlloc")]
pub fn PyType_GenericAlloc(t: *mut PyTypeObject, nitems: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyType_GenericNew")]
pub fn PyType_GenericNew(
t: *mut PyTypeObject,
args: *mut PyObject,
kwds: *mut PyObject,
) -> *mut PyObject;
pub fn PyType_ClearCache() -> c_uint;
#[cfg_attr(PyPy, link_name = "PyPyType_Modified")]
pub fn PyType_Modified(t: *mut PyTypeObject);
#[cfg_attr(PyPy, link_name = "PyPyObject_Repr")]
pub fn PyObject_Repr(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_Str")]
pub fn PyObject_Str(o: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_ASCII")]
pub fn PyObject_ASCII(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_Bytes")]
pub fn PyObject_Bytes(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_RichCompare")]
pub fn PyObject_RichCompare(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: c_int,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_RichCompareBool")]
pub fn PyObject_RichCompareBool(arg1: *mut PyObject, arg2: *mut PyObject, arg3: c_int)
-> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_GetAttrString")]
pub fn PyObject_GetAttrString(arg1: *mut PyObject, arg2: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_SetAttrString")]
pub fn PyObject_SetAttrString(
arg1: *mut PyObject,
arg2: *const c_char,
arg3: *mut PyObject,
) -> c_int;
#[cfg(any(Py_3_13, all(PyPy, not(Py_3_11))))] // CPython defined in 3.12 as an inline function in abstract.h
#[cfg_attr(PyPy, link_name = "PyPyObject_DelAttrString")]
pub fn PyObject_DelAttrString(arg1: *mut PyObject, arg2: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_HasAttrString")]
pub fn PyObject_HasAttrString(arg1: *mut PyObject, arg2: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_GetAttr")]
pub fn PyObject_GetAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyObject_GetOptionalAttr")]
pub fn PyObject_GetOptionalAttr(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *mut *mut PyObject,
) -> c_int;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyObject_GetOptionalAttrString")]
pub fn PyObject_GetOptionalAttrString(
arg1: *mut PyObject,
arg2: *const c_char,
arg3: *mut *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_SetAttr")]
pub fn PyObject_SetAttr(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject)
-> c_int;
#[cfg(any(Py_3_13, all(PyPy, not(Py_3_11))))] // CPython defined in 3.12 as an inline function in abstract.h
#[cfg_attr(PyPy, link_name = "PyPyObject_DelAttr")]
pub fn PyObject_DelAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_HasAttr")]
pub fn PyObject_HasAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyObject_HasAttrWithError")]
pub fn PyObject_HasAttrWithError(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPyObject_HasAttrStringWithError")]
pub fn PyObject_HasAttrStringWithError(arg1: *mut PyObject, arg2: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_SelfIter")]
pub fn PyObject_SelfIter(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_GenericGetAttr")]
pub fn PyObject_GenericGetAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_GenericSetAttr")]
pub fn PyObject_GenericSetAttr(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *mut PyObject,
) -> c_int;
#[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))]
#[cfg_attr(PyPy, link_name = "PyPyObject_GenericGetDict")]
pub fn PyObject_GenericGetDict(arg1: *mut PyObject, arg2: *mut c_void) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_GenericSetDict")]
pub fn PyObject_GenericSetDict(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *mut c_void,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_Hash")]
pub fn PyObject_Hash(arg1: *mut PyObject) -> Py_hash_t;
#[cfg_attr(PyPy, link_name = "PyPyObject_HashNotImplemented")]
pub fn PyObject_HashNotImplemented(arg1: *mut PyObject) -> Py_hash_t;
#[cfg_attr(PyPy, link_name = "PyPyObject_IsTrue")]
pub fn PyObject_IsTrue(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_Not")]
pub fn PyObject_Not(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCallable_Check")]
pub fn PyCallable_Check(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_ClearWeakRefs")]
pub fn PyObject_ClearWeakRefs(arg1: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyObject_Dir")]
pub fn PyObject_Dir(arg1: *mut PyObject) -> *mut PyObject;
pub fn Py_ReprEnter(arg1: *mut PyObject) -> c_int;
pub fn Py_ReprLeave(arg1: *mut PyObject);
}
// Flag bits for printing:
pub const Py_PRINT_RAW: c_int = 1; // No string quotes etc.
// skipped because is a private API
// const _Py_TPFLAGS_STATIC_BUILTIN: c_ulong = 1 << 1;
#[cfg(all(Py_3_12, not(Py_LIMITED_API)))]
pub const Py_TPFLAGS_MANAGED_WEAKREF: c_ulong = 1 << 3;
#[cfg(all(Py_3_11, not(Py_LIMITED_API)))]
pub const Py_TPFLAGS_MANAGED_DICT: c_ulong = 1 << 4;
#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
pub const Py_TPFLAGS_SEQUENCE: c_ulong = 1 << 5;
#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
pub const Py_TPFLAGS_MAPPING: c_ulong = 1 << 6;
#[cfg(Py_3_10)]
pub const Py_TPFLAGS_DISALLOW_INSTANTIATION: c_ulong = 1 << 7;
#[cfg(Py_3_10)]
pub const Py_TPFLAGS_IMMUTABLETYPE: c_ulong = 1 << 8;
/// Set if the type object is dynamically allocated
pub const Py_TPFLAGS_HEAPTYPE: c_ulong = 1 << 9;
/// Set if the type allows subclassing
pub const Py_TPFLAGS_BASETYPE: c_ulong = 1 << 10;
/// Set if the type implements the vectorcall protocol (PEP 590)
#[cfg(any(Py_3_12, not(Py_LIMITED_API)))]
pub const Py_TPFLAGS_HAVE_VECTORCALL: c_ulong = 1 << 11;
// skipped backwards-compatibility alias _Py_TPFLAGS_HAVE_VECTORCALL
/// Set if the type is 'ready' -- fully initialized
pub const Py_TPFLAGS_READY: c_ulong = 1 << 12;
/// Set while the type is being 'readied', to prevent recursive ready calls
pub const Py_TPFLAGS_READYING: c_ulong = 1 << 13;
/// Objects support garbage collection (see objimp.h)
pub const Py_TPFLAGS_HAVE_GC: c_ulong = 1 << 14;
const Py_TPFLAGS_HAVE_STACKLESS_EXTENSION: c_ulong = 0;
pub const Py_TPFLAGS_METHOD_DESCRIPTOR: c_ulong = 1 << 17;
pub const Py_TPFLAGS_VALID_VERSION_TAG: c_ulong = 1 << 19;
/* Type is abstract and cannot be instantiated */
pub const Py_TPFLAGS_IS_ABSTRACT: c_ulong = 1 << 20;
// skipped non-limited / 3.10 Py_TPFLAGS_HAVE_AM_SEND
#[cfg(Py_3_12)]
pub const Py_TPFLAGS_ITEMS_AT_END: c_ulong = 1 << 23;
/* These flags are used to determine if a type is a subclass. */
pub const Py_TPFLAGS_LONG_SUBCLASS: c_ulong = 1 << 24;
pub const Py_TPFLAGS_LIST_SUBCLASS: c_ulong = 1 << 25;
pub const Py_TPFLAGS_TUPLE_SUBCLASS: c_ulong = 1 << 26;
pub const Py_TPFLAGS_BYTES_SUBCLASS: c_ulong = 1 << 27;
pub const Py_TPFLAGS_UNICODE_SUBCLASS: c_ulong = 1 << 28;
pub const Py_TPFLAGS_DICT_SUBCLASS: c_ulong = 1 << 29;
pub const Py_TPFLAGS_BASE_EXC_SUBCLASS: c_ulong = 1 << 30;
pub const Py_TPFLAGS_TYPE_SUBCLASS: c_ulong = 1 << 31;
pub const Py_TPFLAGS_DEFAULT: c_ulong = if cfg!(Py_3_10) {
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION
} else {
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | Py_TPFLAGS_HAVE_VERSION_TAG
};
pub const Py_TPFLAGS_HAVE_FINALIZE: c_ulong = 1;
pub const Py_TPFLAGS_HAVE_VERSION_TAG: c_ulong = 1 << 18;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_NONE: c_uint = 0;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_FALSE: c_uint = 1;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_TRUE: c_uint = 2;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_ELLIPSIS: c_uint = 3;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_NOT_IMPLEMENTED: c_uint = 4;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_ZERO: c_uint = 5;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_ONE: c_uint = 6;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_EMPTY_STR: c_uint = 7;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_EMPTY_BYTES: c_uint = 8;
#[cfg(Py_3_13)]
pub const Py_CONSTANT_EMPTY_TUPLE: c_uint = 9;
extern_libpython! {
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPy_GetConstant")]
pub fn Py_GetConstant(constant_id: c_uint) -> *mut PyObject;
#[cfg(Py_3_13)]
#[cfg_attr(PyPy, link_name = "PyPy_GetConstantBorrowed")]
pub fn Py_GetConstantBorrowed(constant_id: c_uint) -> *mut PyObject;
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "_PyPy_NoneStruct")]
static mut _Py_NoneStruct: PyObject;
#[cfg(GraalPy)]
static mut _Py_NoneStructReference: *mut PyObject;
}
#[inline]
pub unsafe fn Py_None() -> *mut PyObject {
#[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))]
return Py_GetConstantBorrowed(Py_CONSTANT_NONE);
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
return &raw mut _Py_NoneStruct;
#[cfg(GraalPy)]
return _Py_NoneStructReference;
}
#[inline]
pub unsafe fn Py_IsNone(x: *mut PyObject) -> c_int {
Py_Is(x, Py_None())
}
// skipped Py_RETURN_NONE
extern_libpython! {
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "_PyPy_NotImplementedStruct")]
static mut _Py_NotImplementedStruct: PyObject;
#[cfg(GraalPy)]
static mut _Py_NotImplementedStructReference: *mut PyObject;
}
#[inline]
pub unsafe fn Py_NotImplemented() -> *mut PyObject {
#[cfg(all(not(GraalPy), all(Py_3_13, Py_LIMITED_API)))]
return Py_GetConstantBorrowed(Py_CONSTANT_NOT_IMPLEMENTED);
#[cfg(all(not(GraalPy), not(all(Py_3_13, Py_LIMITED_API))))]
return &raw mut _Py_NotImplementedStruct;
#[cfg(GraalPy)]
return _Py_NotImplementedStructReference;
}
// skipped Py_RETURN_NOTIMPLEMENTED
/* Rich comparison opcodes */
pub const Py_LT: c_int = 0;
pub const Py_LE: c_int = 1;
pub const Py_EQ: c_int = 2;
pub const Py_NE: c_int = 3;
pub const Py_GT: c_int = 4;
pub const Py_GE: c_int = 5;
#[cfg(Py_3_10)]
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum PySendResult {
PYGEN_RETURN = 0,
PYGEN_ERROR = -1,
PYGEN_NEXT = 1,
}
// skipped Py_RETURN_RICHCOMPARE
#[inline]
pub unsafe fn PyType_HasFeature(ty: *mut PyTypeObject, feature: c_ulong) -> c_int {
#[cfg(Py_LIMITED_API)]
let flags = PyType_GetFlags(ty);
#[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))]
let flags = (*ty).tp_flags.load(core::sync::atomic::Ordering::Relaxed);
#[cfg(all(not(Py_LIMITED_API), not(Py_GIL_DISABLED)))]
let flags = (*ty).tp_flags;
((flags & feature) != 0) as c_int
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyType_FastSubclass(t: *mut PyTypeObject, f: c_ulong) -> c_int {
PyType_HasFeature(t, f)
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyType_Check(op: *mut PyObject) -> c_int {
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS)
}
// skipped _PyType_CAST
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int {
Py_IS_TYPE(op, &raw mut PyType_Type)
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyType_Check(op: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyType_CheckExact(op: *mut PyObject) -> c_int;
#[cfg(any(Py_3_13, all(Py_3_11, not(Py_LIMITED_API))))]
#[cfg_attr(PyPy, link_name = "PyPyType_GetModuleByDef")]
pub fn PyType_GetModuleByDef(
arg1: *mut crate::PyTypeObject,
arg2: *mut crate::PyModuleDef,
) -> *mut PyObject;
#[cfg(Py_3_14)]
pub fn PyType_Freeze(tp: *mut crate::PyTypeObject) -> c_int;
#[cfg(Py_3_15)]
pub fn PyType_GetModuleByToken(_type: *mut PyTypeObject, token: *const c_void)
-> *mut PyObject;
}
+121
View File
@@ -0,0 +1,121 @@
use core::ffi::{c_int, c_void};
use libc::size_t;
use crate::object::*;
use crate::pyport::Py_ssize_t;
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyObject_Malloc")]
pub fn PyObject_Malloc(size: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyObject_Calloc")]
pub fn PyObject_Calloc(nelem: size_t, elsize: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyObject_Realloc")]
pub fn PyObject_Realloc(ptr: *mut c_void, new_size: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyObject_Free")]
pub fn PyObject_Free(ptr: *mut c_void);
// skipped PyObject_MALLOC
// skipped PyObject_REALLOC
// skipped PyObject_FREE
// skipped PyObject_Del
// skipped PyObject_DEL
#[cfg_attr(PyPy, link_name = "PyPyObject_Init")]
pub fn PyObject_Init(arg1: *mut PyObject, arg2: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyObject_InitVar")]
pub fn PyObject_InitVar(
arg1: *mut PyVarObject,
arg2: *mut PyTypeObject,
arg3: Py_ssize_t,
) -> *mut PyVarObject;
// skipped PyObject_INIT
// skipped PyObject_INIT_VAR
#[cfg_attr(PyPy, link_name = "_PyPyObject_New")]
fn _PyObject_New(typeobj: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "_PyPyObject_NewVar")]
fn _PyObject_NewVar(typeobj: *mut PyTypeObject, n: Py_ssize_t) -> *mut PyVarObject;
}
#[inline]
pub unsafe fn PyObject_New<T>(typeobj: *mut PyTypeObject) -> *mut T {
_PyObject_New(typeobj).cast()
}
// skipped PyObject_NEW
#[inline]
pub unsafe fn PyObject_NewVar<T>(typeobj: *mut PyTypeObject, n: Py_ssize_t) -> *mut T {
_PyObject_NewVar(typeobj, n).cast()
}
// skipped PyObject_NEW_VAR
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyGC_Collect")]
pub fn PyGC_Collect() -> Py_ssize_t;
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyGC_Enable")]
pub fn PyGC_Enable() -> c_int;
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyGC_Disable")]
pub fn PyGC_Disable() -> c_int;
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyGC_IsEnabled")]
pub fn PyGC_IsEnabled() -> c_int;
}
#[inline]
pub unsafe fn PyType_IS_GC(t: *mut PyTypeObject) -> c_int {
PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC)
}
extern_libpython! {
fn _PyObject_GC_Resize(op: *mut PyVarObject, n: Py_ssize_t) -> *mut PyVarObject;
}
#[inline]
pub unsafe fn PyObject_GC_Resize<T>(op: *mut PyObject, n: Py_ssize_t) -> *mut T {
_PyObject_GC_Resize(op.cast(), n).cast()
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "_PyPyObject_GC_New")]
fn _PyObject_GC_New(typeobj: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "_PyPyObject_GC_NewVar")]
fn _PyObject_GC_NewVar(typeobj: *mut PyTypeObject, n: Py_ssize_t) -> *mut PyVarObject;
#[cfg(not(PyPy))]
pub fn PyObject_GC_Track(arg1: *mut c_void);
#[cfg(not(PyPy))]
pub fn PyObject_GC_UnTrack(arg1: *mut c_void);
#[cfg_attr(PyPy, link_name = "PyPyObject_GC_Del")]
pub fn PyObject_GC_Del(arg1: *mut c_void);
}
#[inline]
pub unsafe fn PyObject_GC_New<T>(typeobj: *mut PyTypeObject) -> *mut T {
_PyObject_GC_New(typeobj).cast()
}
#[inline]
pub unsafe fn PyObject_GC_NewVar<T>(typeobj: *mut PyTypeObject, n: Py_ssize_t) -> *mut T {
_PyObject_GC_NewVar(typeobj, n).cast()
}
extern_libpython! {
#[cfg(any(all(Py_3_9, not(PyPy)), Py_3_10))] // added in 3.9, or 3.10 on PyPy
#[cfg_attr(PyPy, link_name = "PyPyObject_GC_IsTracked")]
pub fn PyObject_GC_IsTracked(arg1: *mut PyObject) -> c_int;
#[cfg(any(all(Py_3_9, not(PyPy)), Py_3_10))] // added in 3.9, or 3.10 on PyPy
#[cfg_attr(PyPy, link_name = "PyPyObject_GC_IsFinalized")]
pub fn PyObject_GC_IsFinalized(arg1: *mut PyObject) -> c_int;
}
// skipped Py_VISIT
+6
View File
@@ -0,0 +1,6 @@
use crate::object::PyObject;
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyOS_FSPath")]
pub fn PyOS_FSPath(path: *mut PyObject) -> *mut PyObject;
}
+1
View File
@@ -0,0 +1 @@
opaque_struct!(pub PyArena);
+134
View File
@@ -0,0 +1,134 @@
use crate::object::PyObject;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_int, c_void};
use core::ptr;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Py_buffer {
pub buf: *mut c_void,
/// Owned reference
pub obj: *mut crate::PyObject,
pub len: Py_ssize_t,
pub itemsize: Py_ssize_t,
pub readonly: c_int,
pub ndim: c_int,
pub format: *mut c_char,
pub shape: *mut Py_ssize_t,
pub strides: *mut Py_ssize_t,
pub suboffsets: *mut Py_ssize_t,
pub internal: *mut c_void,
#[cfg(PyPy)]
pub flags: c_int,
#[cfg(PyPy)]
pub _strides: [Py_ssize_t; PyBUF_MAX_NDIM],
#[cfg(PyPy)]
pub _shape: [Py_ssize_t; PyBUF_MAX_NDIM],
}
impl Py_buffer {
#[allow(clippy::new_without_default)]
pub const fn new() -> Self {
Py_buffer {
buf: ptr::null_mut(),
obj: ptr::null_mut(),
len: 0,
itemsize: 0,
readonly: 0,
ndim: 0,
format: ptr::null_mut(),
shape: ptr::null_mut(),
strides: ptr::null_mut(),
suboffsets: ptr::null_mut(),
internal: ptr::null_mut(),
#[cfg(PyPy)]
flags: 0,
#[cfg(PyPy)]
_strides: [0; PyBUF_MAX_NDIM],
#[cfg(PyPy)]
_shape: [0; PyBUF_MAX_NDIM],
}
}
}
pub type getbufferproc = unsafe extern "C" fn(*mut PyObject, *mut crate::Py_buffer, c_int) -> c_int;
pub type releasebufferproc = unsafe extern "C" fn(*mut PyObject, *mut crate::Py_buffer);
/* Return 1 if the getbuffer function is available, otherwise return 0. */
extern_libpython! {
#[cfg(not(PyPy))]
pub fn PyObject_CheckBuffer(obj: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_GetBuffer")]
pub fn PyObject_GetBuffer(obj: *mut PyObject, view: *mut Py_buffer, flags: c_int) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_GetPointer")]
pub fn PyBuffer_GetPointer(view: *const Py_buffer, indices: *const Py_ssize_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_SizeFromFormat")]
pub fn PyBuffer_SizeFromFormat(format: *const c_char) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_ToContiguous")]
pub fn PyBuffer_ToContiguous(
buf: *mut c_void,
view: *const Py_buffer,
len: Py_ssize_t,
order: c_char,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_FromContiguous")]
pub fn PyBuffer_FromContiguous(
view: *const Py_buffer,
buf: *const c_void,
len: Py_ssize_t,
order: c_char,
) -> c_int;
pub fn PyObject_CopyData(dest: *mut PyObject, src: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_IsContiguous")]
pub fn PyBuffer_IsContiguous(view: *const Py_buffer, fort: c_char) -> c_int;
pub fn PyBuffer_FillContiguousStrides(
ndims: c_int,
shape: *mut Py_ssize_t,
strides: *mut Py_ssize_t,
itemsize: c_int,
fort: c_char,
);
#[cfg_attr(PyPy, link_name = "PyPyBuffer_FillInfo")]
pub fn PyBuffer_FillInfo(
view: *mut Py_buffer,
o: *mut PyObject,
buf: *mut c_void,
len: Py_ssize_t,
readonly: c_int,
flags: c_int,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_Release")]
pub fn PyBuffer_Release(view: *mut Py_buffer);
}
/// Maximum number of dimensions
pub const PyBUF_MAX_NDIM: usize = 64;
/* Flags for getting buffers */
pub const PyBUF_SIMPLE: c_int = 0;
pub const PyBUF_WRITABLE: c_int = 0x0001;
/* we used to include an E, backwards compatible alias */
pub const PyBUF_WRITEABLE: c_int = PyBUF_WRITABLE;
pub const PyBUF_FORMAT: c_int = 0x0004;
pub const PyBUF_ND: c_int = 0x0008;
pub const PyBUF_STRIDES: c_int = 0x0010 | PyBUF_ND;
pub const PyBUF_C_CONTIGUOUS: c_int = 0x0020 | PyBUF_STRIDES;
pub const PyBUF_F_CONTIGUOUS: c_int = 0x0040 | PyBUF_STRIDES;
pub const PyBUF_ANY_CONTIGUOUS: c_int = 0x0080 | PyBUF_STRIDES;
pub const PyBUF_INDIRECT: c_int = 0x0100 | PyBUF_STRIDES;
pub const PyBUF_CONTIG: c_int = PyBUF_ND | PyBUF_WRITABLE;
pub const PyBUF_CONTIG_RO: c_int = PyBUF_ND;
pub const PyBUF_STRIDED: c_int = PyBUF_STRIDES | PyBUF_WRITABLE;
pub const PyBUF_STRIDED_RO: c_int = PyBUF_STRIDES;
pub const PyBUF_RECORDS: c_int = PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT;
pub const PyBUF_RECORDS_RO: c_int = PyBUF_STRIDES | PyBUF_FORMAT;
pub const PyBUF_FULL: c_int = PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT;
pub const PyBUF_FULL_RO: c_int = PyBUF_INDIRECT | PyBUF_FORMAT;
pub const PyBUF_READ: c_int = 0x100;
pub const PyBUF_WRITE: c_int = 0x200;
+51
View File
@@ -0,0 +1,51 @@
use crate::object::*;
use core::ffi::{c_char, c_int, c_void};
#[cfg(not(RustPython))]
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyCapsule_Type")]
pub static mut PyCapsule_Type: PyTypeObject;
}
pub type PyCapsule_Destructor = unsafe extern "C" fn(o: *mut PyObject);
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int {
(Py_TYPE(ob) == &raw mut PyCapsule_Type) as c_int
}
extern_libpython! {
#[cfg(RustPython)]
pub fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_New")]
pub fn PyCapsule_New(
pointer: *mut c_void,
name: *const c_char,
destructor: Option<PyCapsule_Destructor>,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_GetPointer")]
pub fn PyCapsule_GetPointer(capsule: *mut PyObject, name: *const c_char) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_GetDestructor")]
pub fn PyCapsule_GetDestructor(capsule: *mut PyObject) -> Option<PyCapsule_Destructor>;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_GetName")]
pub fn PyCapsule_GetName(capsule: *mut PyObject) -> *const c_char;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_GetContext")]
pub fn PyCapsule_GetContext(capsule: *mut PyObject) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_IsValid")]
pub fn PyCapsule_IsValid(capsule: *mut PyObject, name: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_SetPointer")]
pub fn PyCapsule_SetPointer(capsule: *mut PyObject, pointer: *mut c_void) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_SetDestructor")]
pub fn PyCapsule_SetDestructor(
capsule: *mut PyObject,
destructor: Option<PyCapsule_Destructor>,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_SetName")]
pub fn PyCapsule_SetName(capsule: *mut PyObject, name: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_SetContext")]
pub fn PyCapsule_SetContext(capsule: *mut PyObject, context: *mut c_void) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCapsule_Import")]
pub fn PyCapsule_Import(name: *const c_char, no_block: c_int) -> *mut c_void;
}
+397
View File
@@ -0,0 +1,397 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
use core::ffi::{c_char, c_int};
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyErr_SetNone")]
pub fn PyErr_SetNone(arg1: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyErr_SetObject")]
pub fn PyErr_SetObject(arg1: *mut PyObject, arg2: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyErr_SetString")]
pub fn PyErr_SetString(exception: *mut PyObject, string: *const c_char);
#[cfg_attr(PyPy, link_name = "PyPyErr_Occurred")]
pub fn PyErr_Occurred() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyErr_Clear")]
pub fn PyErr_Clear();
#[cfg_attr(Py_3_12, deprecated(note = "Use PyErr_GetRaisedException() instead."))]
#[cfg_attr(PyPy, link_name = "PyPyErr_Fetch")]
pub fn PyErr_Fetch(
arg1: *mut *mut PyObject,
arg2: *mut *mut PyObject,
arg3: *mut *mut PyObject,
);
#[cfg_attr(Py_3_12, deprecated(note = "Use PyErr_SetRaisedException() instead."))]
#[cfg_attr(PyPy, link_name = "PyPyErr_Restore")]
pub fn PyErr_Restore(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyErr_GetExcInfo")]
pub fn PyErr_GetExcInfo(
arg1: *mut *mut PyObject,
arg2: *mut *mut PyObject,
arg3: *mut *mut PyObject,
);
#[cfg_attr(PyPy, link_name = "PyPyErr_SetExcInfo")]
pub fn PyErr_SetExcInfo(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPy_FatalError")]
pub fn Py_FatalError(message: *const c_char) -> !;
#[cfg_attr(PyPy, link_name = "PyPyErr_GivenExceptionMatches")]
pub fn PyErr_GivenExceptionMatches(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyErr_ExceptionMatches")]
pub fn PyErr_ExceptionMatches(arg1: *mut PyObject) -> c_int;
#[cfg_attr(
Py_3_12,
deprecated(
note = "Use PyErr_GetRaisedException() instead, to avoid any possible de-normalization."
)
)]
#[cfg_attr(PyPy, link_name = "PyPyErr_NormalizeException")]
pub fn PyErr_NormalizeException(
arg1: *mut *mut PyObject,
arg2: *mut *mut PyObject,
arg3: *mut *mut PyObject,
);
#[cfg(Py_3_12)]
pub fn PyErr_GetRaisedException() -> *mut PyObject;
#[cfg(Py_3_12)]
pub fn PyErr_SetRaisedException(exc: *mut PyObject);
#[cfg(Py_3_11)]
#[cfg_attr(PyPy, link_name = "PyPyErr_GetHandledException")]
pub fn PyErr_GetHandledException() -> *mut PyObject;
#[cfg(Py_3_11)]
#[cfg_attr(PyPy, link_name = "PyPyErr_SetHandledException")]
pub fn PyErr_SetHandledException(exc: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyException_SetTraceback")]
pub fn PyException_SetTraceback(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyException_GetTraceback")]
pub fn PyException_GetTraceback(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyException_GetCause")]
pub fn PyException_GetCause(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyException_SetCause")]
pub fn PyException_SetCause(arg1: *mut PyObject, arg2: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyException_GetContext")]
pub fn PyException_GetContext(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyException_SetContext")]
pub fn PyException_SetContext(arg1: *mut PyObject, arg2: *mut PyObject);
#[cfg(RustPython)]
pub fn PyExceptionClass_Check(x: *mut PyObject) -> c_int;
#[cfg(RustPython)]
pub fn PyExceptionInstance_Check(x: *mut PyObject) -> c_int;
#[cfg(PyPy)]
#[link_name = "PyPyExceptionInstance_Class"]
pub fn PyExceptionInstance_Class(x: *mut PyObject) -> *mut PyObject;
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyExceptionClass_Check(x: *mut PyObject) -> c_int {
(PyType_Check(x) != 0
&& PyType_FastSubclass(x as *mut PyTypeObject, Py_TPFLAGS_BASE_EXC_SUBCLASS) != 0)
as c_int
}
#[inline]
#[cfg(not(RustPython))]
pub unsafe fn PyExceptionInstance_Check(x: *mut PyObject) -> c_int {
PyType_FastSubclass(Py_TYPE(x), Py_TPFLAGS_BASE_EXC_SUBCLASS)
}
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn PyExceptionInstance_Class(x: *mut PyObject) -> *mut PyObject {
Py_TYPE(x) as *mut PyObject
}
// ported from cpython exception.c (line 2096)
#[cfg(PyPy)]
pub unsafe fn PyUnicodeDecodeError_Create(
encoding: *const c_char,
object: *const c_char,
length: Py_ssize_t,
start: Py_ssize_t,
end: Py_ssize_t,
reason: *const c_char,
) -> *mut PyObject {
crate::_PyObject_CallFunction_SizeT(
PyExc_UnicodeDecodeError,
c"sy#nns".as_ptr(),
encoding,
object,
length,
start,
end,
reason,
)
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyExc_BaseException")]
pub static mut PyExc_BaseException: *mut PyObject;
#[cfg(Py_3_11)]
#[cfg_attr(PyPy, link_name = "PyPyExc_BaseExceptionGroup")]
pub static mut PyExc_BaseExceptionGroup: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_Exception")]
pub static mut PyExc_Exception: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_StopAsyncIteration")]
pub static mut PyExc_StopAsyncIteration: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_StopIteration")]
pub static mut PyExc_StopIteration: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_GeneratorExit")]
pub static mut PyExc_GeneratorExit: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ArithmeticError")]
pub static mut PyExc_ArithmeticError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_LookupError")]
pub static mut PyExc_LookupError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_AssertionError")]
pub static mut PyExc_AssertionError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_AttributeError")]
pub static mut PyExc_AttributeError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_BufferError")]
pub static mut PyExc_BufferError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_EOFError")]
pub static mut PyExc_EOFError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_FloatingPointError")]
pub static mut PyExc_FloatingPointError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_OSError")]
pub static mut PyExc_OSError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ImportError")]
pub static mut PyExc_ImportError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ModuleNotFoundError")]
pub static mut PyExc_ModuleNotFoundError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_IndexError")]
pub static mut PyExc_IndexError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_KeyError")]
pub static mut PyExc_KeyError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_KeyboardInterrupt")]
pub static mut PyExc_KeyboardInterrupt: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_MemoryError")]
pub static mut PyExc_MemoryError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_NameError")]
pub static mut PyExc_NameError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_OverflowError")]
pub static mut PyExc_OverflowError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_RuntimeError")]
pub static mut PyExc_RuntimeError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_RecursionError")]
pub static mut PyExc_RecursionError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_NotImplementedError")]
pub static mut PyExc_NotImplementedError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_SyntaxError")]
pub static mut PyExc_SyntaxError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_IndentationError")]
pub static mut PyExc_IndentationError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_TabError")]
pub static mut PyExc_TabError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ReferenceError")]
pub static mut PyExc_ReferenceError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_SystemError")]
pub static mut PyExc_SystemError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_SystemExit")]
pub static mut PyExc_SystemExit: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_TypeError")]
pub static mut PyExc_TypeError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_UnboundLocalError")]
pub static mut PyExc_UnboundLocalError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeError")]
pub static mut PyExc_UnicodeError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeEncodeError")]
pub static mut PyExc_UnicodeEncodeError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeDecodeError")]
pub static mut PyExc_UnicodeDecodeError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeTranslateError")]
pub static mut PyExc_UnicodeTranslateError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ValueError")]
pub static mut PyExc_ValueError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ZeroDivisionError")]
pub static mut PyExc_ZeroDivisionError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_BlockingIOError")]
pub static mut PyExc_BlockingIOError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_BrokenPipeError")]
pub static mut PyExc_BrokenPipeError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ChildProcessError")]
pub static mut PyExc_ChildProcessError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ConnectionError")]
pub static mut PyExc_ConnectionError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ConnectionAbortedError")]
pub static mut PyExc_ConnectionAbortedError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ConnectionRefusedError")]
pub static mut PyExc_ConnectionRefusedError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ConnectionResetError")]
pub static mut PyExc_ConnectionResetError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_FileExistsError")]
pub static mut PyExc_FileExistsError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_FileNotFoundError")]
pub static mut PyExc_FileNotFoundError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_InterruptedError")]
pub static mut PyExc_InterruptedError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_IsADirectoryError")]
pub static mut PyExc_IsADirectoryError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_NotADirectoryError")]
pub static mut PyExc_NotADirectoryError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_PermissionError")]
pub static mut PyExc_PermissionError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ProcessLookupError")]
pub static mut PyExc_ProcessLookupError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_TimeoutError")]
pub static mut PyExc_TimeoutError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_OSError")]
pub static mut PyExc_EnvironmentError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_OSError")]
pub static mut PyExc_IOError: *mut PyObject;
#[cfg(windows)]
#[cfg_attr(PyPy, link_name = "PyPyExc_OSError")]
pub static mut PyExc_WindowsError: *mut PyObject;
pub static mut PyExc_RecursionErrorInst: *mut PyObject;
/* Predefined warning categories */
#[cfg_attr(PyPy, link_name = "PyPyExc_Warning")]
pub static mut PyExc_Warning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_UserWarning")]
pub static mut PyExc_UserWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_DeprecationWarning")]
pub static mut PyExc_DeprecationWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_PendingDeprecationWarning")]
pub static mut PyExc_PendingDeprecationWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_SyntaxWarning")]
pub static mut PyExc_SyntaxWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_RuntimeWarning")]
pub static mut PyExc_RuntimeWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_FutureWarning")]
pub static mut PyExc_FutureWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ImportWarning")]
pub static mut PyExc_ImportWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_UnicodeWarning")]
pub static mut PyExc_UnicodeWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_BytesWarning")]
pub static mut PyExc_BytesWarning: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ResourceWarning")]
pub static mut PyExc_ResourceWarning: *mut PyObject;
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyExc_EncodingWarning")]
pub static mut PyExc_EncodingWarning: *mut PyObject;
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyErr_BadArgument")]
pub fn PyErr_BadArgument() -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyErr_NoMemory")]
pub fn PyErr_NoMemory() -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyErr_SetFromErrno")]
pub fn PyErr_SetFromErrno(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyErr_SetFromErrnoWithFilenameObject")]
pub fn PyErr_SetFromErrnoWithFilenameObject(
arg1: *mut PyObject,
arg2: *mut PyObject,
) -> *mut PyObject;
pub fn PyErr_SetFromErrnoWithFilenameObjects(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *mut PyObject,
) -> *mut PyObject;
pub fn PyErr_SetFromErrnoWithFilename(
exc: *mut PyObject,
filename: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyErr_Format")]
pub fn PyErr_Format(exception: *mut PyObject, format: *const c_char, ...) -> *mut PyObject;
pub fn PyErr_SetImportErrorSubclass(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *mut PyObject,
arg4: *mut PyObject,
) -> *mut PyObject;
pub fn PyErr_SetImportError(
arg1: *mut PyObject,
arg2: *mut PyObject,
arg3: *mut PyObject,
) -> *mut PyObject;
#[cfg(PyPy)]
#[cfg_attr(PyPy, link_name = "PyPyErr_BadInternalCall")]
pub fn PyErr_BadInternalCall();
#[cfg(not(PyPy))]
fn _PyErr_BadInternalCall(filename: *const c_char, lineno: c_int);
}
#[cfg(not(PyPy))]
#[track_caller]
#[inline]
pub unsafe fn PyErr_BadInternalCall() {
let location = core::panic::Location::caller();
let filename = alloc::ffi::CString::new(location.file()).unwrap();
// SAFETY: `filename` is null terminated, `location.line()` saturates if exceeds c_int
unsafe {
_PyErr_BadInternalCall(
filename.as_ptr(),
location.line().try_into().unwrap_or(c_int::MAX),
)
}
}
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyErr_NewException")]
pub fn PyErr_NewException(
name: *const c_char,
base: *mut PyObject,
dict: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyErr_NewExceptionWithDoc")]
pub fn PyErr_NewExceptionWithDoc(
name: *const c_char,
doc: *const c_char,
base: *mut PyObject,
dict: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyErr_WriteUnraisable")]
pub fn PyErr_WriteUnraisable(arg1: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPyErr_CheckSignals")]
pub fn PyErr_CheckSignals() -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyErr_SetInterrupt")]
pub fn PyErr_SetInterrupt();
#[cfg(Py_3_10)]
#[cfg_attr(PyPy, link_name = "PyPyErr_SetInterruptEx")]
pub fn PyErr_SetInterruptEx(signum: c_int) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyErr_SyntaxLocation")]
pub fn PyErr_SyntaxLocation(filename: *const c_char, lineno: c_int);
#[cfg_attr(PyPy, link_name = "PyPyErr_SyntaxLocationEx")]
pub fn PyErr_SyntaxLocationEx(filename: *const c_char, lineno: c_int, col_offset: c_int);
#[cfg_attr(PyPy, link_name = "PyPyErr_ProgramText")]
pub fn PyErr_ProgramText(filename: *const c_char, lineno: c_int) -> *mut PyObject;
#[cfg(not(PyPy))]
pub fn PyUnicodeDecodeError_Create(
encoding: *const c_char,
object: *const c_char,
length: Py_ssize_t,
start: Py_ssize_t,
end: Py_ssize_t,
reason: *const c_char,
) -> *mut PyObject;
pub fn PyUnicodeEncodeError_GetEncoding(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyUnicodeDecodeError_GetEncoding(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyUnicodeEncodeError_GetObject(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyUnicodeDecodeError_GetObject(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyUnicodeTranslateError_GetObject(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyUnicodeEncodeError_GetStart(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int;
pub fn PyUnicodeDecodeError_GetStart(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int;
pub fn PyUnicodeTranslateError_GetStart(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int;
pub fn PyUnicodeEncodeError_SetStart(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int;
pub fn PyUnicodeDecodeError_SetStart(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int;
pub fn PyUnicodeTranslateError_SetStart(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int;
pub fn PyUnicodeEncodeError_GetEnd(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int;
pub fn PyUnicodeDecodeError_GetEnd(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int;
pub fn PyUnicodeTranslateError_GetEnd(arg1: *mut PyObject, arg2: *mut Py_ssize_t) -> c_int;
pub fn PyUnicodeEncodeError_SetEnd(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int;
pub fn PyUnicodeDecodeError_SetEnd(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int;
pub fn PyUnicodeTranslateError_SetEnd(arg1: *mut PyObject, arg2: Py_ssize_t) -> c_int;
pub fn PyUnicodeEncodeError_GetReason(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyUnicodeDecodeError_GetReason(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyUnicodeTranslateError_GetReason(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyUnicodeEncodeError_SetReason(exc: *mut PyObject, reason: *const c_char) -> c_int;
pub fn PyUnicodeDecodeError_SetReason(exc: *mut PyObject, reason: *const c_char) -> c_int;
pub fn PyUnicodeTranslateError_SetReason(exc: *mut PyObject, reason: *const c_char) -> c_int;
}
+13
View File
@@ -0,0 +1,13 @@
#[cfg(not(GraalPy))]
#[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
use crate::PyCodeObject;
use crate::PyFrameObject;
use core::ffi::c_int;
extern_libpython! {
pub fn PyFrame_GetLineNumber(frame: *mut PyFrameObject) -> c_int;
#[cfg(not(GraalPy))]
#[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
pub fn PyFrame_GetCode(frame: *mut PyFrameObject) -> *mut PyCodeObject;
}
+31
View File
@@ -0,0 +1,31 @@
#[cfg(not(any(Py_LIMITED_API, PyPy, Py_3_14)))]
use crate::pyport::{Py_hash_t, Py_ssize_t};
#[cfg(not(any(Py_LIMITED_API, PyPy, Py_3_14)))]
use core::ffi::c_void;
use core::ffi::{c_int, c_ulong};
extern_libpython! {
// skipped non-limited _Py_HashDouble
// skipped non-limited _Py_HashPointer
// skipped non-limited _Py_HashPointerRaw
#[cfg(not(any(Py_LIMITED_API, PyPy, Py_3_14)))]
pub(crate) fn _Py_HashBytes(src: *const c_void, len: Py_ssize_t) -> Py_hash_t;
}
pub const _PyHASH_MULTIPLIER: c_ulong = 1000003;
// skipped _PyHASH_BITS
// skipped non-limited _Py_HashSecret_t
// skipped Py_HASH_CUTOFF
pub const Py_HASH_EXTERNAL: c_int = 0;
pub const Py_HASH_SIPHASH24: c_int = 1;
pub const Py_HASH_FNV: c_int = 2;
#[cfg(Py_3_11)]
pub const Py_HASH_SIPHASH13: c_int = 3;
// skipped Py_HASH_ALGORITHM
+104
View File
@@ -0,0 +1,104 @@
use crate::pytypedefs::PyThreadState;
use core::ffi::{c_char, c_int};
use libc::wchar_t;
extern_libpython! {
pub fn Py_Initialize();
pub fn Py_InitializeEx(arg1: c_int);
pub fn Py_Finalize();
pub fn Py_FinalizeEx() -> c_int;
#[cfg_attr(PyPy, link_name = "PyPy_IsInitialized")]
pub fn Py_IsInitialized() -> c_int;
pub fn Py_NewInterpreter() -> *mut PyThreadState;
pub fn Py_EndInterpreter(arg1: *mut PyThreadState);
#[cfg_attr(PyPy, link_name = "PyPy_AtExit")]
pub fn Py_AtExit(func: Option<extern "C" fn()>) -> c_int;
pub fn Py_Exit(arg1: c_int) -> !;
pub fn Py_Main(argc: c_int, argv: *mut *mut wchar_t) -> c_int;
pub fn Py_BytesMain(argc: c_int, argv: *mut *mut c_char) -> c_int;
#[cfg_attr(
Py_3_11,
deprecated(note = "Deprecated since Python 3.11. Use `PyConfig.program_name` instead.")
)]
pub fn Py_SetProgramName(arg1: *const wchar_t);
#[cfg(not(Py_3_15))]
#[cfg_attr(PyPy, link_name = "PyPy_GetProgramName")]
#[cfg_attr(
Py_3_13,
deprecated(note = "Deprecated since Python 3.13. Use `sys.executable` instead.")
)]
pub fn Py_GetProgramName() -> *mut wchar_t;
#[cfg_attr(
Py_3_11,
deprecated(note = "Deprecated since Python 3.11. Use `PyConfig.home` instead.")
)]
pub fn Py_SetPythonHome(arg1: *const wchar_t);
#[cfg(not(Py_3_15))]
#[cfg_attr(
Py_3_13,
deprecated(
note = "Deprecated since Python 3.13. Use `PyConfig.home` or the value of the `PYTHONHOME` environment variable instead."
)
)]
pub fn Py_GetPythonHome() -> *mut wchar_t;
#[cfg(not(Py_3_15))]
#[cfg_attr(
Py_3_13,
deprecated(note = "Deprecated since Python 3.13. Use `sys.executable` instead.")
)]
pub fn Py_GetProgramFullPath() -> *mut wchar_t;
#[cfg(not(Py_3_15))]
#[cfg_attr(
Py_3_13,
deprecated(note = "Deprecated since Python 3.13. Use `sys.prefix` instead.")
)]
pub fn Py_GetPrefix() -> *mut wchar_t;
#[cfg(not(Py_3_15))]
#[cfg_attr(
Py_3_13,
deprecated(note = "Deprecated since Python 3.13. Use `sys.exec_prefix` instead.")
)]
pub fn Py_GetExecPrefix() -> *mut wchar_t;
#[cfg(not(Py_3_15))]
#[cfg_attr(
Py_3_13,
deprecated(note = "Deprecated since Python 3.13. Use `sys.path` instead.")
)]
pub fn Py_GetPath() -> *mut wchar_t;
#[cfg(not(Py_3_13))]
#[cfg_attr(
Py_3_11,
deprecated(note = "Deprecated since Python 3.11. Use `sys.path` instead.")
)]
pub fn Py_SetPath(arg1: *const wchar_t);
// skipped _Py_CheckPython3
#[cfg_attr(PyPy, link_name = "PyPy_GetVersion")]
pub fn Py_GetVersion() -> *const c_char;
pub fn Py_GetPlatform() -> *const c_char;
pub fn Py_GetCopyright() -> *const c_char;
pub fn Py_GetCompiler() -> *const c_char;
pub fn Py_GetBuildInfo() -> *const c_char;
}
type PyOS_sighandler_t = unsafe extern "C" fn(arg1: c_int);
extern_libpython! {
pub fn PyOS_getsig(arg1: c_int) -> PyOS_sighandler_t;
pub fn PyOS_setsig(arg1: c_int, arg2: PyOS_sighandler_t) -> PyOS_sighandler_t;
#[cfg(Py_3_11)]
pub static Py_Version: core::ffi::c_ulong;
#[cfg(Py_3_13)]
pub fn Py_IsFinalizing() -> c_int;
}
+13
View File
@@ -0,0 +1,13 @@
use core::ffi::c_void;
use libc::size_t;
extern_libpython! {
#[cfg_attr(PyPy, link_name = "PyPyMem_Malloc")]
pub fn PyMem_Malloc(size: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyMem_Calloc")]
pub fn PyMem_Calloc(nelem: size_t, elsize: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyMem_Realloc")]
pub fn PyMem_Realloc(ptr: *mut c_void, new_size: size_t) -> *mut c_void;
#[cfg_attr(PyPy, link_name = "PyPyMem_Free")]
pub fn PyMem_Free(ptr: *mut c_void);
}
Loaded 100 of 1714 files, more files were not shown because too many files have changed in this diff. Show more