Merge pull request #1341 from nw0/ffi-1
ffi module cleanup: context.h to frameobject.h
This commit is contained in:
commit
fb9ad1e904
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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::*;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -21,4 +21,7 @@ extern "C" {
|
|||
kwdefs: *mut PyObject,
|
||||
closure: *mut PyObject,
|
||||
) -> *mut PyObject;
|
||||
|
||||
// skipped non-limited _PyEval_EvalCodeWithName
|
||||
// skipped non-limited _PyEval_CallTracing
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue