Support rust extensions for PyPy via cpyext (#393)

* wip

* removed stuff

* removed another change

* implemented minimum amouth of ifdefs to make pypy3 hello world to compile

* implemented minimum amount of ifdefs to make pypy3 hello world to compile

* hacking on build.rs

* compiler is happy!

* few todos remain

* extracted build logic to seperate module

* added pypy test

* finally fixed pypy structs

* removed some todos

* test should now be machine independent

* fixed all pypy3 symbols

* added pypy feature

* removed `is_pypy`

* added pypy2 declerations also

* fix for cpython2

* improved libpypy detection

* added all pypy2 macros

* fixed errneous type

* more fixes

* fix python2 string macros

* modsupport symbol

* fix

* fixed and added many symbols

* fixes

* remove dup

* remove mac-specific config

* fix all name mangling macros

* unite imports

* missing symbol

* fix pybool

* implemented another missing symbol

* it works

* fix merge conflict

* uncomment non default features

* cargo.toml

* Cargo fmt

* small merge fixes

* use newer build version

* whoops

* fix build script

* more build hacks

* some random hiccups

* small fixes

* it builds!

* it builds and runs

* revert everything in FFI2

* revert changes to ffi2

* check python3 for pypy

* tiny fix

* revert ffi2 for real

* revert weird formatting changes

* bring back missing feature

* tiny error

* fix py3.7 issue

* add pypy3.5 6.0 to travis

* remove dbg!

* another tiny fix

* removed some useless annotations, and fixed inlines annotations

* removed `pretty_assertions`

* removed pypy feature from cargo.toml

* fix for Py_CompileStringFlags

* tox runs word_count!

* __dict__ changes are not supported for PyPy

* fix 3.7 and copy comment

* fix test script 😳

* transfer ownership of strings to cpython when possible

* remove cstr! macro

* added missing nuls

* as_bytes() -> b’’ string

* symbol removed by mistake

* properly shim pypy date time API, some tests are passing!

* extension_module tests now not crashing! (some still skipped)

* maybe travis has new pypy version?

* small error on windows (build script)

* fix conditional compilation

* try to make tests run on travis..

* invert condition

* added pytest-faulthandler to facilitate debugging

* correctly name dir

* use full paths

* say —yes to conda

* fix

* syntax error

* change PATH

* fixed a terrible bug with PyTypeObjects in PyPy

* fix PyTypeObject defs

* re-enabled tests!

* all tests are passing!

* make the fix ad-hoc for now

* removed build module

* revert changes that cause an additional GC bug

* prevented buggy test from failing pypy

* removed unused comment

* don’t run coverage on pypy

* removed some erroneous symbols from function calls which are actually macros

* restore py37 pyunicode missing def

* use only `link_name` in PyPy specific declarations

* only setup PyPy when testing against PyPy

* annotation that was eaten during merge

* remove change to  comment by mistake + unnecessary changes to cargo.toml

* xfail dates test only on pypy

* changed comment to be a little more helpful

* cleaned up some warnings

* Update src/ffi3/ceval.rs

Co-Authored-By: omerbenamram <omerbenamram@gmail.com>

* @konstin PR notes

* rustfmt

* some documentation

* if configured via env var only, default to cpython

* remove extra unsafe

* refer users to guide for pypy

* Update guide/src/pypy.md

Co-Authored-By: omerbenamram <omerbenamram@gmail.com>

* Update guide/src/pypy.md

Co-Authored-By: omerbenamram <omerbenamram@gmail.com>

* @konstin applied patch

* check that pypy at least build

* search explicitly for libpypy

* added note about some known unsupported features

* use ld_version

* export PYTHON_SYS_EXECUTABLE to `cargo build` test

* inverted if

* always link pypy dynamically

* remove unused imports

* Apply @kngwyu’s suggestion

* fix tox configuration

* try conda virtualenv

* try to simply not install python at all inside pypy environment

* setup pypy before using “python"

* use system_site_packages

* revert change to .travis

* moved cpyext datetime documentation to module level, and revised it.

* Update src/ffi/datetime.rs

Co-Authored-By: omerbenamram <omerbenamram@gmail.com>

* rustfmt

* Update src/ffi/datetime.rs

Co-Authored-By: omerbenamram <omerbenamram@gmail.com>

* kept only notes that are relevant to users.

* invert if

* use bash and not sh
This commit is contained in:
Omer BenAmram 2019-04-23 12:18:42 +01:00 committed by konstin
parent fb8d3605d1
commit f8bf258602
66 changed files with 1068 additions and 88 deletions

View File

@ -23,6 +23,10 @@ matrix:
python: "3.7"
# Keep this synced up with build.rs
env: TRAVIS_RUST_VERSION=nightly-2019-02-07
# Tested via anaconda PyPy (since travis's PyPy version is too old)
- name: PyPy3.5 7.0
python: "3.7"
env: FEATURES="pypy" PATH="$PATH:/opt/anaconda/envs/pypy3/bin"
allow_failures:
- python: "3.8-dev"

View File

@ -18,6 +18,9 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste
PyO3 supports Python 3.5 and up. The minimum required rust version is 1.34.0-nightly 2019-02-06.
PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0.
Please refer to the guide for installation instruction against PyPy.
You can either write a native Python module in rust or use Python from a Rust binary.
However, on some OSs, you need some additional packages. E.g. if you are on *Ubuntu 18.04*, please run

159
build.rs
View File

@ -18,11 +18,18 @@ use version_check::{is_min_date, is_min_version, supports_features};
const MIN_DATE: &'static str = "2019-02-06";
const MIN_VERSION: &'static str = "1.34.0-nightly";
#[derive(Debug, Clone, PartialEq)]
pub enum PythonInterpreterKind {
CPython,
PyPy,
}
#[derive(Debug)]
struct PythonVersion {
major: u8,
// minor == None means any minor version will do
minor: Option<u8>,
implementation: PythonInterpreterKind,
}
impl PartialEq for PythonVersion {
@ -142,6 +149,7 @@ fn load_cross_compile_info() -> Result<(PythonVersion, HashMap<String, String>,
let python_version = PythonVersion {
major,
minor: Some(minor),
implementation: PythonInterpreterKind::CPython,
};
let config_map = parse_header_defines(python_include_dir.join("pyconfig.h"))?;
@ -280,17 +288,43 @@ fn run_python_script(interpreter: &str, script: &str) -> Result<String, String>
Ok(String::from_utf8(out.stdout).unwrap())
}
fn get_library_link_name(version: &PythonVersion, ld_version: &str) -> String {
if cfg!(target_os = "windows") {
let minor_or_empty_string = match version.minor {
Some(minor) => format!("{}", minor),
None => String::new(),
};
match version.implementation {
PythonInterpreterKind::CPython => {
format!("python{}{}", version.major, minor_or_empty_string)
}
PythonInterpreterKind::PyPy => format!("pypy{}-c", version.major),
}
} else {
match version.implementation {
PythonInterpreterKind::CPython => format!("python{}", ld_version),
PythonInterpreterKind::PyPy => format!("pypy{}-c", version.major),
}
}
}
#[cfg(not(target_os = "macos"))]
#[cfg(not(target_os = "windows"))]
fn get_rustc_link_lib(
_: &PythonVersion,
version: &PythonVersion,
ld_version: &str,
enable_shared: bool,
) -> Result<String, String> {
if enable_shared {
Ok(format!("cargo:rustc-link-lib=python{}", ld_version))
Ok(format!(
"cargo:rustc-link-lib={}",
get_library_link_name(&version, ld_version)
))
} else {
Ok(format!("cargo:rustc-link-lib=static=python{}", ld_version))
Ok(format!(
"cargo:rustc-link-lib=static={}",
get_library_link_name(&version, ld_version)
))
}
}
@ -311,42 +345,63 @@ else:
}
#[cfg(target_os = "macos")]
fn get_rustc_link_lib(_: &PythonVersion, ld_version: &str, _: bool) -> Result<String, String> {
fn get_rustc_link_lib(
version: &PythonVersion,
ld_version: &str,
_: bool,
) -> Result<String, String> {
// os x can be linked to a framework or static or dynamic, and
// Py_ENABLE_SHARED is wrong; framework means shared library
match get_macos_linkmodel().unwrap().as_ref() {
"static" => Ok(format!("cargo:rustc-link-lib=static=python{}", ld_version)),
"shared" => Ok(format!("cargo:rustc-link-lib=python{}", ld_version)),
"framework" => Ok(format!("cargo:rustc-link-lib=python{}", ld_version)),
"static" => Ok(format!(
"cargo:rustc-link-lib=static={}",
get_library_link_name(&version, ld_version)
)),
"shared" => Ok(format!(
"cargo:rustc-link-lib={}",
get_library_link_name(&version, ld_version)
)),
"framework" => Ok(format!(
"cargo:rustc-link-lib={}",
get_library_link_name(&version, ld_version)
)),
other => Err(format!("unknown linkmodel {}", other)),
}
}
#[cfg(target_os = "windows")]
fn get_rustc_link_lib(
version: &PythonVersion,
ld_version: &str,
_: bool,
) -> Result<String, String> {
// Py_ENABLE_SHARED doesn't seem to be present on windows.
Ok(format!(
"cargo:rustc-link-lib=pythonXY:{}",
get_library_link_name(&version, ld_version)
))
}
/// Parse string as interpreter version.
fn get_interpreter_version(line: &str) -> Result<PythonVersion, String> {
fn get_interpreter_version(line: &str, implementation: &str) -> Result<PythonVersion, String> {
let version_re = Regex::new(r"\((\d+), (\d+)\)").unwrap();
match version_re.captures(&line) {
Some(cap) => Ok(PythonVersion {
major: cap.get(1).unwrap().as_str().parse().unwrap(),
minor: Some(cap.get(2).unwrap().as_str().parse().unwrap()),
implementation: match implementation {
"CPython" => PythonInterpreterKind::CPython,
"PyPy" => PythonInterpreterKind::PyPy,
_ => panic!(format!(
"Unsupported python implementation `{}`",
implementation
)),
},
}),
None => Err(format!("Unexpected response to version query {}", line)),
}
}
#[cfg(target_os = "windows")]
fn get_rustc_link_lib(version: &PythonVersion, _: &str, _: bool) -> Result<String, String> {
// Py_ENABLE_SHARED doesn't seem to be present on windows.
Ok(format!(
"cargo:rustc-link-lib=pythonXY:python{}{}",
version.major,
match version.minor {
Some(minor) => minor.to_string(),
None => "".to_owned(),
}
))
}
/// Locate a suitable python interpreter and extract config from it.
///
/// The following locations are checked in the order listed:
@ -387,10 +442,17 @@ fn find_interpreter_and_get_config(
let expected_version = version.unwrap_or(PythonVersion {
major: 3,
minor: None,
implementation: PythonInterpreterKind::CPython,
});
let binary_name = match expected_version.implementation {
PythonInterpreterKind::CPython => "python",
PythonInterpreterKind::PyPy => "pypy",
};
// check default python
let interpreter_path = "python";
let interpreter_path = binary_name;
let (interpreter_version, lines) = get_config_from_interpreter(interpreter_path)?;
if expected_version == interpreter_version {
return Ok((
@ -430,20 +492,45 @@ fn get_config_from_interpreter(interpreter: &str) -> Result<(PythonVersion, Vec<
let script = r#"
import sys
import sysconfig
import platform
PYPY = platform.python_implementation() == "PyPy"
print(sys.version_info[0:2])
print(sysconfig.get_config_var('LIBDIR'))
print(sysconfig.get_config_var('Py_ENABLE_SHARED'))
if PYPY:
print("1")
else:
print(sysconfig.get_config_var('Py_ENABLE_SHARED'))
print(sysconfig.get_config_var('LDVERSION') or sysconfig.get_config_var('py_version_short'))
print(sys.exec_prefix)
print(platform.python_implementation())
"#;
let out = run_python_script(interpreter, script)?;
let lines: Vec<String> = out.lines().map(|line| line.to_owned()).collect();
let interpreter_version = get_interpreter_version(&lines[0])?;
let interpreter_version = get_interpreter_version(&lines[0], &lines[5])?;
Ok((interpreter_version, lines))
}
fn ensure_python_version_is_supported(version: &PythonVersion) -> Result<(), String> {
match (&version.implementation, version.major, version.minor) {
(PythonInterpreterKind::PyPy, 2, _) => {
Err("PyPy cpyext bindings is only supported for Python3".to_string())
}
(_, 3, Some(minor)) if minor < PY3_MIN_MINOR => Err(format!(
"Python 3 required version is 3.{}, current version is 3.{}",
PY3_MIN_MINOR, minor
)),
_ => Ok(()),
}
}
fn configure(interpreter_version: &PythonVersion, lines: Vec<String>) -> Result<(String), String> {
ensure_python_version_is_supported(&interpreter_version).expect(&format!(
"Unsupported interpreter {:?}",
interpreter_version
));
let libpath: &str = &lines[1];
let enable_shared: &str = &lines[2];
let ld_version: &str = &lines[3];
@ -464,26 +551,28 @@ fn configure(interpreter_version: &PythonVersion, lines: Vec<String>) -> Result<
let mut flags = String::new();
if interpreter_version.implementation == PythonInterpreterKind::PyPy {
println!("cargo:rustc-cfg=PyPy");
flags += format!("CFG_PyPy").as_ref();
};
if let PythonVersion {
major: 3,
minor: some_minor,
implementation: _,
} = interpreter_version
{
if env::var_os("CARGO_FEATURE_ABI3").is_some() {
println!("cargo:rustc-cfg=Py_LIMITED_API");
}
if let Some(minor) = some_minor {
if minor < &PY3_MIN_MINOR {
return Err(format!(
"Python 3 required version is 3.{}, current version is 3.{}",
PY3_MIN_MINOR, minor
));
}
for i in 5..(minor + 1) {
println!("cargo:rustc-cfg=Py_3_{}", i);
flags += format!("CFG_Py_3_{},", i).as_ref();
}
}
println!("cargo:rustc-cfg=Py_3");
} else {
// fail PYTHON_SYS_EXECUTABLE=python2 cargo ...
return Err("Python 2 is not supported".to_string());
@ -512,6 +601,7 @@ fn version_from_env() -> Option<PythonVersion> {
Some(s) => Some(s.as_str().parse().unwrap()),
None => None,
},
implementation: PythonInterpreterKind::CPython,
});
}
None => (),
@ -589,6 +679,15 @@ fn main() -> Result<(), String> {
}
}
// These flags need to be enabled manually for PyPy, because it does not expose
// them in `sysconfig.get_config_vars()`
if interpreter_version.implementation == PythonInterpreterKind::PyPy {
config_map.insert("WITH_THREAD".to_owned(), "1".to_owned());
config_map.insert("Py_USING_UNICODE".to_owned(), "1".to_owned());
config_map.insert("Py_UNICODE_SIZE".to_owned(), "4".to_owned());
config_map.insert("Py_UNICODE_WIDE".to_owned(), "1".to_owned());
}
// WITH_THREAD is always on for 3.7
if interpreter_version.major == 3 && interpreter_version.minor.unwrap_or(0) >= 7 {
config_map.insert("WITH_THREAD".to_owned(), "1".to_owned());

View File

@ -1,7 +1,13 @@
#!/bin/sh
#!/bin/bash
set -ex
### PyPy does not run the test suite ###########################################
if [[ $FEATURES == *"pypy"* ]]; then
exit 0
fi
### Run kcov ###################################################################
rm -f target/debug/pyo3*.d

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
set -ex

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
set -e
@ -11,9 +11,28 @@ if [ "$TRAVIS_JOB_NAME" = "Minimum nightly" ]; then
rustup component add rustfmt
fi
### Setup PyPy ################################################################
if [[ $FEATURES == *"pypy"* ]]; then
wget --quiet https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
/bin/bash Miniconda3-latest-Linux-x86_64.sh -f -b -p /opt/anaconda && \
/opt/anaconda/bin/conda install --quiet --yes conda && \
/opt/anaconda/bin/conda config --system --add channels conda-forge && \
/opt/anaconda/bin/conda init bash && \
/opt/anaconda/bin/conda create -n pypy3 pypy3.5 -y && \
/opt/anaconda/envs/pypy3/bin/pypy3 -m ensurepip && \
/opt/anaconda/envs/pypy3/bin/pypy3 -m pip install setuptools-rust pytest pytest-benchmark tox
fi
### Setup python linker flags ##################################################
PYTHON_LIB=$(python -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")
if [[ $FEATURES == *"pypy"* ]]; then
PYTHON_BINARY="pypy3"
else
PYTHON_BINARY="python"
fi
PYTHON_LIB=$($PYTHON_BINARY -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PYTHON_LIB:$HOME/rust/lib"

View File

@ -2,13 +2,25 @@
set -ex
cargo clean
cargo test --features "$FEATURES num-complex"
( cd pyo3-derive-backend; cargo test )
# run `cargo test` only if testing against cpython.
if ! [[ $FEATURES == *"pypy"* ]]; then
cargo test --features "$FEATURES num-complex"
( cd pyo3-derive-backend; cargo test )
else
# check that pypy at least builds
PYTHON_SYS_EXECUTABLE="/opt/anaconda/envs/pypy3/bin/pypy3" cargo build;
fi
if [ "$TRAVIS_JOB_NAME" = "Minimum nightly" ]; then
cargo fmt --all -- --check
cargo clippy --features "$FEATURES num-complex"
fi
for example_dir in examples/*; do
if [[ $FEATURES == *"pypy"* ]]; then
tox -c "$example_dir/tox.ini" -e pypy3
else
tox -c "$example_dir/tox.ini" -e py
fi
done

View File

@ -1,4 +1,5 @@
import sys
import platform
from setuptools import setup
from setuptools.command.test import test as TestCommand
@ -25,6 +26,9 @@ def get_py_version_cfgs():
for minor in range(py3_min, version[1] + 1):
out_cfg.append("--cfg=Py_3_%d" % minor)
if platform.python_implementation() == "PyPy":
out_cfg.append("--cfg=PyPy")
return out_cfg

View File

@ -229,7 +229,7 @@ fn datetime(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
}
m.add_wrapped(wrap_pyfunction!(issue_219))?;
m.add_class::<TzClass>()?;
Ok(())
}

View File

@ -32,6 +32,7 @@ fn double(x: i32) -> i32 {
#[pymodule]
fn othermod(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(double))?;
m.add_class::<ModClass>()?;
m.add("USIZE_MIN", usize::min_value())?;

View File

@ -1,5 +1,6 @@
import datetime as pdt
import sys
import platform
import pytest
import rustapi_module.datetime as rdt
@ -44,6 +45,8 @@ except Exception:
MAX_MICROSECONDS = int(pdt.timedelta.max.total_seconds() * 1e6)
MIN_MICROSECONDS = int(pdt.timedelta.min.total_seconds() * 1e6)
PYPY = platform.python_implementation() == "PyPy"
HAS_FOLD = getattr(pdt.datetime, "fold", False)
# Helper functions
@ -80,8 +83,11 @@ def test_invalid_date_fails():
rdt.make_date(2017, 2, 30)
@given(d=dates())
@given(d=st.dates())
def test_date_from_timestamp(d):
if PYPY and d < pdt.date(1900, 1, 1):
pytest.xfail("get_timestamp will raise on PyPy with dates before 1900")
ts = get_timestamp(pdt.datetime.combine(d, pdt.time(0)))
assert rdt.date_from_timestamp(int(ts)) == pdt.date.fromtimestamp(ts)
@ -216,8 +222,11 @@ def test_datetime_typeerror():
rdt.make_datetime("2011", 1, 1, 0, 0, 0, 0)
@given(dt=datetimes())
@given(dt=st.datetimes())
def test_datetime_from_timestamp(dt):
if PYPY and dt < pdt.datetime(1900, 1, 1):
pytest.xfail("get_timestamp will raise on PyPy with dates before 1900")
ts = get_timestamp(dt)
assert rdt.datetime_from_timestamp(ts) == pdt.datetime.fromtimestamp(ts)

View File

@ -1,6 +1,5 @@
from rustapi_module.test_dict import DictSize
import pytest
from rustapi_module.test_dict import DictSize
@pytest.mark.parametrize(
"size",

View File

@ -1,5 +1,6 @@
from hypothesis import given, assume
from hypothesis import strategies as st
from rustapi_module import othermod
INTEGER32_ST = st.integers(min_value=(-(2 ** 31)), max_value=(2 ** 31 - 1))

View File

@ -1,9 +1,13 @@
import platform
from rustapi_module.subclassing import Subclassable
PYPY = platform.python_implementation() == 'PyPy'
class SomeSubClass(Subclassable):
pass
a = SomeSubClass()
_b = str(a) + repr(a)
if not PYPY:
a = SomeSubClass()
_b = str(a) + repr(a)

View File

@ -2,6 +2,7 @@
envlist = py35,
py36,
py37,
pypy35
minversion = 2.9.0
skip_missing_interpreters = true

View File

@ -2,6 +2,7 @@
envlist = py35,
py36,
py37,
pypy35
minversion = 3.4.0
skip_missing_interpreters = true

View File

@ -10,4 +10,5 @@
- [Debugging](debugging.md)
- [Advanced Topics](advanced.md)
- [Building and Distribution](building-and-distribution.md)
- [PyPy support](pypy.md)
- [Appendix: Pyo3 and rust-cpython](rust-cpython.md)

21
guide/src/pypy.md Normal file
View File

@ -0,0 +1,21 @@
# PyPy Support
Using PyPy is supported via cpyext.
Support is only provided for building rust extension for code running under PyPy. This means PyPy **cannot** be called from rust via cpyext. Note that there some differences in the ffi module between pypy and cpython.
This is a limitation of cpyext and supported for embedding cpyext is not planned.
Compilation against PyPy is done by exporting the `PYTHON_SYS_EXECUTABLE` to a pypy binary or by compiling in a PyPy virtualenv.
For example, `PYTHON_SYS_EXECUTABLE="/path/to/pypy3" /path/to/pypy3 setup.py install`
## Unsupported Features
These are features currently supported by PyO3, but not yet implemented in cpyext.
- Complex number functions (`_Py_c_sum`, `_Py_c_sum` ..)
- Conversion to rust's i128, u128 types.
- `PySequence_Count` (which is used to count number of element in array)
- `PyDict_MergeFromSeq2` (used in `PyDict::from_sequence`)

View File

@ -5,16 +5,21 @@
//! 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.
//!
//! A note regarding PyPy (cpyext) support:
//!
//! Support for `PyDateTime_CAPI` is limited as of PyPy 7.0.0.
//! `DateTime_FromTimestamp` and `Date_FromTimestamp` are currently not supported.
use crate::ffi::PyCapsule_Import;
use crate::ffi::Py_hash_t;
use crate::ffi::{PyObject, PyTypeObject};
use crate::ffi::{PyObject_TypeCheck, Py_TYPE};
use std::ffi::CString;
use std::ops::Deref;
use std::os::raw::{c_char, c_int, c_uchar};
use std::ptr;
use std::sync::Once;
#[cfg(not(PyPy))]
use {crate::ffi::PyCapsule_Import, std::ffi::CString};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@ -26,13 +31,14 @@ pub struct PyDateTime_CAPI {
pub TZInfoType: *mut PyTypeObject,
#[cfg(Py_3_7)]
pub TimeZone_UTC: *mut PyObject,
#[cfg_attr(PyPy, link_name = "_PyPyDate_FromDate")]
pub Date_FromDate: unsafe extern "C" fn(
year: c_int,
month: c_int,
day: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
#[cfg_attr(PyPy, link_name = "_PyPyDateTime_FromDateAndTime")]
pub DateTime_FromDateAndTime: unsafe extern "C" fn(
year: c_int,
month: c_int,
@ -44,6 +50,7 @@ pub struct PyDateTime_CAPI {
tzinfo: *mut PyObject,
cls: *mut PyTypeObject,
) -> *mut PyObject,
#[cfg_attr(PyPy, link_name = "_PyPyTime_FromTime")]
pub Time_FromTime: unsafe extern "C" fn(
hour: c_int,
minute: c_int,
@ -52,6 +59,7 @@ pub struct PyDateTime_CAPI {
tzinfo: *mut PyObject,
cls: *mut PyTypeObject,
) -> *mut PyObject,
#[cfg_attr(PyPy, link_name = "_PyPyDelta_FromDelta")]
pub Delta_FromDelta: unsafe extern "C" fn(
days: c_int,
seconds: c_int,
@ -62,11 +70,14 @@ pub struct PyDateTime_CAPI {
#[cfg(Py_3_7)]
pub TimeZone_FromTimeZone:
unsafe extern "C" fn(offset: *mut PyObject, name: *mut PyObject) -> *mut PyObject,
// Defined for PyPy as `PyDateTime_FromTimestamp`
pub DateTime_FromTimestamp: unsafe extern "C" fn(
cls: *mut PyTypeObject,
args: *mut PyObject,
kwargs: *mut PyObject,
) -> *mut PyObject,
// Defined for PyPy as `PyDate_FromTimestamp`
pub Date_FromTimestamp:
unsafe extern "C" fn(cls: *mut PyTypeObject, args: *mut PyObject) -> *mut PyObject,
#[cfg(Py_3_6)]
@ -94,8 +105,46 @@ pub struct PyDateTime_CAPI {
) -> *mut PyObject,
}
// Type struct wrappers
#[cfg(PyPy)]
extern "C" {
#[link_name = "_PyPyDateTime_Import"]
pub fn PyDateTime_Import() -> &'static PyDateTime_CAPI;
#[link_name = "PyPyDateTime_DATE_GET_HOUR"]
pub fn PyDateTime_DATE_GET_HOUR(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_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_DELTA_GET_DAYS"]
pub fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DELTA_GET_MICROSECONDS"]
pub fn PyDateTime_DELTA_GET_MICROSECONDS(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_GET_DAY"]
pub fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_GET_MONTH"]
pub fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_GET_YEAR"]
pub fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_HOUR"]
pub fn PyDateTime_TIME_GET_HOUR(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_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 = "PyPyDate_FromTimestamp"]
pub fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject;
#[link_name = "PyPyDateTime_FromTimestamp"]
pub fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject;
}
// Type struct wrappers
const _PyDateTime_DATE_DATASIZE: usize = 4;
const _PyDateTime_TIME_DATASIZE: usize = 6;
const _PyDateTime_DATETIME_DATASIZE: usize = 10;
@ -171,9 +220,11 @@ pub struct PyDateTime_Delta {
static PY_DATETIME_API_ONCE: Once = Once::new();
static mut PY_DATETIME_API_UNSAFE_CACHE: *const PyDateTime_CAPI = ptr::null();
#[derive(Debug)]
pub struct PyDateTimeAPI {
__private_field: (),
}
pub static PyDateTimeAPI: PyDateTimeAPI = PyDateTimeAPI {
__private_field: (),
};
@ -201,13 +252,21 @@ impl Deref for PyDateTimeAPI {
/// such as if you do not want the first call to a datetime function to be
/// slightly slower than subsequent calls.
pub unsafe fn PyDateTime_IMPORT() -> &'static PyDateTime_CAPI {
// 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 = {
// PyDateTime_CAPSULE_NAME is a macro in C
let PyDateTime_CAPSULE_NAME = CString::new("datetime.datetime_CAPI").unwrap();
let capsule = PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *const PyDateTime_CAPI;
PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *const PyDateTime_CAPI
};
PY_DATETIME_API_ONCE.call_once(move || {
PY_DATETIME_API_UNSAFE_CACHE = capsule;
PY_DATETIME_API_UNSAFE_CACHE = py_datetime_c_api;
});
&(*PY_DATETIME_API_UNSAFE_CACHE)
@ -279,7 +338,7 @@ pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int {
}
/// Accessor functions
///
#[cfg(not(PyPy))]
macro_rules! _access_field {
($obj:expr, $type: ident, $field:tt) => {
(*($obj as *mut $type)).$field
@ -288,6 +347,7 @@ macro_rules! _access_field {
// Accessor functions for PyDateTime_Date and PyDateTime_DateTime
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -297,6 +357,7 @@ pub unsafe fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -305,6 +366,7 @@ pub unsafe fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -313,24 +375,28 @@ pub unsafe fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int {
}
// Accessor macros for times
#[cfg(not(PyPy))]
macro_rules! _PyDateTime_GET_HOUR {
($o: expr, $offset:expr) => {
c_int::from((*$o).data[$offset + 0])
};
}
#[cfg(not(PyPy))]
macro_rules! _PyDateTime_GET_MINUTE {
($o: expr, $offset:expr) => {
c_int::from((*$o).data[$offset + 1])
};
}
#[cfg(not(PyPy))]
macro_rules! _PyDateTime_GET_SECOND {
($o: expr, $offset:expr) => {
c_int::from((*$o).data[$offset + 2])
};
}
#[cfg(not(PyPy))]
macro_rules! _PyDateTime_GET_MICROSECOND {
($o: expr, $offset:expr) => {
(c_int::from((*$o).data[$offset + 3]) << 16)
@ -340,12 +406,14 @@ macro_rules! _PyDateTime_GET_MICROSECOND {
}
#[cfg(Py_3_6)]
#[cfg(not(PyPy))]
macro_rules! _PyDateTime_GET_FOLD {
($o: expr) => {
(*$o).fold
};
}
#[cfg(not(PyPy))]
macro_rules! _PyDateTime_GET_TZINFO {
($o: expr) => {
(*$o).tzinfo
@ -354,6 +422,7 @@ macro_rules! _PyDateTime_GET_TZINFO {
// Accessor functions for DateTime
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -361,6 +430,7 @@ pub unsafe fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -368,6 +438,7 @@ pub unsafe fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -375,6 +446,7 @@ pub unsafe fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -383,6 +455,7 @@ pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int {
#[cfg(Py_3_6)]
#[inline]
#[cfg(not(PyPy))]
/// Retrieve the fold component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 1]`
///
@ -392,6 +465,7 @@ pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_uchar {
}
#[inline]
#[cfg(not(PyPy))]
/// 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.
@ -401,6 +475,7 @@ pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
// Accessor functions for Time
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -408,6 +483,7 @@ pub unsafe fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -415,6 +491,7 @@ pub unsafe fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// 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 {
@ -422,13 +499,14 @@ pub unsafe fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// 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(Py_3_6)]
#[cfg(all(Py_3_6, not(PyPy)))]
#[inline]
/// Retrieve the fold component of a `PyDateTime_Time`.
/// Returns a signed integer in the interval `[0, 1]`
@ -439,6 +517,7 @@ pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar {
}
#[inline]
#[cfg(not(PyPy))]
/// 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.
@ -447,6 +526,7 @@ pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
}
// Accessor functions for PyDateTime_Delta
#[cfg(not(PyPy))]
macro_rules! _access_delta_field {
($obj:expr, $field:tt) => {
_access_field!($obj, PyDateTime_Delta, $field)
@ -454,6 +534,7 @@ macro_rules! _access_delta_field {
}
#[inline]
#[cfg(not(PyPy))]
/// Retrieve the days component of a `PyDateTime_Delta`.
///
/// Returns a signed integer in the interval [-999999999, 999999999].
@ -465,6 +546,7 @@ pub unsafe fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// Retrieve the seconds component of a `PyDateTime_Delta`.
///
/// Returns a signed integer in the interval [0, 86399].
@ -476,6 +558,7 @@ pub unsafe fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
/// Retrieve the seconds component of a `PyDateTime_Delta`.
///
/// Returns a signed integer in the interval [0, 999999].

View File

@ -4,13 +4,18 @@ use std::os::raw::{c_int, c_long};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyBool_Type")]
pub static mut PyBool_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "_PyPy_FalseStruct")]
static mut _Py_FalseStruct: PyLongObject;
#[cfg_attr(PyPy, link_name = "_PyPy_TrueStruct")]
static mut _Py_TrueStruct: PyLongObject;
#[cfg_attr(PyPy, link_name = "PyPyBool_FromLong")]
pub fn PyBool_FromLong(arg1: c_long) -> *mut PyObject;
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyBool_Check")]
pub unsafe fn PyBool_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyBool_Type) as c_int
}

View File

@ -4,7 +4,9 @@ use std::os::raw::{c_char, c_int};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyByteArray_Type")]
pub static mut PyByteArray_Type: PyTypeObject;
pub static mut PyByteArrayIter_Type: PyTypeObject;
}
@ -20,10 +22,16 @@ pub unsafe fn PyByteArray_CheckExact(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
}

View File

@ -4,6 +4,7 @@ use std::os::raw::{c_char, c_int};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyBytes_Type")]
pub static mut PyBytes_Type: PyTypeObject;
pub static mut PyBytesIter_Type: PyTypeObject;
}
@ -20,16 +21,24 @@ pub unsafe fn PyBytes_CheckExact(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
#[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,
@ -38,6 +47,7 @@ extern "C" {
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,

View File

@ -6,6 +6,7 @@ use std::os::raw::{c_char, c_int, c_void};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyEval_CallObjectWithKeywords")]
pub fn PyEval_CallObjectWithKeywords(
func: *mut PyObject,
obj: *mut PyObject,
@ -20,30 +21,38 @@ pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyEval_CallFunction")]
pub fn PyEval_CallFunction(obj: *mut PyObject, format: *const c_char, ...) -> *mut PyObject;
#[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;
pub fn PyEval_GetFrame() -> *mut crate::ffi3::PyFrameObject;
#[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;
fn _Py_CheckRecursiveCall(_where: *mut c_char) -> c_int;
static mut _Py_CheckRecursionLimit: c_int;
}
// TODO: Py_EnterRecursiveCall etc.
#[cfg(Py_3_6)]
pub type _PyFrameEvalFunction =
extern "C" fn(*mut crate::ffi3::PyFrameObject, c_int) -> *mut PyObject;
@ -62,18 +71,24 @@ extern "C" {
#[cfg(Py_3_6)]
pub fn _PyEval_RequestCodeExtraIndex(func: FreeFunc) -> c_int;
pub fn PyEval_EvalFrameEx(f: *mut crate::ffi3::PyFrameObject, exc: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_SaveThread")]
pub fn PyEval_SaveThread() -> *mut PyThreadState;
#[cfg_attr(PyPy, link_name = "PyPyEval_RestoreThread")]
pub fn PyEval_RestoreThread(arg1: *mut PyThreadState) -> ();
}
#[cfg(py_sys_config = "WITH_THREAD")]
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyEval_ThreadsInitialized")]
pub fn PyEval_ThreadsInitialized() -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyEval_InitThreads")]
pub fn PyEval_InitThreads() -> ();
pub fn PyEval_AcquireLock() -> ();
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) -> ();
pub fn PyEval_ReInitThreads() -> ();
}

View File

@ -82,6 +82,7 @@ extern "C" {
#[cfg(Py_3_6)]
pub fn _PyCode_SetExtra(code: *mut PyObject, index: Py_ssize_t, extra: *mut c_void) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCode_New")]
pub fn PyCode_New(
arg1: c_int,
arg2: c_int,
@ -99,6 +100,7 @@ extern "C" {
arg14: c_int,
arg15: *mut PyObject,
) -> *mut PyCodeObject;
#[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")]
pub fn PyCode_NewEmpty(
filename: *const c_char,
funcname: *const c_char,
@ -114,11 +116,13 @@ extern "C" {
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyCode_Check")]
pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCode_Type) as c_int
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyCode_GetNumFree")]
pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t {
crate::ffi3::tupleobject::PyTuple_GET_SIZE((*op).co_freevars)
}

View File

@ -17,10 +17,12 @@ extern "C" {
) -> *mut PyObject;
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,

View File

@ -3,6 +3,7 @@ use std::os::raw::{c_double, c_int};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyComplex_Type")]
pub static mut PyComplex_Type: PyTypeObject;
}
@ -18,8 +19,11 @@ pub unsafe fn PyComplex_CheckExact(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
}
@ -49,6 +53,8 @@ extern "C" {
pub fn _Py_c_quot(dividend: Py_complex, divisor: Py_complex) -> Py_complex;
pub fn _Py_c_pow(num: Py_complex, exp: Py_complex) -> Py_complex;
pub fn _Py_c_abs(arg: Py_complex) -> c_double;
#[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;
}

View File

@ -1,7 +1,7 @@
use crate::ffi3::methodobject::PyMethodDef;
use crate::ffi3::object::{
PyObject, PyObject_GenericGetDict, PyObject_GenericSetDict, PyTypeObject,
};
use crate::ffi3::object::{PyObject, PyTypeObject};
#[cfg(not(PyPy))]
use crate::ffi3::object::{PyObject_GenericGetDict, PyObject_GenericSetDict};
use crate::ffi3::structmember::PyMemberDef;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;
@ -29,6 +29,11 @@ pub const PyGetSetDef_INIT: PyGetSetDef = PyGetSetDef {
closure: ptr::null_mut(),
};
#[cfg(PyPy)]
pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef_INIT;
// PyPy doesn't export neither PyObject_GenericGetDict/PyObject_GenericSetDict
#[cfg(not(PyPy))]
pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef {
name: "__dict__\0".as_ptr() as *mut c_char,
get: Some(PyObject_GenericGetDict),
@ -39,20 +44,29 @@ pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
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;
pub fn PyDescr_NewMember(arg1: *mut PyTypeObject, arg2: *mut PyMemberDef) -> *mut PyObject;
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;
#[cfg_attr(PyPy, link_name = "PyPyProperty_Type")]
pub static mut PyProperty_Type: PyTypeObject;
}

View File

@ -45,32 +45,49 @@ pub unsafe fn PyDictViewSet_Check(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
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;
}

View File

@ -3,6 +3,7 @@ use std::os::raw::c_int;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyEval_EvalCode")]
pub fn PyEval_EvalCode(
arg1: *mut PyObject,
arg2: *mut PyObject,

View File

@ -15,8 +15,11 @@ extern "C" {
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;
pub static mut Py_FileSystemDefaultEncoding: *const c_char;

View File

@ -10,6 +10,7 @@ pub struct PyFloatObject {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyFloat_Type")]
pub static mut PyFloat_Type: PyTypeObject;
}
@ -34,7 +35,10 @@ extern "C" {
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;
}

View File

@ -57,6 +57,7 @@ pub unsafe fn PyFrame_Check(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyFrame_New")]
pub fn PyFrame_New(
tstate: *mut PyThreadState,
code: *mut PyCodeObject,

View File

@ -5,7 +5,9 @@ use std::os::raw::{c_char, c_int, c_long};
extern "C" {
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,
@ -23,11 +25,16 @@ extern "C" {
pathname: *mut PyObject,
cpathname: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyImport_GetModuleDict")]
pub fn PyImport_GetModuleDict() -> *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_attr(PyPy, link_name = "PyPyImport_ImportModule")]
pub fn PyImport_ImportModule(name: *const c_char) -> *mut PyObject;
#[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,
@ -35,6 +42,7 @@ extern "C" {
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,
@ -58,6 +66,7 @@ pub unsafe fn PyImport_ImportModuleEx(
extern "C" {
pub fn PyImport_GetImporter(path: *mut PyObject) -> *mut PyObject;
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;
pub fn PyImport_Cleanup() -> ();
pub fn PyImport_ImportFrozenModuleObject(name: *mut PyObject) -> c_int;

View File

@ -2,7 +2,9 @@ use std::os::raw::c_int;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyOS_InterruptOccurred")]
pub fn PyOS_InterruptOccurred() -> c_int;
pub fn PyOS_InitInterrupts() -> ();
#[cfg_attr(PyPy, link_name = "PyPyOS_AfterFork")]
pub fn PyOS_AfterFork() -> ();
}

View File

@ -6,7 +6,9 @@ extern "C" {
pub static mut PySeqIter_Type: PyTypeObject;
pub static mut PyCallIter_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPySeqIter_New")]
pub fn PySeqIter_New(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyCallIter_New")]
pub fn PyCallIter_New(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
}

View File

@ -18,6 +18,7 @@ pub struct PyListObject {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
@ -55,24 +56,35 @@ pub unsafe fn PyList_SET_ITEM(op: *mut PyObject, i: Py_ssize_t, v: *mut PyObject
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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_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_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;
}

View File

@ -11,6 +11,7 @@ pub struct PyLongObject(*mut c_void);
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyLong_Type")]
pub static mut PyLong_Type: PyTypeObject;
}
@ -26,27 +27,48 @@ pub unsafe fn PyLong_CheckExact(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
pub fn PyLong_GetInfo() -> *mut PyObject;
#[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,
@ -59,6 +81,7 @@ extern "C" {
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "_PyPyLong_FromByteArray")]
pub fn _PyLong_FromByteArray(
bytes: *const c_uchar,
n: size_t,

View File

@ -4,6 +4,7 @@ use std::os::raw::{c_char, c_int};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyMemoryView_Type")]
pub static mut PyMemoryView_Type: PyTypeObject;
}
@ -14,7 +15,9 @@ pub unsafe fn PyMemoryView_Check(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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,

View File

@ -4,9 +4,9 @@ use std::{mem, ptr};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyCFunction_Type")]
pub static mut PyCFunction_Type: PyTypeObject;
}
#[inline]
pub unsafe fn PyCFunction_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyCFunction_Type) as c_int
@ -33,6 +33,7 @@ pub type PyNoArgsFunction = unsafe extern "C" fn(slf: *mut PyObject) -> *mut PyO
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
@ -67,11 +68,13 @@ impl Default for PyMethodDef {
#[inline]
pub unsafe fn PyCFunction_New(ml: *mut PyMethodDef, slf: *mut PyObject) -> *mut PyObject {
#[cfg_attr(PyPy, link_name = "PyPyCFunction_NewEx")]
PyCFunction_NewEx(ml, slf, ptr::null_mut())
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyCFunction_NewEx")]
pub fn PyCFunction_NewEx(
arg1: *mut PyMethodDef,
arg2: *mut PyObject,

View File

@ -6,8 +6,11 @@ use std::os::raw::{c_char, c_int, c_long};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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,
@ -16,6 +19,7 @@ extern "C" {
...
) -> c_int;
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,
@ -23,18 +27,24 @@ extern "C" {
arg4: Py_ssize_t,
...
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPy_BuildValue")]
pub fn Py_BuildValue(arg1: *const c_char, ...) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "_PyPy_BuildValue_SizeT")]
//pub fn _Py_BuildValue_SizeT(arg1: *const c_char, ...)
// -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPy_VaBuildValue")]
//pub fn Py_VaBuildValue(arg1: *const c_char, arg2: va_list)
// -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyModule_AddObject")]
pub fn PyModule_AddObject(
arg1: *mut PyObject,
arg2: *const c_char,
arg3: *mut PyObject,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyModule_AddIntConstant")]
pub fn PyModule_AddIntConstant(arg1: *mut PyObject, arg2: *const c_char, arg3: c_long)
-> c_int;
#[cfg_attr(PyPy, link_name = "PyPyModule_AddStringConstant")]
pub fn PyModule_AddStringConstant(
arg1: *mut PyObject,
arg2: *const c_char,
@ -53,6 +63,7 @@ pub const PYTHON_ABI_VERSION: i32 = 3;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg(not(py_sys_config = "Py_TRACE_REFS"))]
#[cfg_attr(PyPy, link_name = "PyPyModule_Create2")]
pub fn PyModule_Create2(module: *mut PyModuleDef, apiver: c_int) -> *mut PyObject;
#[cfg(py_sys_config = "Py_TRACE_REFS")]

View File

@ -5,6 +5,7 @@ use std::os::raw::{c_char, c_int, c_void};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyModule_Type")]
pub static mut PyModule_Type: PyTypeObject;
}
@ -21,14 +22,19 @@ pub unsafe fn PyModule_CheckExact(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
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;
pub fn PyModule_GetNameObject(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyModule_GetName(arg1: *mut PyObject) -> *const c_char;
pub fn PyModule_GetFilename(arg1: *mut PyObject) -> *const c_char;
pub fn PyModule_GetFilenameObject(arg1: *mut PyObject) -> *mut PyObject;
#[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;
pub static mut PyModuleDef_Type: PyTypeObject;
}

View File

@ -1,10 +1,13 @@
use crate::ffi3::pyport::{Py_hash_t, Py_ssize_t};
#[cfg(PyPy)]
use std::ffi::CStr;
use std::mem;
use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void};
use std::ptr;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg(not(PyPy))]
pub struct PyObject {
#[cfg(py_sys_config = "Py_TRACE_REFS")]
_ob_next: *mut PyObject,
@ -14,7 +17,17 @@ pub struct PyObject {
pub ob_type: *mut PyTypeObject,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[cfg(PyPy)]
pub struct PyObject {
pub ob_refcnt: Py_ssize_t,
pub ob_pypy_link: Py_ssize_t,
pub ob_type: *mut PyTypeObject,
}
#[cfg(py_sys_config = "Py_TRACE_REFS")]
#[cfg(not(PyPy))]
pub const PyObject_HEAD_INIT: PyObject = PyObject {
_ob_next: ::std::ptr::null_mut(),
_ob_prev: ::std::ptr::null_mut(),
@ -23,9 +36,28 @@ pub const PyObject_HEAD_INIT: PyObject = PyObject {
};
#[cfg(not(py_sys_config = "Py_TRACE_REFS"))]
#[cfg(not(PyPy))]
pub const PyObject_HEAD_INIT: PyObject = PyObject {
ob_refcnt: 1,
ob_type: ptr::null_mut(),
ob_type: ::std::ptr::null_mut(),
};
#[cfg(py_sys_config = "Py_TRACE_REFS")]
#[cfg(PyPy)]
pub const PyObject_HEAD_INIT: PyObject = PyObject {
_ob_next: ::std::ptr::null_mut(),
_ob_prev: ::std::ptr::null_mut(),
ob_refcnt: 1,
ob_pypy_link: 0,
ob_type: ::std::ptr::null_mut(),
};
#[cfg(not(py_sys_config = "Py_TRACE_REFS"))]
#[cfg(PyPy)]
pub const PyObject_HEAD_INIT: PyObject = PyObject {
ob_refcnt: 1,
ob_pypy_link: 0,
ob_type: ::std::ptr::null_mut(),
};
#[repr(C)]
@ -43,6 +75,17 @@ pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t {
(*ob).ob_refcnt
}
#[cfg(PyPy)]
pub unsafe fn _PyObject_NextNotImplemented(arg1: *mut PyObject) -> *mut PyObject {
return crate::ffi3::pyerrors::PyErr_Format(
crate::ffi3::pyerrors::PyExc_TypeError,
CStr::from_bytes_with_nul(b"'%.200s' object is not iterable\0")
.unwrap()
.as_ptr(),
Py_TYPE((*(arg1 as *mut PyTypeObject)).tp_name as *mut PyObject),
);
}
#[inline]
pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject {
(*ob).ob_type
@ -406,6 +449,15 @@ mod typeobject {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct PyTypeObject {
#[cfg(PyPy)]
pub ob_refcnt: Py_ssize_t,
#[cfg(PyPy)]
pub ob_pypy_link: Py_ssize_t,
#[cfg(PyPy)]
pub ob_type: *mut PyTypeObject,
#[cfg(PyPy)]
pub ob_size: Py_ssize_t,
#[cfg(not(PyPy))]
pub ob_base: object::PyVarObject,
pub tp_name: *const c_char,
pub tp_basicsize: Py_ssize_t,
@ -454,6 +506,8 @@ mod typeobject {
pub tp_del: Option<ffi3::object::destructor>,
pub tp_version_tag: c_uint,
pub tp_finalize: Option<ffi3::object::destructor>,
#[cfg(PyPy)]
pub tp_pypy_flags: ::std::os::raw::c_long,
#[cfg(py_sys_config = "COUNT_ALLOCS")]
pub tp_allocs: Py_ssize_t,
#[cfg(py_sys_config = "COUNT_ALLOCS")]
@ -466,14 +520,11 @@ mod typeobject {
pub tp_next: *mut PyTypeObject,
}
macro_rules! py_type_object_init {
($tp_as_async:ident, $($tail:tt)*) => {
macro_rules! _type_object_init {
({$($head:tt)*} $tp_as_async:ident, $($tail:tt)*) => {
as_expr! {
PyTypeObject {
ob_base: ffi3::object::PyVarObject {
ob_base: ffi3::object::PyObject_HEAD_INIT,
ob_size: 0
},
$($head)*
tp_name: ptr::null(),
tp_basicsize: 0,
tp_itemsize: 0,
@ -526,6 +577,36 @@ mod typeobject {
}
}
#[cfg(PyPy)]
macro_rules! py_type_object_init {
($tp_as_async:ident, $($tail:tt)*) => {
_type_object_init!({
ob_refcnt: 1,
ob_pypy_link: 0,
ob_type: ptr::null_mut(),
ob_size: 0,
}
$tp_as_async,
tp_pypy_flags: 0,
$($tail)*
)
}
}
#[cfg(not(PyPy))]
macro_rules! py_type_object_init {
($tp_as_async:ident, $($tail:tt)*) => {
_type_object_init!({
ob_base: ffi3::object::PyVarObject {
ob_base: ffi3::object::PyObject_HEAD_INIT,
ob_size: 0
},}
$tp_as_async,
$($tail)*
)
}
}
#[cfg(py_sys_config = "COUNT_ALLOCS")]
macro_rules! py_type_object_init_with_count_allocs {
($tp_as_async:ident, $($tail:tt)*) => {
@ -616,8 +697,10 @@ impl Default for PyType_Spec {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
pub fn PyType_GetSlot(arg1: *mut PyTypeObject, arg2: c_int) -> *mut c_void;
@ -625,6 +708,7 @@ extern "C" {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyType_IsSubtype")]
pub fn PyType_IsSubtype(a: *mut PyTypeObject, b: *mut PyTypeObject) -> c_int;
}
@ -636,8 +720,10 @@ pub unsafe fn PyObject_TypeCheck(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
/// built-in 'type'
#[cfg_attr(PyPy, link_name = "PyPyType_Type")]
pub static mut PyType_Type: PyTypeObject;
/// built-in 'object'
#[cfg_attr(PyPy, link_name = "PyPyBaseObject_Type")]
pub static mut PyBaseObject_Type: PyTypeObject;
/// built-in 'super'
pub static mut PySuper_Type: PyTypeObject;
@ -657,46 +743,66 @@ pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyObject_Print")]
pub fn PyObject_Print(o: *mut PyObject, fp: *mut ::libc::FILE, flags: c_int) -> c_int;
#[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_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_attr(PyPy, link_name = "PyPyObject_SetAttr")]
pub fn PyObject_SetAttr(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject)
-> c_int;
pub fn PyObject_HasAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_SelfIter")]
pub fn PyObject_SelfIter(arg1: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
pub fn _PyObject_NextNotImplemented(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,
@ -708,17 +814,25 @@ extern "C" {
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(not(Py_LIMITED_API))]
pub fn PyObject_CallFinalizer(arg1: *mut PyObject) -> ();
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyObject_CallFinalizerFromDealloc")]
pub fn PyObject_CallFinalizerFromDealloc(arg1: *mut PyObject) -> c_int;
#[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) -> ();
@ -785,6 +899,7 @@ pub unsafe fn PyType_FastSubclass(t: *mut PyTypeObject, f: c_ulong) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "_PyPy_Dealloc")]
pub fn _Py_Dealloc(arg1: *mut PyObject) -> ();
}
@ -835,10 +950,14 @@ pub unsafe fn Py_XDECREF(op: *mut PyObject) {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPy_IncRef")]
pub fn Py_IncRef(o: *mut PyObject);
#[cfg_attr(PyPy, link_name = "PyPy_DecRef")]
pub fn Py_DecRef(o: *mut PyObject);
#[cfg_attr(PyPy, link_name = "_PyPy_NoneStruct")]
static mut _Py_NoneStruct: PyObject;
#[cfg_attr(PyPy, link_name = "_PyPy_NotImplementedStruct")]
static mut _Py_NotImplementedStruct: PyObject;
}

View File

@ -4,7 +4,9 @@ use std::os::raw::{c_char, c_int, c_void};
use std::ptr;
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyObject_DelAttrString")]
pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) -> c_int {
#[cfg_attr(PyPy, link_name = "PyPyObject_SetAttr")]
PyObject_SetAttrString(o, attr_name, ptr::null_mut())
}
@ -15,20 +17,24 @@ pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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,
@ -36,13 +42,17 @@ extern "C" {
...
) -> *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_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;
}
@ -54,23 +64,30 @@ pub unsafe fn PyObject_Length(o: *mut PyObject) -> Py_ssize_t {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyObject_LengthHint")]
pub fn PyObject_LengthHint(o: *mut PyObject, arg1: Py_ssize_t) -> 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;
pub fn PyObject_DelItemString(o: *mut PyObject, key: *const c_char) -> c_int;
pub fn PyObject_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_AsCharBuffer")]
pub fn PyObject_AsCharBuffer(
obj: *mut PyObject,
buffer: *mut *const c_char,
buffer_len: *mut Py_ssize_t,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_CheckReadBuffer")]
pub fn PyObject_CheckReadBuffer(obj: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_AsReadBuffer")]
pub fn PyObject_AsReadBuffer(
obj: *mut PyObject,
buffer: *mut *const c_void,
buffer_len: *mut Py_ssize_t,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_AsWriteBuffer")]
pub fn PyObject_AsWriteBuffer(
obj: *mut PyObject,
buffer: *mut *mut c_void,
@ -88,14 +105,18 @@ pub unsafe fn PyObject_CheckBuffer(o: *mut PyObject) -> c_int {
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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 c_void;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_ToContiguous")]
pub fn PyBuffer_ToContiguous(
buf: *mut 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 c_void,
@ -103,6 +124,7 @@ extern "C" {
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,
@ -111,6 +133,7 @@ extern "C" {
itemsize: c_int,
fort: c_char,
) -> ();
#[cfg_attr(PyPy, link_name = "PyPyBuffer_FillInfo")]
pub fn PyBuffer_FillInfo(
view: *mut Py_buffer,
o: *mut PyObject,
@ -119,17 +142,21 @@ extern "C" {
readonly: c_int,
flags: c_int,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyBuffer_Release")]
pub fn PyBuffer_Release(view: *mut Py_buffer) -> ();
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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(not(Py_LIMITED_API))]
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyIter_Check")]
pub unsafe fn PyIter_Check(o: *mut PyObject) -> c_int {
(match (*(*o).ob_type).tp_iternext {
Some(tp_iternext) => {
@ -142,32 +169,53 @@ pub unsafe fn PyIter_Check(o: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyIter_Next")]
pub fn PyIter_Next(arg1: *mut PyObject) -> *mut PyObject;
#[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(not(Py_LIMITED_API))]
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyIndex_Check")]
pub unsafe fn PyIndex_Check(o: *mut PyObject) -> c_int {
let tp_as_number = (*(*o).ob_type).tp_as_number;
(!tp_as_number.is_null() && (*tp_as_number).nb_index.is_some()) as c_int
@ -175,58 +223,90 @@ pub unsafe fn PyIndex_Check(o: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPySequence_Length")]
pub unsafe fn PySequence_Length(o: *mut PyObject) -> Py_ssize_t {
PySequence_Size(o)
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
// TODO: PySequence_Fast macros
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;
}
@ -237,14 +317,20 @@ pub unsafe fn PySequence_In(o: *mut PyObject, value: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyMapping_Length")]
pub unsafe fn PyMapping_Length(o: *mut PyObject) -> Py_ssize_t {
PyMapping_Size(o)
}
@ -261,17 +347,25 @@ pub unsafe fn PyMapping_DelItem(o: *mut PyObject, key: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyMapping_HasKeyString")]
pub fn PyMapping_HasKeyString(o: *mut PyObject, key: *const c_char) -> c_int;
pub fn PyMapping_HasKey(o: *mut PyObject, key: *mut PyObject) -> 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_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;
}

View File

@ -5,20 +5,27 @@ use std::os::raw::{c_int, c_void};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyObject_Malloc")]
pub fn PyObject_Malloc(size: size_t) -> *mut c_void;
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) -> ();
#[cfg(not(Py_LIMITED_API))]
pub fn _Py_GetAllocatedBlocks() -> Py_ssize_t;
#[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;
#[cfg_attr(PyPy, link_name = "_PyPyObject_New")]
pub fn _PyObject_New(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "_PyPyObject_NewVar")]
pub fn _PyObject_NewVar(arg1: *mut PyTypeObject, arg2: Py_ssize_t) -> *mut PyVarObject;
pub fn PyGC_Collect() -> Py_ssize_t;
@ -73,10 +80,13 @@ extern "C" {
pub fn _PyObject_GC_Malloc(size: size_t) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
pub fn _PyObject_GC_Calloc(size: size_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "_PyPyObject_GC_New")]
pub fn _PyObject_GC_New(arg1: *mut PyTypeObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "_PyPyObject_GC_NewVar")]
pub fn _PyObject_GC_NewVar(arg1: *mut PyTypeObject, arg2: Py_ssize_t) -> *mut PyVarObject;
pub fn PyObject_GC_Track(arg1: *mut c_void) -> ();
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) -> ();
}

View File

@ -3,6 +3,7 @@ use std::os::raw::{c_char, c_int, c_void};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyCapsule_Type")]
pub static mut PyCapsule_Type: PyTypeObject;
}
@ -15,22 +16,33 @@ pub unsafe fn PyCapsule_CheckExact(ob: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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;
}

View File

@ -3,20 +3,33 @@ use std::os::raw::c_int;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPy_DebugFlag")]
pub static mut Py_DebugFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_VerboseFlag")]
pub static mut Py_VerboseFlag: c_int;
pub static mut Py_QuietFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_InteractiveFlag")]
pub static mut Py_InteractiveFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_InspectFlag")]
pub static mut Py_InspectFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_OptimizeFlag")]
pub static mut Py_OptimizeFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_NoSiteFlag")]
pub static mut Py_NoSiteFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_BytesWarningFlag")]
pub static mut Py_BytesWarningFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_UseClassExceptionsFlag")]
pub static mut Py_UseClassExceptionsFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_FrozenFlag")]
pub static mut Py_FrozenFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_IgnoreEnvironmentFlag")]
pub static mut Py_IgnoreEnvironmentFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_DontWriteBytecodeFlag")]
pub static mut Py_DontWriteBytecodeFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_NoUserSiteDirectory")]
pub static mut Py_NoUserSiteDirectory: c_int;
pub static mut Py_UnbufferedStdioFlag: c_int;
#[cfg_attr(PyPy, link_name = "PyPy_HashRandomizationFlag")]
pub static mut Py_HashRandomizationFlag: c_int;
pub static mut Py_IsolatedFlag: c_int;
#[cfg(all(Py_3_6, windows))]

View File

@ -1,39 +1,62 @@
use crate::ffi3::object::*;
#[cfg(PyPy)]
use crate::ffi3::objectabstract::PyObject_CallFunction;
use crate::ffi3::pyport::Py_ssize_t;
#[cfg(PyPy)]
use std::ffi::CStr;
use std::os::raw::{c_char, c_int};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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(PyPy, link_name = "PyPyErr_Fetch")]
pub fn PyErr_Fetch(
arg1: *mut *mut PyObject,
arg2: *mut *mut PyObject,
arg3: *mut *mut PyObject,
) -> ();
#[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(PyPy, link_name = "PyPyErr_NormalizeException")]
pub fn PyErr_NormalizeException(
arg1: *mut *mut PyObject,
arg2: *mut *mut PyObject,
arg3: *mut *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) -> ();
}
@ -50,68 +73,142 @@ pub unsafe fn PyExceptionInstance_Check(x: *mut PyObject) -> c_int {
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyExceptionInstance_Class")]
pub unsafe fn PyExceptionInstance_Class(x: *mut PyObject) -> *mut PyObject {
(*x).ob_type 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 {
return PyObject_CallFunction(
PyExc_UnicodeDecodeError,
CStr::from_bytes_with_nul(b"sy#nns\0").unwrap().as_ptr(),
encoding,
object,
length,
start,
end,
);
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyExc_BaseException")]
pub static mut PyExc_BaseException: *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(Py_3_6)]
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;
pub static mut PyExc_EnvironmentError: *mut PyObject;
@ -122,21 +219,36 @@ extern "C" {
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_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,
@ -150,6 +262,7 @@ extern "C" {
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;
#[cfg(Py_3_6)]
pub fn PyErr_SetImportErrorSubclass(
@ -163,25 +276,32 @@ extern "C" {
arg2: *mut PyObject,
arg3: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyErr_BadInternalCall")]
pub fn PyErr_BadInternalCall() -> ();
pub fn _PyErr_BadInternalCall(filename: *const c_char, lineno: c_int) -> ();
#[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() -> ();
pub fn PyErr_SyntaxLocation(filename: *const c_char, lineno: c_int) -> ();
pub fn PyErr_SyntaxLocationEx(filename: *const c_char, lineno: c_int, col_offset: c_int) -> ();
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,

View File

@ -4,17 +4,25 @@ use std::os::raw::c_void;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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) -> ();
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[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) -> ();
}

View File

@ -30,16 +30,23 @@ extern "C" {
//fn _PyState_AddModule(arg1: *mut PyObject,
// arg2: *mut PyModuleDef) -> c_int;
pub fn PyState_FindModule(arg1: *mut PyModuleDef) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyThreadState_New")]
pub fn PyThreadState_New(arg1: *mut PyInterpreterState) -> *mut PyThreadState;
//fn _PyThreadState_Prealloc(arg1: *mut PyInterpreterState)
// -> *mut PyThreadState;
//fn _PyThreadState_Init(arg1: *mut PyThreadState) -> ();
#[cfg_attr(PyPy, link_name = "PyPyThreadState_Clear")]
pub fn PyThreadState_Clear(arg1: *mut PyThreadState) -> ();
#[cfg_attr(PyPy, link_name = "PyPyThreadState_Delete")]
pub fn PyThreadState_Delete(arg1: *mut PyThreadState) -> ();
#[cfg(py_sys_config = "WITH_THREAD")]
#[cfg_attr(PyPy, link_name = "PyPyThreadState_DeleteCurrent")]
pub fn PyThreadState_DeleteCurrent() -> ();
#[cfg_attr(PyPy, link_name = "PyPyThreadState_Get")]
pub fn PyThreadState_Get() -> *mut PyThreadState;
#[cfg_attr(PyPy, link_name = "PyPyThreadState_Swap")]
pub fn PyThreadState_Swap(arg1: *mut PyThreadState) -> *mut PyThreadState;
#[cfg_attr(PyPy, link_name = "PyPyThreadState_GetDict")]
pub fn PyThreadState_GetDict() -> *mut PyObject;
pub fn PyThreadState_SetAsyncExc(arg1: c_long, arg2: *mut PyObject) -> c_int;
}
@ -53,7 +60,9 @@ pub enum PyGILState_STATE {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyGILState_Ensure")]
pub fn PyGILState_Ensure() -> PyGILState_STATE;
#[cfg_attr(PyPy, link_name = "PyPyGILState_Release")]
pub fn PyGILState_Release(arg1: PyGILState_STATE) -> ();
pub fn PyGILState_GetThisThreadState() -> *mut PyThreadState;
}

View File

@ -3,11 +3,13 @@ use std::os::raw::{c_char, c_double, c_int};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyOS_string_to_double")]
pub fn PyOS_string_to_double(
str: *const c_char,
endptr: *mut *mut c_char,
overflow_exception: *mut PyObject,
) -> c_double;
#[cfg_attr(PyPy, link_name = "PyPyOS_double_to_string")]
pub fn PyOS_double_to_string(
val: c_double,
format_code: c_char,

View File

@ -12,12 +12,14 @@ use std::ptr;
extern "C" {
// TODO: these moved to pylifecycle.h
pub fn Py_SetProgramName(arg1: *mut wchar_t) -> ();
#[cfg_attr(PyPy, link_name = "PyPy_GetProgramName")]
pub fn Py_GetProgramName() -> *mut wchar_t;
pub fn Py_SetPythonHome(arg1: *mut wchar_t) -> ();
pub fn Py_GetPythonHome() -> *mut wchar_t;
pub fn Py_Initialize() -> ();
pub fn Py_InitializeEx(arg1: c_int) -> ();
pub fn Py_Finalize() -> ();
#[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) -> ();
@ -142,6 +144,7 @@ extern "C" {
arg4: c_int,
) -> *mut _node;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyRun_StringFlags")]
pub fn PyRun_StringFlags(
arg1: *const c_char,
arg2: c_int,
@ -160,26 +163,35 @@ extern "C" {
flags: *mut PyCompilerFlags,
) -> *mut PyObject;
#[cfg(Py_LIMITED_API)]
#[cfg(not(PyPy))]
pub fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject;
}
#[cfg(not(Py_LIMITED_API))]
#[inline]
pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject {
Py_CompileStringExFlags(string, p, s, ptr::null_mut(), -1)
}
#[cfg(not(Py_LIMITED_API))]
#[inline]
pub unsafe fn Py_CompileStringFlags(
#[cfg(PyPy)]
#[cfg(not(Py_LIMITED_API))]
#[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 {
Py_CompileStringExFlags(string, p, s, f, -1)
) -> *mut PyObject;
}
#[cfg(not(Py_LIMITED_API))]
#[inline]
#[cfg(not(PyPy))]
pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject {
Py_CompileStringExFlags(string, p, s, ptr::null_mut(), -1)
}
#[inline]
#[cfg(PyPy)]
pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject {
Py_CompileStringFlags(string, p, s, ptr::null_mut())
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
pub fn Py_CompileStringExFlags(
str: *const c_char,
filename: *const c_char,
@ -207,11 +219,15 @@ extern "C" {
start: c_int,
) -> *mut symtable;
#[cfg_attr(PyPy, link_name = "PyPyErr_Print")]
pub fn PyErr_Print() -> ();
#[cfg_attr(PyPy, link_name = "PyPyErr_PrintEx")]
pub fn PyErr_PrintEx(arg1: c_int) -> ();
#[cfg_attr(PyPy, link_name = "PyPyErr_Display")]
pub fn PyErr_Display(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject) -> ();
// TODO: these moved to pylifecycle.h
#[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;
@ -220,6 +236,7 @@ extern "C" {
pub fn Py_GetExecPrefix() -> *mut wchar_t;
pub fn Py_GetPath() -> *mut wchar_t;
pub fn Py_SetPath(arg1: *const wchar_t) -> ();
#[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;

View File

@ -3,6 +3,7 @@ use std::os::raw::c_int;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyRange_Type")]
pub static mut PyRange_Type: PyTypeObject;
pub static mut PyRangeIter_Type: PyTypeObject;
pub static mut PyLongRangeIter_Type: PyTypeObject;

View File

@ -4,17 +4,21 @@ use std::os::raw::c_int;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPySet_Type")]
pub static mut PySet_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyFrozenSet_Type")]
pub static mut PyFrozenSet_Type: PyTypeObject;
pub static mut PySetIter_Type: PyTypeObject;
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyFrozenSet_CheckExact")]
pub unsafe fn PyFrozenSet_CheckExact(ob: *mut PyObject) -> c_int {
(Py_TYPE(ob) == &mut PyFrozenSet_Type) as c_int
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyAnySet_CheckExact")]
pub unsafe fn PyAnySet_CheckExact(ob: *mut PyObject) -> c_int {
(Py_TYPE(ob) == &mut PySet_Type || Py_TYPE(ob) == &mut PyFrozenSet_Type) as c_int
}
@ -27,6 +31,7 @@ pub unsafe fn PyAnySet_Check(ob: *mut PyObject) -> c_int {
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPySet_Check")]
pub unsafe fn PySet_Check(ob: *mut PyObject) -> c_int {
(Py_TYPE(ob) == &mut PySet_Type || PyType_IsSubtype(Py_TYPE(ob), &mut PySet_Type) != 0) as c_int
}
@ -39,12 +44,20 @@ pub unsafe fn PyFrozenSet_Check(ob: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPySet_New")]
pub fn PySet_New(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyFrozenSet_New")]
pub fn PyFrozenSet_New(arg1: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySet_Size")]
pub fn PySet_Size(anyset: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPySet_Clear")]
pub fn PySet_Clear(set: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySet_Contains")]
pub fn PySet_Contains(anyset: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySet_Discard")]
pub fn PySet_Discard(set: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySet_Add")]
pub fn PySet_Add(set: *mut PyObject, key: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySet_Pop")]
pub fn PySet_Pop(set: *mut PyObject) -> *mut PyObject;
}

View File

@ -4,6 +4,7 @@ use std::os::raw::c_int;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "_PyPy_EllipsisObject")]
static mut _Py_EllipsisObject: PyObject;
}
@ -14,22 +15,26 @@ pub unsafe fn Py_Ellipsis() -> *mut PyObject {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPySlice_Type")]
pub static mut PySlice_Type: PyTypeObject;
pub static mut PyEllipsis_Type: PyTypeObject;
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPySlice_Check")]
pub unsafe fn PySlice_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PySlice_Type) as c_int
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPySlice_New")]
pub fn PySlice_New(
start: *mut PyObject,
stop: *mut PyObject,
step: *mut PyObject,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySlice_GetIndices")]
pub fn PySlice_GetIndices(
r: *mut PyObject,
length: Py_ssize_t,
@ -37,6 +42,7 @@ extern "C" {
stop: *mut Py_ssize_t,
step: *mut Py_ssize_t,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPySlice_GetIndicesEx")]
pub fn PySlice_GetIndicesEx(
r: *mut PyObject,
length: Py_ssize_t,

View File

@ -6,12 +6,16 @@ use std::os::raw::{c_char, c_int};
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub fn Py_DecodeLocale(arg1: *const c_char, arg2: Py_ssize_t) -> *mut wchar_t;
#[cfg_attr(PyPy, link_name = "PyPySys_GetObject")]
pub fn PySys_GetObject(arg1: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPySys_SetObject")]
pub fn PySys_SetObject(arg1: *const c_char, arg2: *mut PyObject) -> c_int;
pub fn PySys_SetArgv(arg1: c_int, arg2: *mut *mut wchar_t) -> ();
pub fn PySys_SetArgvEx(arg1: c_int, arg2: *mut *mut wchar_t, arg3: c_int) -> ();
pub fn PySys_SetPath(arg1: *const wchar_t) -> ();
#[cfg_attr(PyPy, link_name = "PyPySys_WriteStdout")]
pub fn PySys_WriteStdout(format: *const c_char, ...) -> ();
#[cfg_attr(PyPy, link_name = "PyPySys_WriteStderr")]
pub fn PySys_WriteStderr(format: *const c_char, ...) -> ();
pub fn PySys_FormatStdout(format: *const c_char, ...) -> ();
pub fn PySys_FormatStderr(format: *const c_char, ...) -> ();

View File

@ -3,12 +3,16 @@ use std::os::raw::c_int;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyTraceBack_Here")]
pub fn PyTraceBack_Here(arg1: *mut crate::ffi3::PyFrameObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyTraceBack_Print")]
pub fn PyTraceBack_Print(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyTraceBack_Type")]
pub static mut PyTraceBack_Type: PyTypeObject;
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyTraceBack_Check")]
pub unsafe fn PyTraceBack_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyTraceBack_Type) as c_int
}

View File

@ -11,6 +11,7 @@ pub struct PyTupleObject {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyTuple_Type")]
pub static mut PyTuple_Type: PyTypeObject;
pub static mut PyTupleIter_Type: PyTypeObject;
}
@ -27,15 +28,21 @@ pub unsafe fn PyTuple_CheckExact(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyTuple_New")]
pub fn PyTuple_New(size: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyTuple_Size")]
pub fn PyTuple_Size(arg1: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyTuple_GetItem")]
pub fn PyTuple_GetItem(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyTuple_SetItem")]
pub fn PyTuple_SetItem(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyTuple_GetSlice")]
pub fn PyTuple_GetSlice(
arg1: *mut PyObject,
arg2: Py_ssize_t,
arg3: Py_ssize_t,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyTuple_Pack")]
pub fn PyTuple_Pack(arg1: Py_ssize_t, ...) -> *mut PyObject;
pub fn PyTuple_ClearFreeList() -> c_int;
}

View File

@ -12,16 +12,19 @@ pub type Py_UCS1 = u8;
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Type")]
pub static mut PyUnicode_Type: PyTypeObject;
pub static mut PyUnicodeIter_Type: PyTypeObject;
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Check")]
pub unsafe fn PyUnicode_Check(op: *mut PyObject) -> c_int {
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_CheckExact")]
pub unsafe fn PyUnicode_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyUnicode_Type) as c_int
}
@ -49,8 +52,10 @@ extern "C" {
fill_char: Py_UCS4,
) -> Py_ssize_t;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromUnicode")]
pub fn PyUnicode_FromUnicode(u: *const Py_UNICODE, size: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromStringAndSize")]
pub fn PyUnicode_FromStringAndSize(u: *const c_char, size: Py_ssize_t) -> *mut PyObject;
pub fn PyUnicode_FromString(u: *const c_char) -> *mut PyObject;
@ -74,13 +79,17 @@ extern "C" {
) -> *mut Py_UCS4;
pub fn PyUnicode_AsUCS4Copy(unicode: *mut PyObject) -> *mut Py_UCS4;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUnicode")]
pub fn PyUnicode_AsUnicode(unicode: *mut PyObject) -> *mut Py_UNICODE;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUnicodeAndSize")]
pub fn PyUnicode_AsUnicodeAndSize(
unicode: *mut PyObject,
size: *mut Py_ssize_t,
) -> *mut Py_UNICODE;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_GetLength")]
pub fn PyUnicode_GetLength(unicode: *mut PyObject) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_GetSize")]
pub fn PyUnicode_GetSize(unicode: *mut PyObject) -> Py_ssize_t;
pub fn PyUnicode_ReadChar(unicode: *mut PyObject, index: Py_ssize_t) -> Py_UCS4;
pub fn PyUnicode_WriteChar(
@ -89,43 +98,59 @@ extern "C" {
character: Py_UCS4,
) -> c_int;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_GetMax")]
pub fn PyUnicode_GetMax() -> Py_UNICODE;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Resize")]
pub fn PyUnicode_Resize(unicode: *mut *mut PyObject, length: Py_ssize_t) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromEncodedObject")]
pub fn PyUnicode_FromEncodedObject(
obj: *mut PyObject,
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromObject")]
pub fn PyUnicode_FromObject(obj: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromFormat")]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromFormatV")]
//pub fn PyUnicode_FromFormatV(format: *const c_char,
// vargs: va_list) -> *mut PyObject;
pub fn PyUnicode_FromFormat(format: *const c_char, ...) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_InternInPlace")]
pub fn PyUnicode_InternInPlace(arg1: *mut *mut PyObject) -> ();
pub fn PyUnicode_InternImmortal(arg1: *mut *mut PyObject) -> ();
#[cfg_attr(PyPy, link_name = "PyPyUnicode_InternFromString")]
pub fn PyUnicode_InternFromString(u: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromWideChar")]
pub fn PyUnicode_FromWideChar(w: *const wchar_t, size: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsWideChar")]
pub fn PyUnicode_AsWideChar(
unicode: *mut PyObject,
w: *mut wchar_t,
size: Py_ssize_t,
) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsWideCharString")]
pub fn PyUnicode_AsWideCharString(
unicode: *mut PyObject,
size: *mut Py_ssize_t,
) -> *mut wchar_t;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FromOrdinal")]
pub fn PyUnicode_FromOrdinal(ordinal: c_int) -> *mut PyObject;
pub fn PyUnicode_ClearFreeList() -> c_int;
#[cfg(not(Py_LIMITED_API))]
#[cfg(Py_3_7)]
pub fn PyUnicode_AsUTF8AndSize(unicode: *mut PyObject, size: *mut Py_ssize_t) -> *const c_char;
#[cfg(not(Py_3_7))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8AndSize")]
pub fn PyUnicode_AsUTF8AndSize(unicode: *mut PyObject, size: *mut Py_ssize_t) -> *mut c_char;
#[cfg(not(Py_LIMITED_API))]
#[cfg(Py_3_7)]
pub fn PyUnicode_AsUTF8(unicode: *mut PyObject) -> *const c_char;
#[cfg(not(Py_3_7))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8")]
pub fn PyUnicode_AsUTF8(unicode: *mut PyObject) -> *mut c_char;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_GetDefaultEncoding")]
pub fn PyUnicode_GetDefaultEncoding() -> *const c_char;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Decode")]
pub fn PyUnicode_Decode(
s: *const c_char,
size: Py_ssize_t,
@ -149,11 +174,13 @@ extern "C" {
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsEncodedObject")]
pub fn PyUnicode_AsEncodedObject(
unicode: *mut PyObject,
encoding: *const c_char,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsEncodedString")]
pub fn PyUnicode_AsEncodedString(
unicode: *mut PyObject,
encoding: *const c_char,
@ -184,6 +211,7 @@ extern "C" {
base64WhiteSpace: c_int,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeUTF8")]
pub fn PyUnicode_DecodeUTF8(
string: *const c_char,
length: Py_ssize_t,
@ -195,13 +223,16 @@ extern "C" {
errors: *const c_char,
consumed: *mut Py_ssize_t,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF8String")]
pub fn PyUnicode_AsUTF8String(unicode: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeUTF8")]
pub fn PyUnicode_EncodeUTF8(
data: *const Py_UNICODE,
length: Py_ssize_t,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeUTF32")]
pub fn PyUnicode_DecodeUTF32(
string: *const c_char,
length: Py_ssize_t,
@ -215,6 +246,7 @@ extern "C" {
byteorder: *mut c_int,
consumed: *mut Py_ssize_t,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF32String")]
pub fn PyUnicode_AsUTF32String(unicode: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
pub fn PyUnicode_EncodeUTF32(
@ -223,6 +255,7 @@ extern "C" {
errors: *const c_char,
byteorder: c_int,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeUTF16")]
pub fn PyUnicode_DecodeUTF16(
string: *const c_char,
length: Py_ssize_t,
@ -236,6 +269,7 @@ extern "C" {
byteorder: *mut c_int,
consumed: *mut Py_ssize_t,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUTF16String")]
pub fn PyUnicode_AsUTF16String(unicode: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
pub fn PyUnicode_EncodeUTF16(
@ -249,6 +283,7 @@ extern "C" {
length: Py_ssize_t,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsUnicodeEscapeString")]
pub fn PyUnicode_AsUnicodeEscapeString(unicode: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
pub fn PyUnicode_EncodeUnicodeEscape(
@ -266,25 +301,31 @@ extern "C" {
data: *const Py_UNICODE,
length: Py_ssize_t,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeLatin1")]
pub fn PyUnicode_DecodeLatin1(
string: *const c_char,
length: Py_ssize_t,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsLatin1String")]
pub fn PyUnicode_AsLatin1String(unicode: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeLatin1")]
pub fn PyUnicode_EncodeLatin1(
data: *const Py_UNICODE,
length: Py_ssize_t,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeASCII")]
pub fn PyUnicode_DecodeASCII(
string: *const c_char,
length: Py_ssize_t,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_AsASCIIString")]
pub fn PyUnicode_AsASCIIString(unicode: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeASCII")]
pub fn PyUnicode_EncodeASCII(
data: *const Py_UNICODE,
length: Py_ssize_t,
@ -316,6 +357,7 @@ extern "C" {
) -> *mut PyObject;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeDecimal")]
pub fn PyUnicode_EncodeDecimal(
s: *mut Py_UNICODE,
length: Py_ssize_t,
@ -323,6 +365,7 @@ extern "C" {
errors: *const c_char,
) -> c_int;
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(PyPy, link_name = "PyPyUnicode_TransformDecimalToASCII")]
pub fn PyUnicode_TransformDecimalToASCII(
s: *mut Py_UNICODE,
length: Py_ssize_t,
@ -334,19 +377,27 @@ extern "C" {
) -> *mut PyObject;
pub fn PyUnicode_DecodeLocale(str: *const c_char, errors: *const c_char) -> *mut PyObject;
pub fn PyUnicode_EncodeLocale(unicode: *mut PyObject, errors: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FSConverter")]
pub fn PyUnicode_FSConverter(arg1: *mut PyObject, arg2: *mut c_void) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_FSDecoder")]
pub fn PyUnicode_FSDecoder(arg1: *mut PyObject, arg2: *mut c_void) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeFSDefault")]
pub fn PyUnicode_DecodeFSDefault(s: *const c_char) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_DecodeFSDefaultAndSize")]
pub fn PyUnicode_DecodeFSDefaultAndSize(s: *const c_char, size: Py_ssize_t) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_EncodeFSDefault")]
pub fn PyUnicode_EncodeFSDefault(unicode: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Concat")]
pub fn PyUnicode_Concat(left: *mut PyObject, right: *mut PyObject) -> *mut PyObject;
pub fn PyUnicode_Append(pleft: *mut *mut PyObject, right: *mut PyObject) -> ();
pub fn PyUnicode_AppendAndDel(pleft: *mut *mut PyObject, right: *mut PyObject) -> ();
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Split")]
pub fn PyUnicode_Split(
s: *mut PyObject,
sep: *mut PyObject,
maxsplit: Py_ssize_t,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Splitlines")]
pub fn PyUnicode_Splitlines(s: *mut PyObject, keepends: c_int) -> *mut PyObject;
pub fn PyUnicode_Partition(s: *mut PyObject, sep: *mut PyObject) -> *mut PyObject;
pub fn PyUnicode_RPartition(s: *mut PyObject, sep: *mut PyObject) -> *mut PyObject;
@ -360,7 +411,9 @@ extern "C" {
table: *mut PyObject,
errors: *const c_char,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Join")]
pub fn PyUnicode_Join(separator: *mut PyObject, seq: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Tailmatch")]
pub fn PyUnicode_Tailmatch(
str: *mut PyObject,
substr: *mut PyObject,
@ -368,6 +421,7 @@ extern "C" {
end: Py_ssize_t,
direction: c_int,
) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Find")]
pub fn PyUnicode_Find(
str: *mut PyObject,
substr: *mut PyObject,
@ -382,25 +436,30 @@ extern "C" {
end: Py_ssize_t,
direction: c_int,
) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Count")]
pub fn PyUnicode_Count(
str: *mut PyObject,
substr: *mut PyObject,
start: Py_ssize_t,
end: Py_ssize_t,
) -> Py_ssize_t;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Replace")]
pub fn PyUnicode_Replace(
str: *mut PyObject,
substr: *mut PyObject,
replstr: *mut PyObject,
maxcount: Py_ssize_t,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Compare")]
pub fn PyUnicode_Compare(left: *mut PyObject, right: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_CompareWithASCIIString")]
pub fn PyUnicode_CompareWithASCIIString(left: *mut PyObject, right: *const c_char) -> c_int;
pub fn PyUnicode_RichCompare(
left: *mut PyObject,
right: *mut PyObject,
op: c_int,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyUnicode_Format")]
pub fn PyUnicode_Format(format: *mut PyObject, args: *mut PyObject) -> *mut PyObject;
pub fn PyUnicode_Contains(container: *mut PyObject, element: *mut PyObject) -> c_int;
pub fn PyUnicode_IsIdentifier(s: *mut PyObject) -> c_int;

View File

@ -9,6 +9,7 @@ extern "C" {
message: *const c_char,
stack_level: Py_ssize_t,
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyErr_WarnFormat")]
pub fn PyErr_WarnFormat(
category: *mut PyObject,
stack_level: Py_ssize_t,

View File

@ -11,16 +11,19 @@ extern "C" {
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyWeakref_CheckRef")]
pub unsafe fn PyWeakref_CheckRef(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut _PyWeakref_RefType)
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyWeakref_CheckRefExact")]
pub unsafe fn PyWeakref_CheckRefExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut _PyWeakref_RefType) as c_int
}
#[inline]
#[cfg_attr(PyPy, link_name = "PyPyWeakref_CheckProxy")]
pub unsafe fn PyWeakref_CheckProxy(op: *mut PyObject) -> c_int {
((Py_TYPE(op) == &mut _PyWeakref_ProxyType)
|| (Py_TYPE(op) == &mut _PyWeakref_CallableProxyType)) as c_int
@ -33,7 +36,10 @@ pub unsafe fn PyWeakref_Check(op: *mut PyObject) -> c_int {
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyWeakref_NewRef")]
pub fn PyWeakref_NewRef(ob: *mut PyObject, callback: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyWeakref_NewProxy")]
pub fn PyWeakref_NewProxy(ob: *mut PyObject, callback: *mut PyObject) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyWeakref_GetObject")]
pub fn PyWeakref_GetObject(_ref: *mut PyObject) -> *mut PyObject;
}

View File

@ -42,6 +42,7 @@ pub fn prepare_freethreaded_python() {
if ffi::Py_IsInitialized() != 0 {
// If Python is already initialized, we expect Python threading to also be initialized,
// as we can't make the existing Python main thread acquire the GIL.
#[cfg(not(Py_3_7))]
assert_ne!(ffi::PyEval_ThreadsInitialized(), 0);
} else {
// If Python isn't initialized yet, we expect that Python threading
@ -53,12 +54,20 @@ pub fn prepare_freethreaded_python() {
// Signal handling depends on the notion of a 'main thread', which doesn't exist in this case.
// Note that the 'main thread' notion in Python isn't documented properly;
// and running Python without one is not officially supported.
// PyPy does not support the embedding API
#[cfg(not(PyPy))]
ffi::Py_InitializeEx(0);
// > Changed in version 3.7: This function is now called by Py_Initialize(), so you dont have
// > to call it yourself anymore.
#[cfg(not(Py_3_7))]
ffi::PyEval_InitThreads();
// PyEval_InitThreads() will acquire the GIL,
// but we don't want to hold it at this point
// (it's not acquired in the other code paths)
// So immediately release the GIL:
#[cfg(not(PyPy))]
let _thread_state = ffi::PyEval_SaveThread();
// Note that the PyThreadState returned by PyEval_SaveThread is also held in TLS by the Python runtime,
// and will be restored by PyGILState_Ensure.

View File

@ -15,7 +15,7 @@ use class::methods::PyMethodsProtocol;
use std::collections::HashMap;
use std::ffi::CString;
use std::os::raw::c_void;
use std::ptr::NonNull;
use std::ptr::{self, NonNull};
/// Python type information.
pub trait PyTypeInfo {
@ -304,7 +304,15 @@ where
unsafe { <T::BaseType as PyTypeInfo>::type_object() };
type_object.tp_name = type_name.into_raw();
// PyPy will segfault if passed only a nul terminator as `tp_doc`.
// ptr::null() is OK though.
if T::DESCRIPTION == "\0" {
type_object.tp_doc = ptr::null();
} else {
type_object.tp_doc = T::DESCRIPTION.as_ptr() as *const _;
};
type_object.tp_base = base_type_object;
// dealloc

View File

@ -1,8 +1,10 @@
use crate::ffi;
#[cfg(not(PyPy))]
use crate::instance::PyNativeType;
use crate::object::PyObject;
use crate::AsPyPointer;
use crate::Python;
#[cfg(not(PyPy))]
use std::ops::*;
use std::os::raw::c_double;
@ -30,6 +32,7 @@ impl PyComplex {
}
/// Returns `|self|`.
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
pub fn abs(&self) -> c_double {
unsafe {
let val = (*(self.as_ptr() as *mut ffi::PyComplexObject)).cval;
@ -38,6 +41,7 @@ impl PyComplex {
}
/// Returns `self ** other`
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
pub fn pow(&self, other: &PyComplex) -> &PyComplex {
unsafe {
self.py()
@ -47,6 +51,7 @@ impl PyComplex {
}
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
#[inline(always)]
unsafe fn complex_operation(
l: &PyComplex,
@ -59,6 +64,7 @@ unsafe fn complex_operation(
}
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
impl<'py> Add for &'py PyComplex {
type Output = &'py PyComplex;
fn add(self, other: &'py PyComplex) -> &'py PyComplex {
@ -70,6 +76,7 @@ impl<'py> Add for &'py PyComplex {
}
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
impl<'py> Sub for &'py PyComplex {
type Output = &'py PyComplex;
fn sub(self, other: &'py PyComplex) -> &'py PyComplex {
@ -81,6 +88,7 @@ impl<'py> Sub for &'py PyComplex {
}
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
impl<'py> Mul for &'py PyComplex {
type Output = &'py PyComplex;
fn mul(self, other: &'py PyComplex) -> &'py PyComplex {
@ -92,6 +100,7 @@ impl<'py> Mul for &'py PyComplex {
}
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
impl<'py> Div for &'py PyComplex {
type Output = &'py PyComplex;
fn div(self, other: &'py PyComplex) -> &'py PyComplex {
@ -103,6 +112,7 @@ impl<'py> Div for &'py PyComplex {
}
#[cfg(not(Py_LIMITED_API))]
#[cfg(not(PyPy))]
impl<'py> Neg for &'py PyComplex {
type Output = &'py PyComplex;
fn neg(self) -> &'py PyComplex {

View File

@ -7,9 +7,11 @@
use crate::err::PyResult;
use crate::ffi;
#[cfg(PyPy)]
use crate::ffi::datetime::{PyDateTime_FromTimestamp, PyDate_FromTimestamp};
use crate::ffi::PyDateTimeAPI;
use crate::ffi::{PyDateTime_Check, PyDate_Check, PyDelta_Check, PyTZInfo_Check, PyTime_Check};
#[cfg(Py_3_6)]
#[cfg(all(Py_3_6, not(PyPy)))]
use crate::ffi::{PyDateTime_DATE_GET_FOLD, PyDateTime_TIME_GET_FOLD};
use crate::ffi::{
PyDateTime_DATE_GET_HOUR, PyDateTime_DATE_GET_MICROSECOND, PyDateTime_DATE_GET_MINUTE,
@ -30,6 +32,7 @@ use crate::AsPyPointer;
use crate::Python;
use crate::ToPyObject;
use std::os::raw::c_int;
#[cfg(not(PyPy))]
use std::ptr;
/// Access traits
@ -58,7 +61,7 @@ pub trait PyTimeAccess {
fn get_minute(&self) -> u8;
fn get_second(&self) -> u8;
fn get_microsecond(&self) -> u32;
#[cfg(Py_3_6)]
#[cfg(all(Py_3_6, not(PyPy)))]
fn get_fold(&self) -> u8;
}
@ -83,10 +86,16 @@ impl PyDate {
///
/// This is equivalent to `datetime.date.fromtimestamp`
pub fn from_timestamp(py: Python, timestamp: i64) -> PyResult<Py<PyDate>> {
let args = PyTuple::new(py, &[timestamp]);
let time_tuple = PyTuple::new(py, &[timestamp]);
unsafe {
let ptr = (PyDateTimeAPI.Date_FromTimestamp)(PyDateTimeAPI.DateType, args.as_ptr());
#[cfg(PyPy)]
let ptr = PyDate_FromTimestamp(time_tuple.as_ptr());
#[cfg(not(PyPy))]
let ptr =
(PyDateTimeAPI.Date_FromTimestamp)(PyDateTimeAPI.DateType, time_tuple.as_ptr());
Py::from_owned_ptr_or_err(py, ptr)
}
}
@ -156,11 +165,18 @@ impl PyDateTime {
let args = PyTuple::new(py, &[timestamp, time_zone_info]);
unsafe {
let ptr = (PyDateTimeAPI.DateTime_FromTimestamp)(
#[cfg(PyPy)]
let ptr = PyDateTime_FromTimestamp(args.as_ptr());
#[cfg(not(PyPy))]
let ptr = {
(PyDateTimeAPI.DateTime_FromTimestamp)(
PyDateTimeAPI.DateTimeType,
args.as_ptr(),
ptr::null_mut(),
);
)
};
Py::from_owned_ptr_or_err(py, ptr)
}
}
@ -197,7 +213,7 @@ impl PyTimeAccess for PyDateTime {
unsafe { PyDateTime_DATE_GET_MICROSECOND(self.as_ptr()) as u32 }
}
#[cfg(Py_3_6)]
#[cfg(all(Py_3_6, not(PyPy)))]
fn get_fold(&self) -> u8 {
unsafe { PyDateTime_DATE_GET_FOLD(self.as_ptr()) as u8 }
}
@ -274,7 +290,7 @@ impl PyTimeAccess for PyTime {
unsafe { PyDateTime_TIME_GET_MICROSECOND(self.as_ptr()) as u32 }
}
#[cfg(Py_3_6)]
#[cfg(all(Py_3_6, not(PyPy)))]
fn get_fold(&self) -> u8 {
unsafe { PyDateTime_TIME_GET_FOLD(self.as_ptr()) as u8 }
}

View File

@ -6,6 +6,7 @@ use crate::instance::PyNativeType;
use crate::object::PyObject;
use crate::types::{PyAny, PyList};
use crate::AsPyPointer;
#[cfg(not(PyPy))]
use crate::IntoPyPointer;
use crate::Python;
use crate::{IntoPyObject, ToBorrowedObject, ToPyObject};
@ -30,6 +31,7 @@ impl PyDict {
///
/// Returns an error on invalid input. In the case of key collisions,
/// this keeps the last entry seen.
#[cfg(not(PyPy))]
pub fn from_sequence(py: Python, seq: PyObject) -> PyResult<&PyDict> {
unsafe {
let dict = py.from_owned_ptr::<PyDict>(ffi::PyDict_New());

View File

@ -168,6 +168,7 @@ impl PySequence {
/// Return the number of occurrences of value in o, that is, return the number of keys for
/// which `o[key] == value`
#[inline]
#[cfg(not(PyPy))]
pub fn count<V>(&self, value: V) -> PyResult<usize>
where
V: ToBorrowedObject,