Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions newsfragments/5989.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Add `PyNameErrorObject` and `PyAttributeErrorObject` structs, and the following API functions:

* pub fn PySignal_SetWakeupFd(fd: c_int) -> c_int
* pub fn PyErr_SyntaxLocationObject(filename: *mut PyObject, lineno: c_int, col_offset: c_int)
* pub fn PyErr_RangedSyntaxLocationObject
filename: *mut PyObject,
lineno: c_int,
col_offset: c_int,
end_lineno: c_int,
end_col_offset: c_int,
)
* pub fn PyErr_ProgramTextObject(filename: *mut PyObject, lineno: c_int) -> *mut PyObject
* pub static PyExc_PythonFinalizationError: *mut PyObject
85 changes: 59 additions & 26 deletions pyo3-ffi/src/cpython/pyerrors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::PyObject;
#[cfg(not(any(PyPy, GraalPy)))]
use crate::Py_ssize_t;
use std::ffi::c_int;

#[repr(C)]
#[derive(Debug)]
Expand Down Expand Up @@ -154,37 +155,69 @@ pub struct PyStopIterationObject {
pub value: *mut PyObject,
}

// skipped _PyErr_ChainExceptions
#[repr(C)]
#[derive(Debug)]
pub struct PyNameErrorObject {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two structs are not used by any public function. Is it useful to expose them? They are not documented on python.org

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two are exposed in public headers: https://github.com/python/cpython/blob/ad7d3616c6cc21c5ec032a726e4c5e819628aa6e/Include/cpython/pyerrors.h#L76-L85

Since they aren't prefixed with _, better to expose them

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it better to expose them? If there's not an actual use case, it's just extra code to maintain for no benefit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we'd exposed none of the other structs, I would support not adding. But I think now that the ship has sailed it somewhat doesn't hurt to add these for completeness; otherwise some user might eventually start doing something with the raw objects and run into a wall with these ones unexpectedly.

One alternative is to remove the others and support the structures for none of them, but probably too late for now. (Maybe CPython removes the structures in the future.)

pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub dict: *mut PyObject,
#[cfg(not(PyPy))]
pub args: *mut PyObject,
#[cfg(all(Py_3_11, not(PyPy)))]
pub notes: *mut PyObject,
#[cfg(not(PyPy))]
pub traceback: *mut PyObject,
#[cfg(not(PyPy))]
pub context: *mut PyObject,
#[cfg(not(PyPy))]
pub cause: *mut PyObject,
#[cfg(not(PyPy))]
pub suppress_context: char,
pub name: *mut PyObject,
}

// skipped PyNameErrorObject
// skipped PyAttributeErrorObject
#[repr(C)]
#[derive(Debug)]
pub struct PyAttributeErrorObject {
pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub dict: *mut PyObject,
#[cfg(not(PyPy))]
pub args: *mut PyObject,
#[cfg(all(Py_3_11, not(PyPy)))]
pub notes: *mut PyObject,
#[cfg(not(PyPy))]
pub traceback: *mut PyObject,
#[cfg(not(PyPy))]
pub context: *mut PyObject,
#[cfg(not(PyPy))]
pub cause: *mut PyObject,
#[cfg(not(PyPy))]
pub suppress_context: char,
pub obj: *mut PyObject,
pub name: *mut PyObject,
}

// skipped PyEnvironmentErrorObject
// skipped PyWindowsErrorObject

// skipped _PyErr_SetKeyError
// skipped _PyErr_GetTopmostException
// skipped _PyErr_GetExcInfo

// skipped PyErr_SetFromErrnoWithUnicodeFilename

// skipped _PyErr_FormatFromCause

// skipped PyErr_SetFromWindowsErrWithUnicodeFilename
// skipped PyErr_SetExcFromWindowsErrWithUnicodeFilename

// skipped _PyErr_TrySetFromCause

// skipped PySignal_SetWakeupFd
// skipped _PyErr_CheckSignals

// skipped PyErr_SyntaxLocationObject
// skipped PyErr_RangedSyntaxLocationObject
// skipped PyErr_ProgramTextObject
// skipped _PyErr_ChainExceptions
// skipped PyUnstable_Exc_PrepReraiseStar

// skipped _PyErr_ProgramDecodedTextObject
// skipped _PyUnicodeTranslateError_Create
// skipped _PyErr_WriteUnraisableMsg
// skipped _Py_FatalErrorFunc
// skipped _Py_FatalErrorFormat
// skipped Py_FatalError
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a ton of skipped comments above which are now either implemented or no longer in the cpython headers. Would be great to synchronize them.


extern_libpython! {
pub fn PySignal_SetWakeupFd(fd: c_int) -> c_int;
pub fn PyErr_SyntaxLocationObject(filename: *mut PyObject, lineno: c_int, col_offset: c_int);
#[cfg(Py_3_10)]
pub fn PyErr_RangedSyntaxLocationObject(
Comment thread
clin1234 marked this conversation as resolved.
filename: *mut PyObject,
lineno: c_int,
col_offset: c_int,
end_lineno: c_int,
end_col_offset: c_int,
);
pub fn PyErr_ProgramTextObject(filename: *mut PyObject, lineno: c_int) -> *mut PyObject;
pub static PyExc_PythonFinalizationError: *mut PyObject;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could implement Py_FatalError as an inline function calling _Py_FatalErrorFunc privately.

}
Loading