Skip to content

internal: introduce ErrorAlreadySet marker when FFI calls return an exception#6069

Open
davidhewitt wants to merge 2 commits into
PyO3:mainfrom
davidhewitt:err-already-set
Open

internal: introduce ErrorAlreadySet marker when FFI calls return an exception#6069
davidhewitt wants to merge 2 commits into
PyO3:mainfrom
davidhewitt:err-already-set

Conversation

@davidhewitt
Copy link
Copy Markdown
Member

@davidhewitt davidhewitt commented May 24, 2026

This is a bit of an experiment to add an ErrorAlreadySet<'py> zero-sized type to denote that a Python exception has been raised in the interpreter. This avoids all the overhead of PyErr::fetch, especially on paths where we immediately clear the error.

Because many C API calls may not legally be called when there is an exception raised in the interpreter, I denote it unsafe to create and probably all functions which may return a Result<_, ErrorAlreadySet<'_>> should be unsafe too.

I see two key advantages of this type:

  • When we know we're about to exit a #[pyfunction] into the Python interpreter, we could potentially avoid fetching a PyErr.
  • Internal PyO3 code which makes a lot of FFI calls might prefer to use this type and only yield to user code at the end.

In this PR I:

  1. Introduce the type, and add plumbing for it to FfiPtrExt and PyResultExt internal traits
  2. Use it in PySetMethods::pop, where it eagerly discards the error instead of fetching it and then dropping it.
  3. Use it in tuple construction; I did some refactoring with the goal of reducing possible error handling cost. In the end I don't think it was that helpful here (yet - needs IntoPyObject support perhaps, see below).

If the type seems promising, I'd like to experiment with using it for the #[pyfunction] boundary. The hardest part is that IntoPyObject implementations don't currently use this error type.

I can either do further experimentation in this PR, or as a follow up, depending on what folks think about the potential of this type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant