diff --git a/.travis.yml b/.travis.yml index a42eceb6..da864c74 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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" diff --git a/README.md b/README.md index a4063a15..863335a8 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/build.rs b/build.rs index 172454f7..9d1a58d0 100644 --- a/build.rs +++ b/build.rs @@ -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, + implementation: PythonInterpreterKind, } impl PartialEq for PythonVersion { @@ -142,6 +149,7 @@ fn load_cross_compile_info() -> Result<(PythonVersion, HashMap, 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 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 { 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 { +fn get_rustc_link_lib( + version: &PythonVersion, + ld_version: &str, + _: bool, +) -> Result { // 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 { + // 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 { +fn get_interpreter_version(line: &str, implementation: &str) -> Result { 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 { - // 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 = 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) -> 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) -> 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 { 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()); diff --git a/ci/travis/cover.sh b/ci/travis/cover.sh index 8b8ee8e5..1b685005 100755 --- a/ci/travis/cover.sh +++ b/ci/travis/cover.sh @@ -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 diff --git a/ci/travis/guide.sh b/ci/travis/guide.sh index 245bec37..a0261b40 100755 --- a/ci/travis/guide.sh +++ b/ci/travis/guide.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -ex diff --git a/ci/travis/setup.sh b/ci/travis/setup.sh index 3702865e..96c9d82d 100755 --- a/ci/travis/setup.sh +++ b/ci/travis/setup.sh @@ -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" @@ -32,4 +51,4 @@ if [ ! -f "$HOME/.cargo/bin/kcov" ]; then make install src/kcov $HOME/.cargo/bin/kcov cd $TRAVIS_BUILD_DIR -fi +fi \ No newline at end of file diff --git a/ci/travis/test.sh b/ci/travis/test.sh index 01ae03dc..728e50f7 100755 --- a/ci/travis/test.sh +++ b/ci/travis/test.sh @@ -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 - tox -c "$example_dir/tox.ini" -e py + if [[ $FEATURES == *"pypy"* ]]; then + tox -c "$example_dir/tox.ini" -e pypy3 + else + tox -c "$example_dir/tox.ini" -e py + fi done diff --git a/examples/rustapi_module/setup.py b/examples/rustapi_module/setup.py index a5c69179..278ab4a3 100644 --- a/examples/rustapi_module/setup.py +++ b/examples/rustapi_module/setup.py @@ -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 diff --git a/examples/rustapi_module/src/datetime.rs b/examples/rustapi_module/src/datetime.rs index e62ee882..05486955 100644 --- a/examples/rustapi_module/src/datetime.rs +++ b/examples/rustapi_module/src/datetime.rs @@ -229,7 +229,7 @@ fn datetime(_py: Python<'_>, m: &PyModule) -> PyResult<()> { } m.add_wrapped(wrap_pyfunction!(issue_219))?; - m.add_class::()?; + Ok(()) } diff --git a/examples/rustapi_module/src/othermod.rs b/examples/rustapi_module/src/othermod.rs index 34e65c68..dd43694d 100644 --- a/examples/rustapi_module/src/othermod.rs +++ b/examples/rustapi_module/src/othermod.rs @@ -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::()?; m.add("USIZE_MIN", usize::min_value())?; diff --git a/examples/rustapi_module/tests/test_datetime.py b/examples/rustapi_module/tests/test_datetime.py index 8114a925..9fc5b230 100644 --- a/examples/rustapi_module/tests/test_datetime.py +++ b/examples/rustapi_module/tests/test_datetime.py @@ -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) diff --git a/examples/rustapi_module/tests/test_dict_iter.py b/examples/rustapi_module/tests/test_dict_iter.py index 98acc214..d5592fa4 100644 --- a/examples/rustapi_module/tests/test_dict_iter.py +++ b/examples/rustapi_module/tests/test_dict_iter.py @@ -1,6 +1,5 @@ -from rustapi_module.test_dict import DictSize import pytest - +from rustapi_module.test_dict import DictSize @pytest.mark.parametrize( "size", diff --git a/examples/rustapi_module/tests/test_othermod.py b/examples/rustapi_module/tests/test_othermod.py index 8389076b..f47c64b7 100644 --- a/examples/rustapi_module/tests/test_othermod.py +++ b/examples/rustapi_module/tests/test_othermod.py @@ -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)) diff --git a/examples/rustapi_module/tests/test_subclassing.py b/examples/rustapi_module/tests/test_subclassing.py index 8c086b75..062710f6 100644 --- a/examples/rustapi_module/tests/test_subclassing.py +++ b/examples/rustapi_module/tests/test_subclassing.py @@ -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) \ No newline at end of file diff --git a/examples/rustapi_module/tox.ini b/examples/rustapi_module/tox.ini index d6c1d587..fda16955 100644 --- a/examples/rustapi_module/tox.ini +++ b/examples/rustapi_module/tox.ini @@ -2,6 +2,7 @@ envlist = py35, py36, py37, + pypy35 minversion = 2.9.0 skip_missing_interpreters = true diff --git a/examples/word-count/tox.ini b/examples/word-count/tox.ini index d5a9413a..ebc22945 100644 --- a/examples/word-count/tox.ini +++ b/examples/word-count/tox.ini @@ -2,6 +2,7 @@ envlist = py35, py36, py37, + pypy35 minversion = 3.4.0 skip_missing_interpreters = true diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index 64515c6e..405bb6ac 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -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) diff --git a/guide/src/pypy.md b/guide/src/pypy.md new file mode 100644 index 00000000..71729ca6 --- /dev/null +++ b/guide/src/pypy.md @@ -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`) \ No newline at end of file diff --git a/src/ffi/datetime.rs b/src/ffi/datetime.rs index 87851731..c7662279 100644 --- a/src/ffi/datetime.rs +++ b/src/ffi/datetime.rs @@ -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 { - // PyDateTime_CAPSULE_NAME is a macro in C - let PyDateTime_CAPSULE_NAME = CString::new("datetime.datetime_CAPI").unwrap(); + // 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(); - let capsule = PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *const PyDateTime_CAPI; + #[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(); + + 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]. diff --git a/src/ffi3/boolobject.rs b/src/ffi3/boolobject.rs index 17f096dd..947d9ab0 100644 --- a/src/ffi3/boolobject.rs +++ b/src/ffi3/boolobject.rs @@ -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 } diff --git a/src/ffi3/bytearrayobject.rs b/src/ffi3/bytearrayobject.rs index 5a87930e..2b661109 100644 --- a/src/ffi3/bytearrayobject.rs +++ b/src/ffi3/bytearrayobject.rs @@ -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; } diff --git a/src/ffi3/bytesobject.rs b/src/ffi3/bytesobject.rs index 75d2809b..c91055af 100644 --- a/src/ffi3/bytesobject.rs +++ b/src/ffi3/bytesobject.rs @@ -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, diff --git a/src/ffi3/ceval.rs b/src/ffi3/ceval.rs index ebfbca36..3c77de60 100644 --- a/src/ffi3/ceval.rs +++ b/src/ffi3/ceval.rs @@ -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 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() -> (); } diff --git a/src/ffi3/code.rs b/src/ffi3/code.rs index 77ad061a..71ad0376 100644 --- a/src/ffi3/code.rs +++ b/src/ffi3/code.rs @@ -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) } diff --git a/src/ffi3/codecs.rs b/src/ffi3/codecs.rs index af5c34a6..d8241da0 100644 --- a/src/ffi3/codecs.rs +++ b/src/ffi3/codecs.rs @@ -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, diff --git a/src/ffi3/complexobject.rs b/src/ffi3/complexobject.rs index 50cfa40f..62fc2004 100644 --- a/src/ffi3/complexobject.rs +++ b/src/ffi3/complexobject.rs @@ -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; } diff --git a/src/ffi3/descrobject.rs b/src/ffi3/descrobject.rs index 6ec5eebe..05af23b0 100644 --- a/src/ffi3/descrobject.rs +++ b/src/ffi3/descrobject.rs @@ -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; } diff --git a/src/ffi3/dictobject.rs b/src/ffi3/dictobject.rs index 73623389..e6a40af3 100644 --- a/src/ffi3/dictobject.rs +++ b/src/ffi3/dictobject.rs @@ -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; } diff --git a/src/ffi3/eval.rs b/src/ffi3/eval.rs index 7d3b53f1..abf276b7 100644 --- a/src/ffi3/eval.rs +++ b/src/ffi3/eval.rs @@ -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, diff --git a/src/ffi3/fileobject.rs b/src/ffi3/fileobject.rs index 9f6170f0..36152677 100644 --- a/src/ffi3/fileobject.rs +++ b/src/ffi3/fileobject.rs @@ -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; diff --git a/src/ffi3/floatobject.rs b/src/ffi3/floatobject.rs index f49a937e..89824862 100644 --- a/src/ffi3/floatobject.rs +++ b/src/ffi3/floatobject.rs @@ -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; } diff --git a/src/ffi3/frameobject.rs b/src/ffi3/frameobject.rs index 349f830f..c71212b4 100644 --- a/src/ffi3/frameobject.rs +++ b/src/ffi3/frameobject.rs @@ -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, diff --git a/src/ffi3/import.rs b/src/ffi3/import.rs index 655d5ad5..6a1ec2da 100644 --- a/src/ffi3/import.rs +++ b/src/ffi3/import.rs @@ -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; diff --git a/src/ffi3/intrcheck.rs b/src/ffi3/intrcheck.rs index d68f7382..4e1e3088 100644 --- a/src/ffi3/intrcheck.rs +++ b/src/ffi3/intrcheck.rs @@ -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() -> (); } diff --git a/src/ffi3/iterobject.rs b/src/ffi3/iterobject.rs index f5e8d2a4..dde0df0d 100644 --- a/src/ffi3/iterobject.rs +++ b/src/ffi3/iterobject.rs @@ -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; } diff --git a/src/ffi3/listobject.rs b/src/ffi3/listobject.rs index 0170a2b7..1fb339cf 100644 --- a/src/ffi3/listobject.rs +++ b/src/ffi3/listobject.rs @@ -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; } diff --git a/src/ffi3/longobject.rs b/src/ffi3/longobject.rs index 39fa3143..1bd3076e 100644 --- a/src/ffi3/longobject.rs +++ b/src/ffi3/longobject.rs @@ -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, diff --git a/src/ffi3/memoryobject.rs b/src/ffi3/memoryobject.rs index 532d9ada..e4879128 100644 --- a/src/ffi3/memoryobject.rs +++ b/src/ffi3/memoryobject.rs @@ -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, diff --git a/src/ffi3/methodobject.rs b/src/ffi3/methodobject.rs index f880435e..2a949ff2 100644 --- a/src/ffi3/methodobject.rs +++ b/src/ffi3/methodobject.rs @@ -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; 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, diff --git a/src/ffi3/modsupport.rs b/src/ffi3/modsupport.rs index 8e85aff6..19bfebfe 100644 --- a/src/ffi3/modsupport.rs +++ b/src/ffi3/modsupport.rs @@ -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")] diff --git a/src/ffi3/moduleobject.rs b/src/ffi3/moduleobject.rs index af1a7d1a..f1f49887 100644 --- a/src/ffi3/moduleobject.rs +++ b/src/ffi3/moduleobject.rs @@ -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; } diff --git a/src/ffi3/object.rs b/src/ffi3/object.rs index 0ccbffff..a20e4c77 100644 --- a/src/ffi3/object.rs +++ b/src/ffi3/object.rs @@ -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, pub tp_version_tag: c_uint, pub tp_finalize: Option, + #[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; } diff --git a/src/ffi3/objectabstract.rs b/src/ffi3/objectabstract.rs index fee180c9..a95bc6e3 100644 --- a/src/ffi3/objectabstract.rs +++ b/src/ffi3/objectabstract.rs @@ -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; } diff --git a/src/ffi3/objimpl.rs b/src/ffi3/objimpl.rs index 08d80e9f..9aa9437d 100644 --- a/src/ffi3/objimpl.rs +++ b/src/ffi3/objimpl.rs @@ -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) -> (); } diff --git a/src/ffi3/pycapsule.rs b/src/ffi3/pycapsule.rs index 26cbc410..a0fcee9f 100644 --- a/src/ffi3/pycapsule.rs +++ b/src/ffi3/pycapsule.rs @@ -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, ) -> *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; + #[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, ) -> 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; } diff --git a/src/ffi3/pydebug.rs b/src/ffi3/pydebug.rs index 7c6a4f31..6422716d 100644 --- a/src/ffi3/pydebug.rs +++ b/src/ffi3/pydebug.rs @@ -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))] diff --git a/src/ffi3/pyerrors.rs b/src/ffi3/pyerrors.rs index 9b80d1e1..bc12572e 100644 --- a/src/ffi3/pyerrors.rs +++ b/src/ffi3/pyerrors.rs @@ -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, diff --git a/src/ffi3/pymem.rs b/src/ffi3/pymem.rs index 5c0f9d15..5bb517f2 100644 --- a/src/ffi3/pymem.rs +++ b/src/ffi3/pymem.rs @@ -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) -> (); } diff --git a/src/ffi3/pystate.rs b/src/ffi3/pystate.rs index 8478eb83..19afac0a 100644 --- a/src/ffi3/pystate.rs +++ b/src/ffi3/pystate.rs @@ -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; } diff --git a/src/ffi3/pystrtod.rs b/src/ffi3/pystrtod.rs index 462d0a28..0fc2e2f8 100644 --- a/src/ffi3/pystrtod.rs +++ b/src/ffi3/pystrtod.rs @@ -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, diff --git a/src/ffi3/pythonrun.rs b/src/ffi3/pythonrun.rs index d206d55c..2ee8e2a5 100644 --- a/src/ffi3/pythonrun.rs +++ b/src/ffi3/pythonrun.rs @@ -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(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; } #[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) } -#[cfg(not(Py_LIMITED_API))] + #[inline] -pub unsafe fn Py_CompileStringFlags( - string: *const c_char, - p: *const c_char, - s: c_int, - f: *mut PyCompilerFlags, -) -> *mut PyObject { - Py_CompileStringExFlags(string, p, s, f, -1) +#[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 ()>) -> 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; diff --git a/src/ffi3/rangeobject.rs b/src/ffi3/rangeobject.rs index 8011e6ba..65c6529b 100644 --- a/src/ffi3/rangeobject.rs +++ b/src/ffi3/rangeobject.rs @@ -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; diff --git a/src/ffi3/setobject.rs b/src/ffi3/setobject.rs index e9843240..ea06fd75 100644 --- a/src/ffi3/setobject.rs +++ b/src/ffi3/setobject.rs @@ -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; } diff --git a/src/ffi3/sliceobject.rs b/src/ffi3/sliceobject.rs index 7c9e29ff..02d23071 100644 --- a/src/ffi3/sliceobject.rs +++ b/src/ffi3/sliceobject.rs @@ -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, diff --git a/src/ffi3/sysmodule.rs b/src/ffi3/sysmodule.rs index b6c0c4c0..f52e1b37 100644 --- a/src/ffi3/sysmodule.rs +++ b/src/ffi3/sysmodule.rs @@ -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, ...) -> (); diff --git a/src/ffi3/traceback.rs b/src/ffi3/traceback.rs index 8c45ab65..8bd12bf3 100644 --- a/src/ffi3/traceback.rs +++ b/src/ffi3/traceback.rs @@ -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 } diff --git a/src/ffi3/tupleobject.rs b/src/ffi3/tupleobject.rs index abac5671..d626e07c 100644 --- a/src/ffi3/tupleobject.rs +++ b/src/ffi3/tupleobject.rs @@ -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; } diff --git a/src/ffi3/unicodeobject.rs b/src/ffi3/unicodeobject.rs index e3ceb800..b50dd00b 100644 --- a/src/ffi3/unicodeobject.rs +++ b/src/ffi3/unicodeobject.rs @@ -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; diff --git a/src/ffi3/warnings.rs b/src/ffi3/warnings.rs index 952cf370..c26a493f 100644 --- a/src/ffi3/warnings.rs +++ b/src/ffi3/warnings.rs @@ -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, diff --git a/src/ffi3/weakrefobject.rs b/src/ffi3/weakrefobject.rs index 766457f8..0c8a0baa 100644 --- a/src/ffi3/weakrefobject.rs +++ b/src/ffi3/weakrefobject.rs @@ -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; } diff --git a/src/gil.rs b/src/gil.rs index b0073198..7b90526f 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -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 don’t 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. diff --git a/src/type_object.rs b/src/type_object.rs index c58274ac..40fe13d9 100644 --- a/src/type_object.rs +++ b/src/type_object.rs @@ -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 { ::type_object() }; type_object.tp_name = type_name.into_raw(); - type_object.tp_doc = T::DESCRIPTION.as_ptr() as *const _; + + // 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 diff --git a/src/types/complex.rs b/src/types/complex.rs index 071387da..adee578d 100644 --- a/src/types/complex.rs +++ b/src/types/complex.rs @@ -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 { diff --git a/src/types/datetime.rs b/src/types/datetime.rs index 5d8e536b..207c4c5a 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -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> { - 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)( - PyDateTimeAPI.DateTimeType, - args.as_ptr(), - ptr::null_mut(), - ); + #[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 } } diff --git a/src/types/dict.rs b/src/types/dict.rs index b12543b9..429729a0 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -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::(ffi::PyDict_New()); diff --git a/src/types/sequence.rs b/src/types/sequence.rs index 98153544..70b840d8 100644 --- a/src/types/sequence.rs +++ b/src/types/sequence.rs @@ -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(&self, value: V) -> PyResult where V: ToBorrowedObject,