Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Closed
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
9 changes: 0 additions & 9 deletions 9 Doc/c-api/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,6 @@ defined closer to where they are useful (e.g. :c:macro:`Py_RETURN_NONE`).
Others of a more general utility are defined here. This is not necessarily a
complete listing.

.. c:macro:: Py_UNREACHABLE()

Use this when you have a code path that you do not expect to be reached.
For example, in the ``default:`` clause in a ``switch`` statement for which
all possible values are covered in ``case`` statements. Use this in places
where you might be tempted to put an ``assert(0)`` or ``abort()`` call.

.. versionadded:: 3.7

.. c:macro:: Py_ABS(x)

Return the absolute value of ``x``.
Expand Down
14 changes: 14 additions & 0 deletions 14 Doc/c-api/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,17 @@ Process Control
function registered last is called first. Each cleanup function will be called
at most once. Since Python's internal finalization will have completed before
the cleanup function, no Python APIs should be called by *func*.

.. c:function:: void Py_UNREACHABLE(void)

Use this when you have a code path that you do not expect to be reached.
For example, in the ``default:`` clause in a ``switch`` statement for which
all possible values are covered in ``case`` statements. Use this in places
where you might be tempted to put an ``assert(0)`` or ``abort()`` call.

Call :c:func:`Py_FatalError` which dumps the Python traceback where the
bug occurs.

In Python 3.8 and older, ``Py_UNREACHABLE()`` was a macro.

.. versionadded:: 3.9
2 changes: 2 additions & 0 deletions 2 Include/pyerrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,8 @@ PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...)
PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
Py_GCC_ATTRIBUTE((format(printf, 3, 0)));

PyAPI_FUNC(void) _Py_NO_RETURN Py_UNREACHABLE(void);

#ifndef Py_LIMITED_API
# define Py_CPYTHON_ERRORS_H
# include "cpython/pyerrors.h"
Expand Down
28 changes: 0 additions & 28 deletions 28 Include/pymacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,32 +100,4 @@
# define Py_UNUSED(name) _unused_ ## name
#endif

#if defined(RANDALL_WAS_HERE)
#define Py_UNREACHABLE() do { \
fputs( \
"ERROR:\n\n" \
"If you're seeing this, the code is in what I thought was\n" \
"an unreachable state.\n\n" \
"I could give you advice for what to do, but honestly, why\n" \
"should you trust me? I clearly screwed this up. I'm writing\n" \
"a message that should never appear, yet I know it will\n" \
"probably appear someday.\n\n" \
"On a deep level, I know I'm not up to this task.\n" \
"I'm so sorry.\n\n" \
"https://xkcd.com/2200\n", stderr); \
abort(); \
} while(0)
#elif defined(Py_DEBUG)
#define Py_UNREACHABLE() do { \
fputs( \
"ERROR:\n\n" \
"We've reached an unreachable state. Anything is possible.\n" \
"The limits were in our heads all along. Follow your dreams.\n\n" \
"https://xkcd.com/2200\n", stderr); \
abort(); \
} while(0)
#else
#define Py_UNREACHABLE() abort()
#endif

#endif /* Py_PYMACRO_H */
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Convert :c:func:`Py_UNREACHABLE` macro to a function.
13 changes: 13 additions & 0 deletions 13 Python/errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,19 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno)
return err_programtext(tstate, fp, lineno);
}

void _Py_NO_RETURN
Py_UNREACHABLE(void)
{
#ifdef Py_DEBUG
Py_FatalError(
"We've reached an unreachable state. Anything is possible.\n"
"The limits were in our heads all along. Follow your dreams.\n"
"https://xkcd.com/2200");
#else
Py_FatalError("Unreachable C code path reached");
#endif
}
Comment thread
zware marked this conversation as resolved.

#ifdef __cplusplus
}
#endif
Morty Proxy This is a proxified and sanitized view of the page, visit original site.