Merge pull request #1341 from nw0/ffi-1

ffi module cleanup: context.h to frameobject.h
This commit is contained in:
David Hewitt 2020-12-28 16:04:43 +00:00 committed by GitHub
commit fb9ad1e904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 586 additions and 414 deletions

View File

@ -9,10 +9,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Add support for `#[pyclass(dict)]` and `#[pyclass(weakref)]` with the `abi3` feature on Python 3.9 and up. [#1342](https://github.com/PyO3/pyo3/pull/1342)
### Changed
- Deprecate FFI definitions `PyEval_CallObjectWithKeywords`, `PyEval_CallObject`, `PyEval_CallFunction`, `PyEval_CallMethod` when building for Python 3.9. [#1338](https://github.com/PyO3/pyo3/pull/1338)
- Deprecate FFI definitions `PyGetSetDef_DICT` and `PyGetSetDef_INIT` which have never been in the Python API. [#1341](https://github.com/PyO3/pyo3/pull/1341)
### Removed
- Remove FFI definition `PyFrame_ClearFreeList` when building for Python 3.9. [#1341](https://github.com/PyO3/pyo3/pull/1341)
- Remove FFI definition `_PyDict_Contains` when building for Python 3.10. [#1341](https://github.com/PyO3/pyo3/pull/1341)
### Fixed
- Stop including `Py_TRACE_REFS` config setting automatically if `Py_DEBUG` is set on Python 3.8 and up. [#1334](https://github.com/PyO3/pyo3/pull/1334)
- Remove `#[deny(warnings)]` attribute (and instead refuse warnings only in CI). [#1340](https://github.com/PyO3/pyo3/pull/1340)
- Deprecate FFI definitions `PyEval_CallObjectWithKeywords`, `PyEval_CallObject`, `PyEval_CallFunction`, `PyEval_CallMethod` when building for Python 3.9. [#1338](https://github.com/PyO3/pyo3/pull/1338)
- Fix deprecation warning for missing `__module__` with `#[pyclass]`. [#1343](https://github.com/PyO3/pyo3/pull/1343)
## [0.13.0] - 2020-12-22

View File

@ -3,21 +3,11 @@ use std::os::raw::{c_char, c_int};
extern "C" {
pub static mut PyContext_Type: PyTypeObject;
// skipped non-limited opaque PyContext
pub static mut PyContextVar_Type: PyTypeObject;
// skipped non-limited opaque PyContextVar
pub static mut PyContextToken_Type: PyTypeObject;
pub fn PyContext_New() -> *mut PyObject;
pub fn PyContext_Copy(ctx: *mut PyObject) -> *mut PyObject;
pub fn PyContext_CopyCurrent() -> *mut PyObject;
pub fn PyContext_Enter(ctx: *mut PyObject) -> c_int;
pub fn PyContext_Exit(ctx: *mut PyObject) -> c_int;
pub fn PyContextVar_New(name: *const c_char, def: *mut PyObject) -> *mut PyObject;
pub fn PyContextVar_Get(
var: *mut PyObject,
default_value: *mut PyObject,
value: *mut *mut PyObject,
) -> c_int;
pub fn PyContextVar_Set(var: *mut PyObject, value: *mut PyObject) -> *mut PyObject;
pub fn PyContextVar_Reset(var: *mut PyObject, token: *mut PyObject) -> c_int;
// skipped non-limited opaque PyContextToken
}
#[inline]
@ -34,3 +24,22 @@ pub unsafe fn PyContextVar_CheckExact(op: *mut PyObject) -> c_int {
pub unsafe fn PyContextToken_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyContextToken_Type) as c_int
}
extern "C" {
pub fn PyContext_New() -> *mut PyObject;
pub fn PyContext_Copy(ctx: *mut PyObject) -> *mut PyObject;
pub fn PyContext_CopyCurrent() -> *mut PyObject;
pub fn PyContext_Enter(ctx: *mut PyObject) -> c_int;
pub fn PyContext_Exit(ctx: *mut PyObject) -> c_int;
pub fn PyContextVar_New(name: *const c_char, def: *mut PyObject) -> *mut PyObject;
pub fn PyContextVar_Get(
var: *mut PyObject,
default_value: *mut PyObject,
value: *mut *mut PyObject,
) -> c_int;
pub fn PyContextVar_Set(var: *mut PyObject, value: *mut PyObject) -> *mut PyObject;
pub fn PyContextVar_Reset(var: *mut PyObject, token: *mut PyObject) -> c_int;
// skipped non-limited _PyContext_NewHamtForTests
}

View File

@ -0,0 +1,63 @@
use crate::ffi::object::*;
use crate::ffi::pyport::Py_ssize_t;
use std::os::raw::c_int;
opaque_struct!(PyDictKeysObject);
#[repr(C)]
#[derive(Debug)]
// Not moved because dict.rs uses PyDictObject extensively.
pub struct PyDictObject {
pub ob_base: PyObject,
pub ma_used: Py_ssize_t,
pub ma_version_tag: u64,
pub ma_keys: *mut PyDictKeysObject,
pub ma_values: *mut *mut PyObject,
}
extern "C" {
// skipped _PyDict_GetItem_KnownHash
// skipped _PyDict_GetItemIdWithError
// skipped _PyDict_GetItemStringWithError
// skipped PyDict_SetDefault
pub fn _PyDict_SetItem_KnownHash(
mp: *mut PyObject,
key: *mut PyObject,
item: *mut PyObject,
hash: crate::ffi::Py_hash_t,
) -> c_int;
// skipped _PyDict_DelItem_KnownHash
// skipped _PyDict_DelItemIf
// skipped _PyDict_NewKeysForClass
pub fn _PyDict_Next(
mp: *mut PyObject,
pos: *mut Py_ssize_t,
key: *mut *mut PyObject,
value: *mut *mut PyObject,
hash: *mut crate::ffi::Py_hash_t,
) -> c_int;
// skipped PyDict_GET_SIZE
// skipped _PyDict_Contains_KnownHash
// skipped _PyDict_ContainsId
pub fn _PyDict_NewPresized(minused: Py_ssize_t) -> *mut PyObject;
// skipped _PyDict_MaybeUntrack
// skipped _PyDict_HasOnlyStringKeys
// skipped _PyDict_KeysSize
// skipped _PyDict_SizeOf
// skipped _PyDict_Pop
// skipped _PyDict_Pop_KnownHash
// skipped _PyDict_FromKeys
// skipped _PyDict_HasSplitTable
// skipped _PyDict_MergeEx
// skipped _PyDict_SetItemId
// skipped _PyDict_DelItemId
// skipped _PyDict_DebugMallocStats
// skipped _PyObjectDict_SetItem
// skipped _PyDict_LoadGlobal
// skipped _PyDict_GetItemHint
// skipped _PyDictViewObject
// skipped _PyDictView_New
// skipped _PyDictView_Intersect
#[cfg(not(Py_3_10))]
pub fn _PyDict_Contains(mp: *mut PyObject, key: *mut PyObject, hash: Py_ssize_t) -> c_int;
}

View File

@ -3,6 +3,9 @@ use crate::ffi::object::*;
use crate::ffi::pystate::PyThreadState;
use std::os::raw::{c_char, c_int};
// skipped _framestate
// skipped PyFrameState
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyTryBlock {
@ -11,6 +14,7 @@ pub struct PyTryBlock {
pub b_level: c_int,
}
/// struct _frame as typedef'ed in pyframe.h
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyFrameObject {
@ -45,6 +49,10 @@ pub struct PyFrameObject {
pub f_localsplus: [*mut PyObject; 1], /* locals+stack, dynamically sized */
}
// skipped _PyFrame_IsRunnable
// skipped _PyFrame_IsExecuting
// skipped _PyFrameHasCompleted
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut PyFrame_Type: PyTypeObject;
@ -63,6 +71,7 @@ extern "C" {
globals: *mut PyObject,
locals: *mut PyObject,
) -> *mut PyFrameObject;
// skipped _PyFrame_New_NoTrack
pub fn PyFrame_BlockSetup(f: *mut PyFrameObject, _type: c_int, handler: c_int, level: c_int);
pub fn PyFrame_BlockPop(f: *mut PyFrameObject) -> *mut PyTryBlock;
@ -71,6 +80,9 @@ extern "C" {
pub fn PyFrame_FastToLocalsWithError(f: *mut PyFrameObject) -> c_int;
pub fn PyFrame_FastToLocals(f: *mut PyFrameObject);
// skipped _PyFrame_DebugMallocStats
// skipped PyFrame_GetBack
#[cfg(not(Py_3_9))]
pub fn PyFrame_ClearFreeList() -> c_int;
pub fn PyFrame_GetLineNumber(f: *mut PyFrameObject) -> c_int;
}

View File

@ -1,11 +1,19 @@
pub mod abstract_;
// skipped bytearrayobject.h
#[cfg(not(PyPy))]
pub mod bytesobject;
pub mod ceval;
pub mod code;
#[cfg(not(PyPy))]
pub mod dictobject;
// skipped fileobject.h
pub mod frameobject;
pub use self::abstract_::*;
#[cfg(not(PyPy))]
pub use self::bytesobject::*;
pub use self::ceval::*;
pub use self::code::*;
#[cfg(not(PyPy))]
pub use self::dictobject::*;
pub use self::frameobject::*;

View File

@ -23,134 +23,42 @@ use {
std::ffi::CString,
};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct PyDateTime_CAPI {
pub DateType: *mut PyTypeObject,
pub DateTimeType: *mut PyTypeObject,
pub TimeType: *mut PyTypeObject,
pub DeltaType: *mut PyTypeObject,
pub TZInfoType: *mut PyTypeObject,
#[cfg(all(Py_3_7, not(PyPy)))]
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,
day: c_int,
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
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,
second: c_int,
microsecond: c_int,
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,
microseconds: c_int,
normalize: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
#[cfg(all(Py_3_7, not(PyPy)))]
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(not(PyPy))]
pub DateTime_FromDateAndTimeAndFold: unsafe extern "C" fn(
year: c_int,
month: c_int,
day: c_int,
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
tzinfo: *mut PyObject,
fold: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
#[cfg(not(PyPy))]
pub Time_FromTimeAndFold: unsafe extern "C" fn(
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
tzinfo: *mut PyObject,
fold: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
}
#[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;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.timedelta`.
pub struct PyDateTime_Delta {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
pub days: c_int,
pub seconds: c_int,
pub microseconds: c_int,
}
// skipped non-limited PyDateTime_TZInfo
// skipped non-limited _PyDateTime_BaseTZInfo
// skipped non-limited _PyDateTime_BaseTime
#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.time`.
pub struct PyDateTime_Time {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
pub hastzinfo: c_char,
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
#[cfg(not(PyPy))]
pub fold: c_uchar,
pub tzinfo: *mut PyObject,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.date`
@ -162,20 +70,7 @@ pub struct PyDateTime_Date {
pub data: [c_uchar; _PyDateTime_DATE_DATASIZE],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.time`
pub struct PyDateTime_Time {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
pub hastzinfo: c_char,
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
#[cfg(not(PyPy))]
pub fold: c_uchar,
pub tzinfo: *mut PyObject,
}
// skipped non-limited _PyDateTime_BaseDateTime
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@ -192,142 +87,7 @@ pub struct PyDateTime_DateTime {
pub tzinfo: *mut PyObject,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
/// Structure representing a `datetime.timedelta`
pub struct PyDateTime_Delta {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t,
pub days: c_int,
pub seconds: c_int,
pub microseconds: c_int,
}
// Python already shares this object between threads, so it's no more evil for us to do it too!
unsafe impl Sync for PyDateTime_CAPI {}
static PY_DATETIME_API: GILOnceCell<&'static PyDateTime_CAPI> = GILOnceCell::new();
#[derive(Debug)]
pub struct PyDateTimeAPI {
__private_field: (),
}
pub static PyDateTimeAPI: PyDateTimeAPI = PyDateTimeAPI {
__private_field: (),
};
impl Deref for PyDateTimeAPI {
type Target = PyDateTime_CAPI;
fn deref(&self) -> &'static PyDateTime_CAPI {
unsafe { PyDateTime_IMPORT() }
}
}
#[inline]
/// Populates the `PyDateTimeAPI` object
///
/// Unlike in C, this does *not* need to be actively invoked in Rust, which
/// will populate the `PyDateTimeAPI` struct automatically on first use.
/// Use this function only if you want to eagerly load the datetime module,
/// such as if you do not want the first call to a datetime function to be
/// slightly slower than subsequent calls.
///
/// # Safety
/// The Python GIL must be held.
pub unsafe fn PyDateTime_IMPORT() -> &'static PyDateTime_CAPI {
let py = Python::assume_gil_acquired();
PY_DATETIME_API.get_or_init(py, || {
// PyPy expects the C-API to be initialized via PyDateTime_Import, so trying to use
// `PyCapsule_Import` will behave unexpectedly in pypy.
#[cfg(PyPy)]
let py_datetime_c_api = PyDateTime_Import();
#[cfg(not(PyPy))]
let py_datetime_c_api = {
// PyDateTime_CAPSULE_NAME is a macro in C
let PyDateTime_CAPSULE_NAME = CString::new("datetime.datetime_CAPI").unwrap();
&*(PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *const PyDateTime_CAPI)
};
py_datetime_c_api
})
}
/// Type Check macros
///
/// These are bindings around the C API typecheck macros, all of them return
/// `1` if True and `0` if False. In all type check macros, the argument (`op`)
/// must not be `NULL`.
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DateType` or subtype.
pub unsafe fn PyDate_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.DateType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DateType`.
pub unsafe fn PyDate_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.DateType) as c_int
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DateTimeType` or subtype.
pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.DateTimeType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DateTimeType`.
pub unsafe fn PyDateTime_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.DateTimeType) as c_int
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.TimeType` or subtype.
pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.TimeType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.TimeType`.
pub unsafe fn PyTime_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.TimeType) as c_int
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DetaType` or subtype.
pub unsafe fn PyDelta_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.DeltaType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DeltaType`.
pub unsafe fn PyDelta_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.DeltaType) as c_int
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.TZInfoType` or subtype.
pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.TZInfoType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.TZInfoType`.
pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.TZInfoType) as c_int
}
/// Accessor functions
#[cfg(not(PyPy))]
macro_rules! _access_field {
($obj:expr, $type: ident, $field:ident) => {
(*($obj as *mut $type)).$field
};
}
// skipped non-limited _PyDateTime_HAS_TZINFO
// Accessor functions for PyDateTime_Date and PyDateTime_DateTime
#[inline]
@ -503,6 +263,14 @@ pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
_PyDateTime_GET_TZINFO!(o as *mut PyDateTime_Time)
}
// Accessor functions
#[cfg(not(PyPy))]
macro_rules! _access_field {
($obj:expr, $type: ident, $field:ident) => {
(*($obj as *mut $type)).$field
};
}
// Accessor functions for PyDateTime_Delta
#[cfg(not(PyPy))]
macro_rules! _access_delta_field {
@ -546,3 +314,268 @@ pub unsafe fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int {
pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int {
_access_delta_field!(o, microseconds)
}
#[cfg(PyPy)]
extern "C" {
// skipped _PyDateTime_HAS_TZINFO (not in PyPy)
#[link_name = "PyPyDateTime_GET_YEAR"]
pub fn PyDateTime_GET_YEAR(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_GET_MONTH"]
pub fn PyDateTime_GET_MONTH(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_GET_DAY"]
pub fn PyDateTime_GET_DAY(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_HOUR"]
pub fn PyDateTime_DATE_GET_HOUR(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_MINUTE"]
pub fn PyDateTime_DATE_GET_MINUTE(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_SECOND"]
pub fn PyDateTime_DATE_GET_SECOND(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DATE_GET_MICROSECOND"]
pub fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int;
// skipped PyDateTime_DATE_GET_FOLD (not in PyPy)
// skipped PyDateTime_DATE_GET_TZINFO (not in PyPy)
#[link_name = "PyPyDateTime_TIME_GET_HOUR"]
pub fn PyDateTime_TIME_GET_HOUR(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_MINUTE"]
pub fn PyDateTime_TIME_GET_MINUTE(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_SECOND"]
pub fn PyDateTime_TIME_GET_SECOND(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_TIME_GET_MICROSECOND"]
pub fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int;
// skipped PyDateTime_TIME_GET_FOLD (not in PyPy)
// skipped PyDateTime_TIME_GET_TZINFO (not in PyPy)
#[link_name = "PyPyDateTime_DELTA_GET_DAYS"]
pub fn PyDateTime_DELTA_GET_DAYS(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DELTA_GET_SECONDS"]
pub fn PyDateTime_DELTA_GET_SECONDS(o: *mut PyObject) -> c_int;
#[link_name = "PyPyDateTime_DELTA_GET_MICROSECONDS"]
pub fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct PyDateTime_CAPI {
pub DateType: *mut PyTypeObject,
pub DateTimeType: *mut PyTypeObject,
pub TimeType: *mut PyTypeObject,
pub DeltaType: *mut PyTypeObject,
pub TZInfoType: *mut PyTypeObject,
#[cfg(all(Py_3_7, not(PyPy)))]
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,
day: c_int,
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
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,
second: c_int,
microsecond: c_int,
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,
microseconds: c_int,
normalize: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
#[cfg(all(Py_3_7, not(PyPy)))]
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(not(PyPy))]
pub DateTime_FromDateAndTimeAndFold: unsafe extern "C" fn(
year: c_int,
month: c_int,
day: c_int,
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
tzinfo: *mut PyObject,
fold: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
#[cfg(not(PyPy))]
pub Time_FromTimeAndFold: unsafe extern "C" fn(
hour: c_int,
minute: c_int,
second: c_int,
microsecond: c_int,
tzinfo: *mut PyObject,
fold: c_int,
cls: *mut PyTypeObject,
) -> *mut PyObject,
}
// Python already shares this object between threads, so it's no more evil for us to do it too!
unsafe impl Sync for PyDateTime_CAPI {}
static PY_DATETIME_API: GILOnceCell<&'static PyDateTime_CAPI> = GILOnceCell::new();
#[derive(Debug)]
pub struct PyDateTimeAPI {
__private_field: (),
}
pub static PyDateTimeAPI: PyDateTimeAPI = PyDateTimeAPI {
__private_field: (),
};
impl Deref for PyDateTimeAPI {
type Target = PyDateTime_CAPI;
fn deref(&self) -> &'static PyDateTime_CAPI {
unsafe { PyDateTime_IMPORT() }
}
}
#[inline]
/// Populates the `PyDateTimeAPI` object
///
/// Unlike in C, this does *not* need to be actively invoked in Rust, which
/// will populate the `PyDateTimeAPI` struct automatically on first use.
/// Use this function only if you want to eagerly load the datetime module,
/// such as if you do not want the first call to a datetime function to be
/// slightly slower than subsequent calls.
///
/// # Safety
/// The Python GIL must be held.
pub unsafe fn PyDateTime_IMPORT() -> &'static PyDateTime_CAPI {
let py = Python::assume_gil_acquired();
PY_DATETIME_API.get_or_init(py, || {
// PyPy expects the C-API to be initialized via PyDateTime_Import, so trying to use
// `PyCapsule_Import` will behave unexpectedly in pypy.
#[cfg(PyPy)]
let py_datetime_c_api = PyDateTime_Import();
#[cfg(not(PyPy))]
let py_datetime_c_api = {
// PyDateTime_CAPSULE_NAME is a macro in C
let PyDateTime_CAPSULE_NAME = CString::new("datetime.datetime_CAPI").unwrap();
&*(PyCapsule_Import(PyDateTime_CAPSULE_NAME.as_ptr(), 1) as *const PyDateTime_CAPI)
};
py_datetime_c_api
})
}
// skipped non-limited PyDateTime_TimeZone_UTC
/// Type Check macros
///
/// These are bindings around the C API typecheck macros, all of them return
/// `1` if True and `0` if False. In all type check macros, the argument (`op`)
/// must not be `NULL`.
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DateType` or subtype.
pub unsafe fn PyDate_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.DateType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DateType`.
pub unsafe fn PyDate_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.DateType) as c_int
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DateTimeType` or subtype.
pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.DateTimeType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DateTimeType`.
pub unsafe fn PyDateTime_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.DateTimeType) as c_int
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.TimeType` or subtype.
pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.TimeType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.TimeType`.
pub unsafe fn PyTime_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.TimeType) as c_int
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.DetaType` or subtype.
pub unsafe fn PyDelta_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.DeltaType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.DeltaType`.
pub unsafe fn PyDelta_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.DeltaType) as c_int
}
#[inline]
/// Check if `op` is a `PyDateTimeAPI.TZInfoType` or subtype.
pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, PyDateTimeAPI.TZInfoType) as c_int
}
#[inline]
/// Check if `op`'s type is exactly `PyDateTimeAPI.TZInfoType`.
pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == PyDateTimeAPI.TZInfoType) as c_int
}
// skipped non-limited PyDate_FromDate
// skipped non-limited PyDateTime_FromDateAndTime
// skipped non-limited PyDateTime_FromDateAndTimeAndFold
// skipped non-limited PyTime_FromTime
// skipped non-limited PyTime_FromTimeAndFold
// skipped non-limited PyDelta_FromDSU
// skipped non-limited PyTimeZone_FromOffset
// skipped non-limited PyTimeZone_FromOffsetAndName
#[cfg(PyPy)]
extern "C" {
#[link_name = "PyPyDate_FromTimestamp"]
pub fn PyDate_FromTimestamp(args: *mut PyObject) -> *mut PyObject;
#[link_name = "PyPyDateTime_FromTimestamp"]
pub fn PyDateTime_FromTimestamp(args: *mut PyObject) -> *mut PyObject;
}
#[cfg(PyPy)]
extern "C" {
#[link_name = "_PyPyDateTime_Import"]
pub fn PyDateTime_Import() -> &'static PyDateTime_CAPI;
}

View File

@ -20,27 +20,19 @@ pub struct PyGetSetDef {
pub closure: *mut c_void,
}
pub const PyGetSetDef_INIT: PyGetSetDef = PyGetSetDef {
name: ptr::null_mut(),
get: None,
set: None,
doc: ptr::null_mut(),
closure: ptr::null_mut(),
};
// skipped non-limited wrapperfunc
// skipped non-limited wrapperfunc_kwds
// skipped non-limited struct wrapperbase
// skipped non-limited PyWrapperFlag_KEYWORDS
#[cfg(any(PyPy, Py_LIMITED_API))]
pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef_INIT;
// PyPy doesn't export neither PyObject_GenericGetDict/PyObject_GenericSetDict
// Py_LIMITED_API exposes PyObject_GenericSetDict but not Get.
#[cfg(all(not(PyPy), not(Py_LIMITED_API)))]
pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef {
name: "__dict__\0".as_ptr() as *mut c_char,
get: Some(PyObject_GenericGetDict),
set: Some(PyObject_GenericSetDict),
doc: ptr::null_mut(),
closure: ptr::null_mut(),
};
// skipped non-limited PyDescrObject
// skipped non-limited PyDescr_COMMON
// skipped non-limited PyDescr_TYPE
// skipped non-limited PyDescr_NAME
// skipped non-limited PyMethodDescrObject
// skipped non-limited PyMemberDescrObject
// skipped non-limited PyGetSetDescrObject
// skipped non-limited PyWrapperDescrObject
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
@ -56,6 +48,7 @@ extern "C" {
pub static mut PyWrapperDescr_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyDictProxy_Type")]
pub static mut PyDictProxy_Type: PyTypeObject;
// skipped non-limited _PyMethodWrapper_Type
}
extern "C" {
@ -65,6 +58,8 @@ extern "C" {
-> *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;
// skipped non-limited PyDescr_NewWrapper
// skipped non-limited PyDescr_IsData
#[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;
@ -72,3 +67,35 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyProperty_Type")]
pub static mut PyProperty_Type: PyTypeObject;
}
/// Helper initial value of [`PyGetSetDef`] for a Python class.
///
/// Not present in `cpython/Include/descrobject`.
#[deprecated(note = "not present in Python headers; to be removed")]
pub const PyGetSetDef_INIT: PyGetSetDef = PyGetSetDef {
name: ptr::null_mut(),
get: None,
set: None,
doc: ptr::null_mut(),
closure: ptr::null_mut(),
};
#[cfg(any(PyPy, Py_LIMITED_API))]
#[deprecated(note = "not present in Python headers; to be removed")]
#[allow(deprecated)]
pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef_INIT;
/// Helper initial value of [`PyGetSetDef`] for a dict-like Python class.
///
/// Not present in `cpython/Include/descrobject.h`.
// PyPy doesn't export neither PyObject_GenericGetDict/PyObject_GenericSetDict
// Py_LIMITED_API exposes PyObject_GenericSetDict but not Get.
#[cfg(all(not(PyPy), not(Py_LIMITED_API)))]
#[deprecated(note = "not present in Python headers; to be removed")]
pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef {
name: "__dict__\0".as_ptr() as *mut c_char,
get: Some(PyObject_GenericGetDict),
set: Some(PyObject_GenericSetDict),
doc: ptr::null_mut(),
closure: ptr::null_mut(),
};

View File

@ -6,33 +6,6 @@ use std::os::raw::{c_char, c_int};
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyDict_Type")]
pub static mut PyDict_Type: PyTypeObject;
pub static mut PyDictIterKey_Type: PyTypeObject;
pub static mut PyDictIterValue_Type: PyTypeObject;
pub static mut PyDictIterItem_Type: PyTypeObject;
pub static mut PyDictKeys_Type: PyTypeObject;
pub static mut PyDictItems_Type: PyTypeObject;
pub static mut PyDictValues_Type: PyTypeObject;
#[cfg(Py_3_8)]
pub static mut PyDictRevIterKey_Type: PyTypeObject;
#[cfg(Py_3_8)]
pub static mut PyDictRevIterValue_Type: PyTypeObject;
#[cfg(Py_3_8)]
pub static mut PyDictRevIterItem_Type: PyTypeObject;
}
#[repr(C)]
pub struct PyDictKeysObject {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug)]
pub struct PyDictObject {
pub ob_base: PyObject,
pub ma_used: Py_ssize_t,
pub ma_version_tag: u64,
pub ma_keys: *mut PyDictKeysObject,
pub ma_values: *mut *mut PyObject,
}
#[inline]
@ -45,43 +18,14 @@ pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDict_Type) as c_int
}
#[inline]
pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictKeys_Type) as c_int
}
#[inline]
pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictItems_Type) as c_int
}
#[inline]
pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictValues_Type) as c_int
}
#[inline]
pub unsafe fn PyDictViewSet_Check(op: *mut PyObject) -> c_int {
(PyDictKeys_Check(op) != 0 || PyDictItems_Check(op) != 0) as c_int
}
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyDict_New")]
pub fn PyDict_New() -> *mut PyObject;
#[cfg(not(PyPy))]
pub fn _PyDict_NewPresized(minused: Py_ssize_t) -> *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(not(PyPy))]
pub fn _PyDict_SetItem_KnownHash(
mp: *mut PyObject,
key: *mut PyObject,
item: *mut PyObject,
hash: crate::ffi::Py_hash_t,
) -> 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")]
@ -93,14 +37,6 @@ extern "C" {
key: *mut *mut PyObject,
value: *mut *mut PyObject,
) -> c_int;
#[cfg(not(PyPy))]
pub fn _PyDict_Next(
mp: *mut PyObject,
pos: *mut Py_ssize_t,
key: *mut *mut PyObject,
value: *mut *mut PyObject,
hash: *mut crate::ffi::Py_hash_t,
) -> 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")]
@ -113,8 +49,6 @@ extern "C" {
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(not(PyPy))]
pub fn _PyDict_Contains(mp: *mut PyObject, key: *mut PyObject, hash: Py_ssize_t) -> 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")]
@ -130,6 +64,49 @@ extern "C" {
) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyDict_DelItemString")]
pub fn PyDict_DelItemString(dp: *mut PyObject, key: *const c_char) -> c_int;
#[cfg(not(PyPy))]
pub fn _PyObject_GetDictPtr(obj: *mut PyObject) -> *mut *mut PyObject;
// skipped 3.10 / ex-non-limited PyObject_GenericGetDict
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut PyDictKeys_Type: PyTypeObject;
pub static mut PyDictValues_Type: PyTypeObject;
pub static mut PyDictItems_Type: PyTypeObject;
}
#[inline]
pub unsafe fn PyDictKeys_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictKeys_Type) as c_int
}
#[inline]
pub unsafe fn PyDictValues_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictValues_Type) as c_int
}
#[inline]
pub unsafe fn PyDictItems_Check(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictItems_Type) as c_int
}
#[inline]
pub unsafe fn PyDictViewSet_Check(op: *mut PyObject) -> c_int {
(PyDictKeys_Check(op) != 0 || PyDictItems_Check(op) != 0) as c_int
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut PyDictIterKey_Type: PyTypeObject;
pub static mut PyDictIterValue_Type: PyTypeObject;
pub static mut PyDictIterItem_Type: PyTypeObject;
#[cfg(Py_3_8)]
pub static mut PyDictRevIterKey_Type: PyTypeObject;
#[cfg(Py_3_8)]
pub static mut PyDictRevIterValue_Type: PyTypeObject;
#[cfg(Py_3_8)]
pub static mut PyDictRevIterItem_Type: PyTypeObject;
}
#[cfg(any(PyPy, Py_LIMITED_API))]
// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985)
opaque_struct!(PyDictObject);

