diff --git a/CHANGELOG.md b/CHANGELOG.md index 774c8507..e2894da0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Use `parking_lot::Mutex` instead of `spin::Mutex`. [#734](https://github.com/PyO3/pyo3/pull/734) * Bumped minimum Rust version to `1.42.0-nightly 2020-01-21`. [#761](https://github.com/PyO3/pyo3/pull/761) * `PyRef` and `PyRefMut` are renewed for `PyCell`. [#770](https://github.com/PyO3/pyo3/pull/770) +* Some new FFI functions for Python 3.8. [#784](https://github.com/PyO3/pyo3/pull/784) ### Added * `PyCell`, which has RefCell-like features. [#770](https://github.com/PyO3/pyo3/pull/770) diff --git a/src/ffi/ceval.rs b/src/ffi/ceval.rs index 34238292..f5265c75 100644 --- a/src/ffi/ceval.rs +++ b/src/ffi/ceval.rs @@ -90,5 +90,6 @@ extern "C" { pub fn PyEval_AcquireThread(tstate: *mut PyThreadState) -> (); #[cfg_attr(PyPy, link_name = "PyPyEval_ReleaseThread")] pub fn PyEval_ReleaseThread(tstate: *mut PyThreadState) -> (); + #[cfg(not(Py_3_8))] pub fn PyEval_ReInitThreads() -> (); } diff --git a/src/ffi/code.rs b/src/ffi/code.rs index 05609269..6ee9f799 100644 --- a/src/ffi/code.rs +++ b/src/ffi/code.rs @@ -2,6 +2,9 @@ use crate::ffi::object::*; use crate::ffi::pyport::Py_ssize_t; use std::os::raw::{c_char, c_int, c_uchar, c_void}; +#[cfg(Py_3_8)] +pub enum _PyOpcache {} + #[repr(C)] #[derive(Copy, Clone)] pub struct PyCodeObject { @@ -29,6 +32,14 @@ pub struct PyCodeObject { pub co_weakreflist: *mut PyObject, #[cfg(Py_3_6)] pub co_extra: *mut c_void, + #[cfg(Py_3_8)] + pub co_opcache_map: *mut c_uchar, + #[cfg(Py_3_8)] + pub co_opcache: *mut _PyOpcache, + #[cfg(Py_3_8)] + pub co_opcache_flag: c_int, + #[cfg(Py_3_8)] + pub co_opcache_size: c_uchar, } /* Masks for co_flags */ @@ -77,21 +88,40 @@ extern "C" { #[cfg_attr(PyPy, link_name = "PyPyCode_New")] pub fn PyCode_New( - arg1: c_int, - arg2: c_int, - arg3: c_int, - arg4: c_int, - arg5: c_int, - arg6: *mut PyObject, - arg7: *mut PyObject, - arg8: *mut PyObject, - arg9: *mut PyObject, - arg10: *mut PyObject, - arg11: *mut PyObject, - arg12: *mut PyObject, - arg13: *mut PyObject, - arg14: c_int, - arg15: *mut PyObject, + argcount: c_int, + kwonlyargcount: c_int, + nlocals: c_int, + stacksize: c_int, + flags: c_int, + code: *mut PyObject, + consts: *mut PyObject, + names: *mut PyObject, + varnames: *mut PyObject, + freevars: *mut PyObject, + cellvars: *mut PyObject, + filename: *mut PyObject, + name: *mut PyObject, + firstlineno: c_int, + lnotab: *mut PyObject, + ) -> *mut PyCodeObject; + #[cfg(Py_3_8)] + pub fn PyCode_NewWithPosOnlyArgs( + argcount: c_int, + posonlyargcount: c_int, + kwonlyargcount: c_int, + nlocals: c_int, + stacksize: c_int, + flags: c_int, + code: *mut PyObject, + consts: *mut PyObject, + names: *mut PyObject, + varnames: *mut PyObject, + freevars: *mut PyObject, + cellvars: *mut PyObject, + filename: *mut PyObject, + name: *mut PyObject, + firstlineno: c_int, + lnotab: *mut PyObject, ) -> *mut PyCodeObject; #[cfg_attr(PyPy, link_name = "PyPyCode_NewEmpty")] pub fn PyCode_NewEmpty( diff --git a/src/ffi/compile.rs b/src/ffi/compile.rs index 11386762..03e13951 100644 --- a/src/ffi/compile.rs +++ b/src/ffi/compile.rs @@ -60,8 +60,13 @@ extern "C" { ) -> *mut PyFutureFeatures; pub fn PyCompile_OpcodeStackEffect(opcode: c_int, oparg: c_int) -> c_int; + + #[cfg(Py_3_8)] + pub fn PyCompile_OpcodeStackEffectWithJump(opcode: c_int, oparg: c_int, jump: c_int) -> c_int; } pub const Py_single_input: c_int = 256; pub const Py_file_input: c_int = 257; pub const Py_eval_input: c_int = 258; +#[cfg(Py_3_8)] +pub const Py_func_type_input: c_int = 345; diff --git a/src/ffi/dictobject.rs b/src/ffi/dictobject.rs index 5db462c1..eb3cbf6c 100644 --- a/src/ffi/dictobject.rs +++ b/src/ffi/dictobject.rs @@ -1,5 +1,5 @@ use crate::ffi::object::*; -use crate::ffi::pyport::{Py_hash_t, Py_ssize_t}; +use crate::ffi::pyport::Py_ssize_t; use std::os::raw::{c_char, c_int}; #[cfg_attr(windows, link(name = "pythonXY"))] @@ -11,6 +11,12 @@ extern "C" { 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)] @@ -73,7 +79,7 @@ extern "C" { mp: *mut PyObject, key: *mut PyObject, item: *mut PyObject, - hash: Py_hash_t, + hash: crate::ffi::pyport::Py_hash_t, ) -> c_int; #[cfg_attr(PyPy, link_name = "PyPyDict_DelItem")] pub fn PyDict_DelItem(mp: *mut PyObject, key: *mut PyObject) -> c_int; diff --git a/src/ffi/object.rs b/src/ffi/object.rs index 066567a4..6ceb6d3b 100644 --- a/src/ffi/object.rs +++ b/src/ffi/object.rs @@ -241,6 +241,13 @@ pub type newfunc = unsafe extern "C" fn( ) -> *mut PyObject; pub type allocfunc = unsafe extern "C" fn(arg1: *mut PyTypeObject, arg2: Py_ssize_t) -> *mut PyObject; +#[cfg(Py_3_8)] +pub type vectorcallfunc = unsafe extern "C" fn( + callable: *mut PyObject, + args: *const *mut PyObject, + nargsf: libc::size_t, + kwnames: *mut PyObject, +) -> *mut PyObject; #[cfg(Py_LIMITED_API)] mod typeobject { @@ -492,23 +499,25 @@ mod typeobject { pub tp_members: *mut ffi::structmember::PyMemberDef, pub tp_getset: *mut ffi::descrobject::PyGetSetDef, pub tp_base: *mut PyTypeObject, - pub tp_dict: *mut ffi::object::PyObject, - pub tp_descr_get: Option, - pub tp_descr_set: Option, + pub tp_dict: *mut object::PyObject, + pub tp_descr_get: Option, + pub tp_descr_set: Option, pub tp_dictoffset: Py_ssize_t, - pub tp_init: Option, - pub tp_alloc: Option, - pub tp_new: Option, - pub tp_free: Option, - pub tp_is_gc: Option, - pub tp_bases: *mut ffi::object::PyObject, - pub tp_mro: *mut ffi::object::PyObject, - pub tp_cache: *mut ffi::object::PyObject, - pub tp_subclasses: *mut ffi::object::PyObject, - pub tp_weaklist: *mut ffi::object::PyObject, - pub tp_del: Option, + pub tp_init: Option, + pub tp_alloc: Option, + pub tp_new: Option, + pub tp_free: Option, + pub tp_is_gc: Option, + pub tp_bases: *mut object::PyObject, + pub tp_mro: *mut object::PyObject, + pub tp_cache: *mut object::PyObject, + pub tp_subclasses: *mut object::PyObject, + pub tp_weaklist: *mut object::PyObject, + pub tp_del: Option, pub tp_version_tag: c_uint, - pub tp_finalize: Option, + pub tp_finalize: Option, + #[cfg(Py_3_8)] + pub tp_vectorcall: Option, #[cfg(PyPy)] pub tp_pypy_flags: ::std::os::raw::c_long, #[cfg(py_sys_config = "COUNT_ALLOCS")] @@ -524,7 +533,7 @@ mod typeobject { } macro_rules! _type_object_init { - ({$($head:tt)*} $tp_as_async:ident, $($tail:tt)*) => { + ({$($head:tt)*}, $($tail:tt)*) => { as_expr! { PyTypeObject { $($head)* @@ -538,7 +547,7 @@ mod typeobject { tp_vectorcall_offset: 0, tp_getattr: None, tp_setattr: None, - $tp_as_async: ptr::null_mut(), + tp_as_async: ptr::null_mut(), tp_repr: None, tp_as_number: ptr::null_mut(), tp_as_sequence: ptr::null_mut(), @@ -549,7 +558,7 @@ mod typeobject { tp_getattro: None, tp_setattro: None, tp_as_buffer: ptr::null_mut(), - tp_flags: ffi::object::Py_TPFLAGS_DEFAULT, + tp_flags: object::Py_TPFLAGS_DEFAULT, tp_doc: ptr::null(), tp_traverse: None, tp_clear: None, @@ -577,6 +586,9 @@ mod typeobject { tp_weaklist: ptr::null_mut(), tp_del: None, tp_version_tag: 0, + tp_finalize: None, + #[cfg(Py_3_8)] + tp_vectorcall: None, $($tail)* } } @@ -584,15 +596,14 @@ mod typeobject { } #[cfg(PyPy)] - macro_rules! py_type_object_init { - ($tp_as_async:ident, $($tail:tt)*) => { + macro_rules! type_object_init { + ($($tail:tt)*) => { _type_object_init!({ ob_refcnt: 1, ob_pypy_link: 0, ob_type: ptr::null_mut(), ob_size: 0, - } - $tp_as_async, + }, tp_pypy_flags: 0, $($tail)* ) @@ -600,42 +611,29 @@ mod typeobject { } #[cfg(not(PyPy))] - macro_rules! py_type_object_init { - ($tp_as_async:ident, $($tail:tt)*) => { + macro_rules! type_object_init { + ($($tail:tt)*) => { _type_object_init!({ - ob_base: ffi::object::PyVarObject { - ob_base: ffi::object::PyObject_HEAD_INIT, + ob_base: object::PyVarObject { + ob_base: object::PyObject_HEAD_INIT, ob_size: 0 - },} - $tp_as_async, + },}, $($tail)* ) } } #[cfg(py_sys_config = "COUNT_ALLOCS")] - macro_rules! py_type_object_init_with_count_allocs { - ($tp_as_async:ident, $($tail:tt)*) => { - py_type_object_init!($tp_as_async, - $($tail)* - tp_allocs: 0, - tp_frees: 0, - tp_maxalloc: 0, - tp_prev: ptr::null_mut(), - tp_next: ptr::null_mut(), - ) - } - } + pub const PyTypeObject_INIT: PyTypeObject = type_object_init! { + tp_allocs: 0, + tp_frees: 0, + tp_maxalloc: 0, + tp_prev: ptr::null_mut(), + tp_next: ptr::null_mut(), + }; #[cfg(not(py_sys_config = "COUNT_ALLOCS"))] - macro_rules! py_type_object_init_with_count_allocs { - ($tp_as_async:ident, $($tail:tt)*) => { - py_type_object_init!($tp_as_async, $($tail)*) - } - } - - pub const PyTypeObject_INIT: PyTypeObject = - py_type_object_init_with_count_allocs!(tp_as_async, tp_finalize: None,); + pub const PyTypeObject_INIT: PyTypeObject = type_object_init!(); #[repr(C)] #[derive(Copy, Clone)] @@ -646,9 +644,9 @@ mod typeobject { pub as_mapping: PyMappingMethods, pub as_sequence: PySequenceMethods, pub as_buffer: PyBufferProcs, - pub ht_name: *mut ffi::object::PyObject, - pub ht_slots: *mut ffi::object::PyObject, - pub ht_qualname: *mut ffi::object::PyObject, + pub ht_name: *mut object::PyObject, + pub ht_slots: *mut object::PyObject, + pub ht_qualname: *mut object::PyObject, pub ht_cached_keys: *mut c_void, } @@ -663,7 +661,7 @@ mod typeobject { pub unsafe fn PyHeapType_GET_MEMBERS( etype: *mut PyHeapTypeObject, ) -> *mut ffi::structmember::PyMemberDef { - let py_type = ffi::object::Py_TYPE(etype as *mut ffi::object::PyObject); + let py_type = object::Py_TYPE(etype as *mut object::PyObject); let ptr = etype.offset((*py_type).tp_basicsize); ptr as *mut ffi::structmember::PyMemberDef }