This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Expose _PyErr_GetTopmostException
Type: enhancement Stage: resolved
Components: C API Versions: Python 3.9
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Mark.Shannon, jd, scoder, vstinner
Priority: normal Keywords: patch

Created on 2020-05-07 09:29 by jd, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 19977 closed jd, 2020-05-07 09:32
PR 19978 merged vstinner, 2020-05-07 09:42
Messages (10)
msg368327 - (view) Author: Julien Danjou (jd) * Date: 2020-05-07 09:29
The function _PyErr_GetTopmostException() is not exported and is useful to get access to exceptions info from a PyThreadState.
msg368328 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-05-07 09:43
The function was added by:

commit ae3087c6382011c47db82fea4d05f8bbf514265d
Author: Mark Shannon <>
Date:   Sun Oct 22 22:41:51 2017 +0100

    Move exc state to generator. Fixes bpo-25612 (#1773)
    Move exception state information from frame objects to coroutine (generator/thread) object where it belongs.

Python 3.9 is now built with -fvisibility=hidden, bpo-11410:

commit 0b60f64e4343913b4931dc27379d9808e5b78fe1
Author: Vinay Sajip <>
Date:   Tue Oct 15 08:26:12 2019 +0100

    bpo-11410: Standardize and use symbol visibility attributes across POSIX and Windows. (GH-16347)

It means that functions which are not explicitly exported are no longer exported.

So yeah, _PyErr_GetTopmostException() symbol is not properly exported.

But the function remains private. IMHO if someone wants to add a *public* function, it should return a *strong* reference to the 3 variables (exc type, exc value, exc tb).

See also bpo-39947: "[C API] Make the PyThreadState structure opaque (move it to the internal C API)". I added multiple public getters for PyThreadState structure in Python 3.9.
msg368332 - (view) Author: Julien Danjou (jd) * Date: 2020-05-07 10:45
I would definitely love to have a public API for this.

Would `PyErr_GetTopmostException` be a good candidate for this?

(I can open a different bug report if needed)
msg368338 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-05-07 13:42
New changeset 8963a7f1f84a05412178b56629508b660d38861b by Victor Stinner in branch 'master':
bpo-40545: Export _PyErr_GetTopmostException() function (GH-19978)
msg368339 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-05-07 13:50
> I would definitely love to have a public API for this.

I'm not sure if it's a good idea. It's kind of semi-internal.

Stephan Behnel and Mark Shannon: What do you think of exposing PyThreadState exception stack (exc_state)? Especially the "top" exception. If I recall correctly, Mark designed it and Stephan "reimplemented" it in Cython.

I also recall a minor issue in greenlet:
msg368340 - (view) Author: Mark Shannon (Mark.Shannon) * (Python committer) Date: 2020-05-07 14:02
What's wrong with `PyErr_GetExcInfo()` for accessing the current exception?

Victor, would you revert until we decide what to do. Thanks.
msg368341 - (view) Author: Julien Danjou (jd) * Date: 2020-05-07 14:10
PyErr_GetExcInfo() does not allow to specify a PyThreadState as argument.
msg368343 - (view) Author: Mark Shannon (Mark.Shannon) * (Python committer) Date: 2020-05-07 14:15
Why do you need to specify a `PyThreadState`?
msg368345 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-05-07 14:39
> Why do you need to specify a `PyThreadState`?

From past issues, I understood that Julien's use case is a profiler which inspects memory without calling functions nor switching to other threads. It's like "dump the state of all Python threads".

I'm fine with exposing _PyErr_GetTopmostException() as a *private* function.  Moreover, the function was already exposed in 3.8. It was not exposed because of the visibility change which was made in 3.9.
msg368348 - (view) Author: Julien Danjou (jd) * Date: 2020-05-07 14:53
I confirm what Victor wrote. :)
Date User Action Args
2022-04-11 14:59:30adminsetgithub: 84725
2022-01-06 16:49:34iritkatrielsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2020-05-07 14:53:22jdsetmessages: + msg368348
2020-05-07 14:39:04vstinnersetmessages: + msg368345
2020-05-07 14:15:27Mark.Shannonsetmessages: + msg368343
2020-05-07 14:10:08jdsetmessages: + msg368341
2020-05-07 14:02:26Mark.Shannonsetmessages: + msg368340
2020-05-07 13:50:54vstinnersetnosy: + scoder, Mark.Shannon
messages: + msg368339
2020-05-07 13:42:40vstinnersetmessages: + msg368338
2020-05-07 10:45:43jdsetmessages: + msg368332
2020-05-07 09:43:44vstinnersetmessages: + msg368328
2020-05-07 09:42:09vstinnersetnosy: + vstinner
pull_requests: + pull_request19293
2020-05-07 09:32:14jdsetkeywords: + patch
stage: patch review
pull_requests: + pull_request19292
2020-05-07 09:29:58jdcreate