Skip to content

Commit b2e5794

Browse files
authored
* Add Py_UNREACHABLE() as an alias to abort(). * Use Py_UNREACHABLE() instead of assert(0) * Convert more unreachable code to use Py_UNREACHABLE() * Document Py_UNREACHABLE() and a few other macros.
1 parent d384a81 commit b2e5794

22 files changed

+128
-111
lines changed

Doc/c-api/intro.rst

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ common use. The second reason is to use Python as a component in a larger
1717
application; this technique is generally referred to as :dfn:`embedding` Python
1818
in an application.
1919

20-
Writing an extension module is a relatively well-understood process, where a
21-
"cookbook" approach works well. There are several tools that automate the
22-
process to some extent. While people have embedded Python in other
23-
applications since its early existence, the process of embedding Python is less
24-
straightforward than writing an extension.
20+
Writing an extension module is a relatively well-understood process, where a
21+
"cookbook" approach works well. There are several tools that automate the
22+
process to some extent. While people have embedded Python in other
23+
applications since its early existence, the process of embedding Python is
24+
less straightforward than writing an extension.
2525

2626
Many API functions are useful independent of whether you're embedding or
2727
extending Python; moreover, most applications that embed Python will need to
@@ -30,6 +30,16 @@ familiar with writing an extension before attempting to embed Python in a real
3030
application.
3131

3232

33+
Coding standards
34+
================
35+
36+
If you're writing C code for inclusion in CPython, you **must** follow the
37+
guidelines and standards defined in :PEP:`7`. These guidelines apply
38+
regardless of the version of Python you are contributing to. Following these
39+
conventions is not necessary for your own third party extension modules,
40+
unless you eventually expect to contribute them to Python.
41+
42+
3343
.. _api-includes:
3444

3545
Include Files
@@ -81,6 +91,48 @@ header files do properly declare the entry points to be ``extern "C"``, so there
8191
is no need to do anything special to use the API from C++.
8292

8393

94+
Useful macros
95+
=============
96+
97+
Several useful macros are defined in the Python header files. Many are
98+
defined closer to where they are useful (e.g. :c:macro:`Py_RETURN_NONE`).
99+
Others of a more general utility are defined here. This is not necessarily a
100+
complete listing.
101+
102+
.. c:macro:: Py_UNREACHABLE()
103+
104+
Use this when you have a code path that you do not expect to be reached.
105+
For example, in the ``default:`` clause in a ``switch`` statement for which
106+
all possible values are covered in ``case`` statements. Use this in places
107+
where you might be tempted to put an ``assert(0)`` or ``abort()`` call.
108+
109+
.. c:macro:: Py_ABS(x)
110+
111+
Return the absolute value of ``x``.
112+
113+
.. c:macro:: Py_MIN(x, y)
114+
115+
Return the minimum value between ``x`` and ``y``.
116+
117+
.. c:macro:: Py_MAX(x, y)
118+
119+
Return the maximum value between ``x`` and ``y``.
120+
121+
.. c:macro:: Py_STRINGIFY(x)
122+
123+
Convert ``x`` to a C string. E.g. ``Py_STRINGIFY(123)`` returns
124+
``"123"``.
125+
126+
.. c:macro:: Py_MEMBER_SIZE(type, member)
127+
128+
Return the size of a structure (``type``) ``member`` in bytes.
129+
130+
.. c:macro:: Py_CHARMASK(c)
131+
132+
Argument must be a character or an integer in the range [-128, 127] or [0,
133+
255]. This macro returns ``c`` cast to an ``unsigned char``.
134+
135+
84136
.. _api-objects:
85137

86138
Objects, Types and Reference Counts

Include/pymacro.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,6 @@
9595
#define Py_UNUSED(name) _unused_ ## name
9696
#endif
9797

98+
#define Py_UNREACHABLE() abort()
99+
98100
#endif /* Py_PYMACRO_H */
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Added the ``Py_UNREACHABLE()`` macro for code paths which are never expected
2+
to be reached. This and a few other useful macros are now documented in the
3+
C API manual.

Modules/_datetimemodule.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,8 +1453,7 @@ diff_to_bool(int diff, int op)
14531453
case Py_LT: istrue = diff < 0; break;
14541454
case Py_GT: istrue = diff > 0; break;
14551455
default:
1456-
assert(! "op unknown");
1457-
istrue = 0; /* To shut up compiler */
1456+
Py_UNREACHABLE();
14581457
}
14591458
result = istrue ? Py_True : Py_False;
14601459
Py_INCREF(result);

Modules/_pickle.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,7 @@ _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
750750
if (entry->me_key == NULL || entry->me_key == key)
751751
return entry;
752752
}
753-
assert(0); /* Never reached */
754-
return NULL;
753+
Py_UNREACHABLE();
755754
}
756755

