From 72b8ffc588303460ef28b50698ee52eab79be00c Mon Sep 17 00:00:00 2001 From: Dean Li Date: Thu, 26 Aug 2021 18:09:29 +0800 Subject: [PATCH] ffi: cleanup pythonrun Move multiple limited api to cpython. Many API in `pythonrun` are removed in python 3.10. There is also some function and macro share the same name (documented below) in cpython, which I choose to skip macro definition. - PyRun_String - PyRun_AnyFile - PyRun_AnyFileEx - PyRun_AnyFileFlags --- src/ffi/cpython/compile.rs | 13 +- src/ffi/cpython/mod.rs | 2 + src/ffi/cpython/pythonrun.rs | 240 +++++++++++++++++++++++++++++++++++ src/ffi/pythonrun.rs | 203 +++++------------------------ 4 files changed, 289 insertions(+), 169 deletions(-) create mode 100644 src/ffi/cpython/pythonrun.rs diff --git a/src/ffi/cpython/compile.rs b/src/ffi/cpython/compile.rs index a8b4bde4..4308730e 100644 --- a/src/ffi/cpython/compile.rs +++ b/src/ffi/cpython/compile.rs @@ -1,8 +1,14 @@ +#[cfg(not(Py_3_10))] use crate::ffi::object::PyObject; +#[cfg(not(Py_3_10))] use crate::ffi::pyarena::*; +#[cfg(not(Py_3_10))] use crate::ffi::pythonrun::*; +#[cfg(not(Py_3_10))] use crate::ffi::PyCodeObject; -use std::os::raw::{c_char, c_int}; +#[cfg(not(Py_3_10))] +use std::os::raw::c_char; +use std::os::raw::c_int; // skipped non-limited PyCF_MASK // skipped non-limited PyCF_MASK_OBSOLETE @@ -36,8 +42,10 @@ pub const FUTURE_GENERATOR_STOP: &str = "generator_stop"; // skipped non-limited FUTURE_ANNOTATIONS extern "C" { + #[cfg(not(Py_3_10))] pub fn PyNode_Compile(arg1: *mut _node, arg2: *const c_char) -> *mut PyCodeObject; + #[cfg(not(Py_3_10))] pub fn PyAST_CompileEx( _mod: *mut _mod, filename: *const c_char, @@ -46,6 +54,7 @@ extern "C" { arena: *mut PyArena, ) -> *mut PyCodeObject; + #[cfg(not(Py_3_10))] pub fn PyAST_CompileObject( _mod: *mut _mod, filename: *mut PyObject, @@ -54,8 +63,10 @@ extern "C" { arena: *mut PyArena, ) -> *mut PyCodeObject; + #[cfg(not(Py_3_10))] pub fn PyFuture_FromAST(_mod: *mut _mod, filename: *const c_char) -> *mut PyFutureFeatures; + #[cfg(not(Py_3_10))] pub fn PyFuture_FromASTObject( _mod: *mut _mod, filename: *mut PyObject, diff --git a/src/ffi/cpython/mod.rs b/src/ffi/cpython/mod.rs index b1701d17..35341304 100644 --- a/src/ffi/cpython/mod.rs +++ b/src/ffi/cpython/mod.rs @@ -20,6 +20,7 @@ pub(crate) mod pydebug; #[cfg(all(Py_3_8, not(PyPy)))] pub(crate) mod pylifecycle; pub(crate) mod pystate; +pub(crate) mod pythonrun; pub(crate) mod unicodeobject; pub use self::abstract_::*; @@ -41,4 +42,5 @@ pub use self::pydebug::*; #[cfg(all(Py_3_8, not(PyPy)))] pub use self::pylifecycle::*; pub use self::pystate::*; +pub use self::pythonrun::*; pub use self::unicodeobject::*; diff --git a/src/ffi/cpython/pythonrun.rs b/src/ffi/cpython/pythonrun.rs new file mode 100644 index 00000000..058dc172 --- /dev/null +++ b/src/ffi/cpython/pythonrun.rs @@ -0,0 +1,240 @@ +use crate::ffi::object::*; +#[cfg(all(not(Py_LIMITED_API), not(Py_3_10)))] +use crate::ffi::pyarena::PyArena; +use crate::ffi::PyCompilerFlags; +#[cfg(not(Py_3_10))] +use crate::ffi::{_mod, _node}; +use libc::FILE; +use std::os::raw::{c_char, c_int}; + +extern "C" { + pub fn PyRun_SimpleStringFlags(arg1: *const c_char, arg2: *mut PyCompilerFlags) -> c_int; + pub fn _PyRun_SimpleFileObject( + fp: *mut FILE, + filename: *mut PyObject, + closeit: c_int, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_AnyFileExFlags( + fp: *mut FILE, + filename: *const c_char, + closeit: c_int, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn _PyRun_AnyFileObject( + fp: *mut FILE, + filename: *mut PyObject, + closeit: c_int, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_SimpleFileExFlags( + fp: *mut FILE, + filename: *const c_char, + closeit: c_int, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_InteractiveOneFlags( + fp: *mut FILE, + filename: *const c_char, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_InteractiveOneObject( + fp: *mut FILE, + filename: *mut PyObject, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_InteractiveLoopFlags( + fp: *mut FILE, + filename: *const c_char, + flags: *mut PyCompilerFlags, + ) -> c_int; + pub fn _PyRun_InteractiveLoopObject( + fp: *mut FILE, + filename: *mut PyObject, + flags: *mut PyCompilerFlags, + ) -> c_int; + + #[cfg(not(Py_3_10))] + pub fn PyParser_ASTFromString( + s: *const c_char, + filename: *const c_char, + start: c_int, + flags: *mut PyCompilerFlags, + arena: *mut PyArena, + ) -> *mut _mod; + #[cfg(not(Py_3_10))] + pub fn PyParser_ASTFromStringObject( + s: *const c_char, + filename: *mut PyObject, + start: c_int, + flags: *mut PyCompilerFlags, + arena: *mut PyArena, + ) -> *mut _mod; + #[cfg(not(Py_3_10))] + pub fn PyParser_ASTFromFile( + fp: *mut FILE, + filename: *const c_char, + enc: *const c_char, + start: c_int, + ps1: *const c_char, + ps2: *const c_char, + flags: *mut PyCompilerFlags, + errcode: *mut c_int, + arena: *mut PyArena, + ) -> *mut _mod; + #[cfg(not(Py_3_10))] + pub fn PyParser_ASTFromFileObject( + fp: *mut FILE, + filename: *mut PyObject, + enc: *const c_char, + start: c_int, + ps1: *const c_char, + ps2: *const c_char, + flags: *mut PyCompilerFlags, + errcode: *mut c_int, + arena: *mut PyArena, + ) -> *mut _mod; +} + +extern "C" { + #[cfg_attr(PyPy, link_name = "PyPyRun_StringFlags")] + pub fn PyRun_StringFlags( + arg1: *const c_char, + arg2: c_int, + arg3: *mut PyObject, + arg4: *mut PyObject, + arg5: *mut PyCompilerFlags, + ) -> *mut PyObject; + pub fn PyRun_FileExFlags( + fp: *mut FILE, + filename: *const c_char, + start: c_int, + globals: *mut PyObject, + locals: *mut PyObject, + closeit: c_int, + flags: *mut PyCompilerFlags, + ) -> *mut PyObject; + + #[cfg(not(PyPy))] + pub fn Py_CompileStringExFlags( + str: *const c_char, + filename: *const c_char, + start: c_int, + flags: *mut PyCompilerFlags, + optimize: c_int, + ) -> *mut PyObject; + #[cfg(not(Py_LIMITED_API))] + pub fn Py_CompileStringObject( + str: *const c_char, + filename: *mut PyObject, + start: c_int, + flags: *mut PyCompilerFlags, + optimize: c_int, + ) -> *mut PyObject; +} + +#[inline] +pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject { + #[cfg(not(PyPy))] + return Py_CompileStringExFlags(string, p, s, std::ptr::null_mut(), -1); + + #[cfg(PyPy)] + Py_CompileStringFlags(string, p, s, std::ptr::null_mut()) +} + +#[inline] +#[cfg(not(PyPy))] +pub unsafe fn Py_CompileStringFlags( + string: *const c_char, + p: *const c_char, + s: c_int, + f: *mut PyCompilerFlags, +) -> *mut PyObject { + Py_CompileStringExFlags(string, p, s, f, -1) +} + +// skipped _Py_SourceAsString + +extern "C" { + pub fn PyRun_String( + string: *const c_char, + s: c_int, + g: *mut PyObject, + l: *mut PyObject, + ) -> *mut PyObject; + pub fn PyRun_AnyFile(fp: *mut FILE, name: *const c_char) -> c_int; + pub fn PyRun_AnyFileEx(fp: *mut FILE, name: *const c_char, closeit: c_int) -> c_int; + pub fn PyRun_AnyFileFlags( + arg1: *mut FILE, + arg2: *const c_char, + arg3: *mut PyCompilerFlags, + ) -> c_int; + pub fn PyRun_SimpleString(s: *const c_char) -> c_int; + pub fn PyRun_SimpleFile(f: *mut FILE, p: *const c_char) -> c_int; + pub fn PyRun_SimpleFileEx(f: *mut FILE, p: *const c_char, c: c_int) -> c_int; + pub fn PyRun_InteractiveOne(f: *mut FILE, p: *const c_char) -> c_int; + pub fn PyRun_InteractiveLoop(f: *mut FILE, p: *const c_char) -> c_int; + pub fn PyRun_File( + fp: *mut FILE, + p: *const c_char, + s: c_int, + g: *mut PyObject, + l: *mut PyObject, + ) -> *mut PyObject; + pub fn PyRun_FileEx( + fp: *mut FILE, + p: *const c_char, + s: c_int, + g: *mut PyObject, + l: *mut PyObject, + c: c_int, + ) -> *mut PyObject; + pub fn PyRun_FileFlags( + fp: *mut FILE, + p: *const c_char, + s: c_int, + g: *mut PyObject, + l: *mut PyObject, + flags: *mut PyCompilerFlags, + ) -> *mut PyObject; +} + +// skipped macro PyRun_String +// skipped macro PyRun_AnyFile +// skipped macro PyRun_AnyFileEx +// skipped macro PyRun_AnyFileFlags + +extern "C" { + #[cfg(not(Py_3_10))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + pub fn PyParser_SimpleParseStringFlags( + arg1: *const c_char, + arg2: c_int, + arg3: c_int, + ) -> *mut _node; + #[cfg(not(Py_3_10))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + pub fn PyParser_SimpleParseStringFlagsFilename( + arg1: *const c_char, + arg2: *const c_char, + arg3: c_int, + arg4: c_int, + ) -> *mut _node; + #[cfg(not(Py_3_10))] + #[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] + pub fn PyParser_SimpleParseFileFlags( + arg1: *mut FILE, + arg2: *const c_char, + arg3: c_int, + arg4: c_int, + ) -> *mut _node; + + #[cfg(PyPy)] + #[cfg_attr(PyPy, link_name = "PyPy_CompileStringFlags")] + pub fn Py_CompileStringFlags( + string: *const c_char, + p: *const c_char, + s: c_int, + f: *mut PyCompilerFlags, + ) -> *mut PyObject; +} diff --git a/src/ffi/pythonrun.rs b/src/ffi/pythonrun.rs index a7eaf986..a0506c16 100644 --- a/src/ffi/pythonrun.rs +++ b/src/ffi/pythonrun.rs @@ -1,11 +1,28 @@ use crate::ffi::object::*; -#[cfg(not(Py_LIMITED_API))] -use crate::ffi::pyarena::PyArena; -#[cfg(not(Py_LIMITED_API))] +#[cfg(all(not(Py_LIMITED_API), not(Py_3_10)))] use libc::FILE; -use std::os::raw::{c_char, c_int}; +#[cfg(all(Py_LIMITED_API, not(Py_3_10)))] +use std::os::raw::c_char; +use std::os::raw::c_int; -// TODO: PyCF_MASK etc. constants +extern "C" { + #[cfg(Py_LIMITED_API)] + #[cfg(not(PyPy))] + pub fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject; + + #[cfg_attr(PyPy, link_name = "PyPyErr_Print")] + pub fn PyErr_Print(); + #[cfg_attr(PyPy, link_name = "PyPyErr_PrintEx")] + pub fn PyErr_PrintEx(arg1: c_int); + #[cfg_attr(PyPy, link_name = "PyPyErr_Display")] + pub fn PyErr_Display(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject); +} + +// skipped PyOS_InputHook + +pub const PYOS_STACK_MARGIN: c_int = 2048; + +// skipped PyOS_CheckStack under Microsoft C #[repr(C)] #[derive(Copy, Clone)] @@ -17,191 +34,41 @@ pub struct PyCompilerFlags { #[cfg(Py_LIMITED_API)] opaque_struct!(PyCompilerFlags); -#[cfg(not(Py_LIMITED_API))] +#[cfg(all(not(Py_LIMITED_API), not(Py_3_10)))] opaque_struct!(_mod); -#[cfg(not(Py_LIMITED_API))] -extern "C" { - pub fn PyRun_SimpleStringFlags(arg1: *const c_char, arg2: *mut PyCompilerFlags) -> c_int; - pub fn PyRun_AnyFileFlags( - arg1: *mut FILE, - arg2: *const c_char, - arg3: *mut PyCompilerFlags, - ) -> c_int; - pub fn PyRun_AnyFileExFlags( - fp: *mut FILE, - filename: *const c_char, - closeit: c_int, - flags: *mut PyCompilerFlags, - ) -> c_int; - pub fn PyRun_SimpleFileExFlags( - fp: *mut FILE, - filename: *const c_char, - closeit: c_int, - flags: *mut PyCompilerFlags, - ) -> c_int; - pub fn PyRun_InteractiveOneFlags( - fp: *mut FILE, - filename: *const c_char, - flags: *mut PyCompilerFlags, - ) -> c_int; - pub fn PyRun_InteractiveOneObject( - fp: *mut FILE, - filename: *mut PyObject, - flags: *mut PyCompilerFlags, - ) -> c_int; - pub fn PyRun_InteractiveLoopFlags( - fp: *mut FILE, - filename: *const c_char, - flags: *mut PyCompilerFlags, - ) -> c_int; - pub fn PyParser_ASTFromString( - s: *const c_char, - filename: *const c_char, - start: c_int, - flags: *mut PyCompilerFlags, - arena: *mut PyArena, - ) -> *mut _mod; - pub fn PyParser_ASTFromStringObject( - s: *const c_char, - filename: *mut PyObject, - start: c_int, - flags: *mut PyCompilerFlags, - arena: *mut PyArena, - ) -> *mut _mod; - pub fn PyParser_ASTFromFile( - fp: *mut FILE, - filename: *const c_char, - enc: *const c_char, - start: c_int, - ps1: *const c_char, - ps2: *const c_char, - flags: *mut PyCompilerFlags, - errcode: *mut c_int, - arena: *mut PyArena, - ) -> *mut _mod; - pub fn PyParser_ASTFromFileObject( - fp: *mut FILE, - filename: *mut PyObject, - enc: *const c_char, - start: c_int, - ps1: *const c_char, - ps2: *const c_char, - flags: *mut PyCompilerFlags, - errcode: *mut c_int, - arena: *mut PyArena, - ) -> *mut _mod; -} - +#[cfg(not(Py_3_10))] opaque_struct!(symtable); +#[cfg(not(Py_3_10))] opaque_struct!(_node); +#[cfg(all(not(Py_LIMITED_API), not(Py_3_10)))] +#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] #[inline] pub unsafe fn PyParser_SimpleParseString(s: *const c_char, b: c_int) -> *mut _node { - PyParser_SimpleParseStringFlags(s, b, 0) + #[allow(deprecated)] + crate::ffi::PyParser_SimpleParseStringFlags(s, b, 0) } -#[cfg(not(Py_LIMITED_API))] +#[cfg(all(not(Py_LIMITED_API), not(Py_3_10)))] +#[cfg_attr(Py_3_9, deprecated(note = "Python 3.9"))] #[inline] pub unsafe fn PyParser_SimpleParseFile(fp: *mut FILE, s: *const c_char, b: c_int) -> *mut _node { - PyParser_SimpleParseFileFlags(fp, s, b, 0) + #[allow(deprecated)] + crate::ffi::PyParser_SimpleParseFileFlags(fp, s, b, 0) } extern "C" { - pub fn PyParser_SimpleParseStringFlags( - arg1: *const c_char, - arg2: c_int, - arg3: c_int, - ) -> *mut _node; - pub fn PyParser_SimpleParseStringFlagsFilename( - arg1: *const c_char, - arg2: *const c_char, - arg3: c_int, - arg4: c_int, - ) -> *mut _node; - #[cfg(not(Py_LIMITED_API))] - pub fn PyParser_SimpleParseFileFlags( - arg1: *mut FILE, - arg2: *const c_char, - arg3: c_int, - arg4: c_int, - ) -> *mut _node; - #[cfg(not(Py_LIMITED_API))] - #[cfg_attr(PyPy, link_name = "PyPyRun_StringFlags")] - pub fn PyRun_StringFlags( - arg1: *const c_char, - arg2: c_int, - arg3: *mut PyObject, - arg4: *mut PyObject, - arg5: *mut PyCompilerFlags, - ) -> *mut PyObject; - #[cfg(not(Py_LIMITED_API))] - pub fn PyRun_FileExFlags( - fp: *mut FILE, - filename: *const c_char, - start: c_int, - globals: *mut PyObject, - locals: *mut PyObject, - closeit: c_int, - flags: *mut PyCompilerFlags, - ) -> *mut PyObject; - #[cfg(Py_LIMITED_API)] - #[cfg(not(PyPy))] - pub fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject; - #[cfg(any(PyPy, not(Py_LIMITED_API)))] - #[cfg_attr(PyPy, link_name = "PyPy_CompileStringFlags")] - pub fn Py_CompileStringFlags( - string: *const c_char, - p: *const c_char, - s: c_int, - f: *mut PyCompilerFlags, - ) -> *mut PyObject; -} - -#[inline] -#[cfg(any(not(Py_LIMITED_API), PyPy))] -pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject { - #[cfg(not(PyPy))] - return Py_CompileStringExFlags(string, p, s, std::ptr::null_mut(), -1); - - #[cfg(PyPy)] - Py_CompileStringFlags(string, p, s, std::ptr::null_mut()) -} - -extern "C" { - #[cfg(not(Py_LIMITED_API))] - #[cfg(not(PyPy))] - pub fn Py_CompileStringExFlags( - str: *const c_char, - filename: *const c_char, - start: c_int, - flags: *mut PyCompilerFlags, - optimize: c_int, - ) -> *mut PyObject; - #[cfg(not(Py_LIMITED_API))] - pub fn Py_CompileStringObject( - str: *const c_char, - filename: *mut PyObject, - start: c_int, - flags: *mut PyCompilerFlags, - optimize: c_int, - ) -> *mut PyObject; + #[cfg(not(Py_3_10))] pub fn Py_SymtableString( str: *const c_char, filename: *const c_char, start: c_int, ) -> *mut symtable; - #[cfg(not(Py_LIMITED_API))] + #[cfg(all(not(Py_LIMITED_API), not(Py_3_10)))] pub fn Py_SymtableStringObject( str: *const c_char, filename: *mut PyObject, start: c_int, ) -> *mut symtable; - - #[cfg_attr(PyPy, link_name = "PyPyErr_Print")] - pub fn PyErr_Print(); - #[cfg_attr(PyPy, link_name = "PyPyErr_PrintEx")] - pub fn PyErr_PrintEx(arg1: c_int); - #[cfg_attr(PyPy, link_name = "PyPyErr_Display")] - pub fn PyErr_Display(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject); }