View File

@ -21,4 +21,7 @@ extern "C" {
kwdefs: *mut PyObject,
closure: *mut PyObject,
) -> *mut PyObject;
// skipped non-limited _PyEval_EvalCodeWithName
// skipped non-limited _PyEval_CallTracing
}

View File

@ -14,14 +14,14 @@ extern "C" {
arg7: *const c_char,
arg8: c_int,
) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyFile_AsFileDescriptor")]
pub fn PyObject_AsFileDescriptor(arg1: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyFile_GetLine")]
pub fn PyFile_GetLine(arg1: *mut PyObject, arg2: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyFile_WriteObject")]
pub fn PyFile_WriteObject(arg1: *mut PyObject, arg2: *mut PyObject, arg3: c_int) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyFile_WriteString")]
pub fn PyFile_WriteString(arg1: *const c_char, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyFile_AsFileDescriptor")]
pub fn PyObject_AsFileDescriptor(arg1: *mut PyObject) -> c_int;
}
#[cfg_attr(windows, link(name = "pythonXY"))]
@ -29,4 +29,7 @@ extern "C" {
pub static mut Py_FileSystemDefaultEncoding: *const c_char;
pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char;
pub static mut Py_HasFileSystemDefaultEncoding: c_int;
// skipped Python 3.7 / ex-non-limited Py_UTF8Mode
}
// skipped _PyIsSelectable_fd

View File

@ -1,6 +1,11 @@
use crate::ffi::object::*;
use std::os::raw::{c_double, c_int};
#[cfg(Py_LIMITED_API)]
// TODO: remove (see https://github.com/PyO3/pyo3/pull/1341#issuecomment-751515985)
opaque_struct!(PyFloatObject);
#[cfg(not(Py_LIMITED_API))]
#[repr(C)]
pub struct PyFloatObject {
pub ob_base: PyObject,
@ -23,11 +28,8 @@ pub unsafe fn PyFloat_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyFloat_Type) as c_int
}
#[cfg(not(Py_LIMITED_API))]
#[inline]
pub unsafe fn PyFloat_AS_DOUBLE(op: *mut PyObject) -> c_double {
(*(op as *mut PyFloatObject)).ob_fval
}
// skipped Py_RETURN_NAN
// skipped Py_RETURN_INF
extern "C" {
pub fn PyFloat_GetMax() -> c_double;
@ -40,3 +42,18 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyFloat_AsDouble")]
pub fn PyFloat_AsDouble(arg1: *mut PyObject) -> c_double;
}
#[cfg(not(Py_LIMITED_API))]
#[inline]
pub unsafe fn PyFloat_AS_DOUBLE(op: *mut PyObject) -> c_double {
(*(op as *mut PyFloatObject)).ob_fval
}
// skipped non-limited _PyFloat_Pack2
// skipped non-limited _PyFloat_Pack4
// skipped non-limited _PyFloat_Pack8
// skipped non-limited _PyFloat_Unpack2
// skipped non-limited _PyFloat_Unpack4
// skipped non-limited _PyFloat_Unpack8
// skipped non-limited _PyFloat_DebugMallocStats
// skipped non-limited _PyFloat_FormatAdvancedWriter

View File

@ -1,6 +1,6 @@
use crate::ffi::frameobject::PyFrameObject;
use crate::ffi::object::*;
use crate::ffi::pyport::Py_ssize_t;
use crate::ffi::PyFrameObject;
use std::os::raw::c_int;
#[repr(C)]

View File

@ -30,7 +30,6 @@ pub use self::enumobject::*;
pub use self::eval::*;
pub use self::fileobject::*;
pub use self::floatobject::*;
pub use self::frameobject::PyFrameObject;
pub use self::funcobject::*;
pub use self::genobject::*;
pub use self::import::*;
@ -53,6 +52,7 @@ pub use self::pyarena::*;
pub use self::pycapsule::*;
pub use self::pydebug::*;
pub use self::pyerrors::*;
pub use self::pyframe::*;
pub use self::pyhash::*;
pub use self::pylifecycle::*;
pub use self::pymem::*;
@ -79,22 +79,37 @@ pub use self::cpython::*;
// skipped asdl.h
// skipped ast.h
mod bltinmodule;
mod boolobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod boolobject; // TODO supports PEP-384 only
mod bytearrayobject;
mod bytesobject;
// skipped cellobject.h
mod ceval; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod ceval; // TODO supports PEP-384 only
// skipped classobject.h
mod code;
mod codecs; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod codecs; // TODO supports PEP-384 only
mod compile; // TODO: incomplete
mod complexobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod complexobject; // TODO supports PEP-384 only
#[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
mod context; // It's actually 3.7.1, but no cfg for patches.
#[cfg(not(all(Py_3_8, not(Py_LIMITED_API))))]
mod context {}
#[cfg(not(Py_LIMITED_API))]
pub(crate) mod datetime;
mod descrobject; // TODO supports PEP-384 only
mod dictobject;
// skipped dynamic_annotations.h
mod enumobject;
// skipped errcode.h
mod eval; // TODO supports PEP-384 only
// skipped exports.h
mod fileobject; // TODO: incomplete
// skipped fileutils.h
mod floatobject; // TODO supports PEP-384 only
// skipped empty frameobject.h
// skipped genericaliasobject.h
// skipped interpreteridobject.h
// skipped longintrepr.h
@ -111,7 +126,8 @@ mod complexobject; // TODO supports PEP-384 only; needs adjustment for Python 3.
// skipped pydtrace.h
// skipped pyexpat.h
// skipped pyfpe.h
// skipped pyframe.h
mod pyframe; // TODO: incomplete
// skipped pymacconfig.h
// skipped pymacro.h
// skipped pymath.h
@ -142,25 +158,20 @@ mod typeslots;
mod longobject;
mod unicodeobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod longintrepr; TODO excluded by PEP-384
mod dictobject;
mod floatobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod listobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod memoryobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod rangeobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod tupleobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod odictobject; TODO new in 3.5
mod enumobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod methodobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod moduleobject;
mod setobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod funcobject; TODO excluded by PEP-384
// mod classobject; TODO excluded by PEP-384
mod fileobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod pycapsule; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod sliceobject;
mod traceback; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod cellobject; TODO excluded by PEP-384
mod descrobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod genobject; // TODO excluded by PEP-384
mod iterobject; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod structseq;
@ -185,14 +196,6 @@ mod sysmodule; // TODO supports PEP-384 only; needs adjustment for Python 3.3 an
mod objectabstract; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
#[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
mod context; // It's actually 3.7.1, but no cfg for patches.
#[cfg(not(all(Py_3_8, not(Py_LIMITED_API))))]
mod context {}
mod eval; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod pyctype; TODO excluded by PEP-384
mod pystrtod; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
// mod pystrcmp; TODO nothing interesting for Rust?
@ -203,15 +206,6 @@ mod pystrtod; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and
// Additional headers that are not exported by Python.h
pub mod structmember; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
#[cfg(not(Py_LIMITED_API))]
pub mod frameobject;
#[cfg(Py_LIMITED_API)]
pub mod frameobject {
opaque_struct!(PyFrameObject);
}
#[cfg(not(Py_LIMITED_API))]
pub(crate) mod datetime;
pub(crate) mod marshal;
pub(crate) mod funcobject;

View File

@ -892,3 +892,8 @@ pub fn PyObject_Check(_arg1: *mut PyObject) -> c_int {
pub fn PySuper_Check(_arg1: *mut PyObject) -> c_int {
0
}
#[cfg(not(PyPy))]
extern "C" {
pub fn _PyObject_GetDictPtr(obj: *mut PyObject) -> *mut *mut PyObject;
}

12
src/ffi/pyframe.rs Normal file
View File

@ -0,0 +1,12 @@
#[cfg(not(Py_LIMITED_API))]
use crate::ffi::PyFrameObject;
use std::os::raw::c_int;
#[cfg(Py_LIMITED_API)]
opaque_struct!(PyFrameObject);
extern "C" {
pub fn PyFrame_GetLineNumber(f: *mut PyFrameObject) -> c_int;
}
// skipped PyFrame_GetLineNumber
// skipped PyFrame_GetCode

View File

@ -1,7 +1,7 @@
use crate::ffi::ceval::_PyFrameEvalFunction;
use crate::ffi::frameobject::PyFrameObject;
use crate::ffi::moduleobject::PyModuleDef;
use crate::ffi::object::PyObject;
use crate::ffi::PyFrameObject;
use std::os::raw::{c_int, c_long};
pub const MAX_CO_EXTRA_USERS: c_int = 255;

View File

@ -391,6 +391,7 @@ fn py_class_properties<T: PyClass>() -> Vec<ffi::PyGetSetDef> {
match def {
PyMethodDefType::Getter(getter) => {
if !defs.contains_key(getter.name) {
#[allow(deprecated)]
let _ = defs.insert(getter.name.to_owned(), ffi::PyGetSetDef_INIT);
}
let def = defs.get_mut(getter.name).expect("Failed to call get_mut");
@ -398,6 +399,7 @@ fn py_class_properties<T: PyClass>() -> Vec<ffi::PyGetSetDef> {
}
PyMethodDefType::Setter(setter) => {
if !defs.contains_key(setter.name) {
#[allow(deprecated)]
let _ = defs.insert(setter.name.to_owned(), ffi::PyGetSetDef_INIT);
}
let def = defs.get_mut(setter.name).expect("Failed to call get_mut");