757756
/* Returns -1 on failure, 0 on success. */

Modules/_tracemalloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size)
726726
727727
The GIL and the table lock ensures that only one thread is
728728
allocating memory. */
729-
assert(0 && "should never happen");
729+
Py_UNREACHABLE();
730730
}
731731
TABLES_UNLOCK();
732732
}

Modules/mathmodule.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ sinpi(double x)
105105
r = sin(pi*(y-2.0));
106106
break;
107107
default:
108-
assert(0); /* should never get here */
109-
r = -1.23e200; /* silence gcc warning */
108+
Py_UNREACHABLE();
110109
}
111110
return copysign(1.0, x)*r;
112111
}

Objects/abstract.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1984,7 +1984,7 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
19841984
goto Done;
19851985

19861986
default:
1987-
assert(!"unknown operation");
1987+
Py_UNREACHABLE();
19881988
}
19891989
}
19901990

Objects/bytesobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
868868
switch(c)
869869
{
870870
default:
871-
assert(0 && "'type' not in [diuoxX]");
871+
Py_UNREACHABLE();
872872
case 'd':
873873
case 'i':
874874
case 'u':

Objects/dictobject.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,7 @@ lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index)
643643
perturb >>= PERTURB_SHIFT;
644644
i = mask & (i*5 + perturb + 1);
645645
}
646-
assert(0); /* NOT REACHED */
647-
return DKIX_ERROR;
646+
Py_UNREACHABLE();
648647
}
649648

650649
/*
@@ -723,8 +722,7 @@ lookdict(PyDictObject *mp, PyObject *key,
723722
perturb >>= PERTURB_SHIFT;
724723
i = (i*5 + perturb + 1) & mask;
725724
}
726-
assert(0); /* NOT REACHED */
727-
return 0;
725+
Py_UNREACHABLE();
728726
}
729727

730728
/* Specialized version for string-only keys */
@@ -766,9 +764,7 @@ lookdict_unicode(PyDictObject *mp, PyObject *key,
766764
perturb >>= PERTURB_SHIFT;
767765
i = mask & (i*5 + perturb + 1);
768766
}
769-
770-
assert(0); /* NOT REACHED */
771-
return 0;
767+
Py_UNREACHABLE();
772768
}
773769

774770
/* Faster version of lookdict_unicode when it is known that no <dummy> keys
@@ -810,8 +806,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
810806
perturb >>= PERTURB_SHIFT;
811807
i = mask & (i*5 + perturb + 1);
812808
}
813-
assert(0); /* NOT REACHED */
814-
return 0;
809+
Py_UNREACHABLE();
815810
}
816811

817812
/* Version of lookdict for split tables.
@@ -856,8 +851,7 @@ lookdict_split(PyDictObject *mp, PyObject *key,
856851
perturb >>= PERTURB_SHIFT;
857852
i = mask & (i*5 + perturb + 1);
858853
}
859-
assert(0); /* NOT REACHED */
860-
return 0;
854+
Py_UNREACHABLE();
861855
}
862856

863857
int
@@ -3603,7 +3597,7 @@ dictiter_reduce(dictiterobject *di)
36033597
else if (Py_TYPE(di) == &PyDictIterValue_Type)
36043598
element = dictiter_iternextvalue(&tmp);
36053599
else
3606-
assert(0);
3600+
Py_UNREACHABLE();
36073601
if (element) {
36083602
if (PyList_Append(list, element)) {
36093603
Py_DECREF(element);

Objects/longobject.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,8 +1806,7 @@ long_format_binary(PyObject *aa, int base, int alternate,
18061806
bits = 1;
18071807
break;
18081808
default:
1809-
assert(0); /* shouldn't ever get here */
1810-
bits = 0; /* to silence gcc warning */
1809+
Py_UNREACHABLE();
18111810
}
18121811

18131812
/* Compute exact length 'sz' of output string. */
@@ -2169,8 +2168,8 @@ PyLong_FromString(const char *str, char **pend, int base)
21692168
}
21702169
}
21712170
if (str[0] == '_') {
2172-
/* May not start with underscores. */
2173-
goto onError;
2171+
/* May not start with underscores. */
2172+
goto onError;
21742173
}
21752174

21762175
start = str;

Objects/stringlib/eq.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ unicode_eq(PyObject *aa, PyObject *bb)
1010
PyUnicodeObject *b = (PyUnicodeObject *)bb;
1111

1212
if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
13-
assert(0 && "unicode_eq ready fail");
14-
return 0;
13+
Py_UNREACHABLE();
1514
}
1615

1716
if (PyUnicode_GET_LENGTH(a) != PyUnicode_GET_LENGTH(b))

0 commit comments

Comments
 (0)