diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 74681d2c851..4942b1a4698 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -17,11 +17,11 @@ common use. The second reason is to use Python as a component in a larger application; this technique is generally referred to as :dfn:`embedding` Python in an application. -Writing an extension module is a relatively well-understood process, where a -"cookbook" approach works well. There are several tools that automate the -process to some extent. While people have embedded Python in other -applications since its early existence, the process of embedding Python is less -straightforward than writing an extension. +Writing an extension module is a relatively well-understood process, where a +"cookbook" approach works well. There are several tools that automate the +process to some extent. While people have embedded Python in other +applications since its early existence, the process of embedding Python is +less straightforward than writing an extension. Many API functions are useful independent of whether you're embedding or 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 application. +Coding standards +================ + +If you're writing C code for inclusion in CPython, you **must** follow the +guidelines and standards defined in :PEP:`7`. These guidelines apply +regardless of the version of Python you are contributing to. Following these +conventions is not necessary for your own third party extension modules, +unless you eventually expect to contribute them to Python. + + .. _api-includes: Include Files @@ -81,6 +91,48 @@ header files do properly declare the entry points to be ``extern "C"``, so there is no need to do anything special to use the API from C++. +Useful macros +============= + +Several useful macros are defined in the Python header files. Many are +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. + +.. c:macro:: Py_ABS(x) + + Return the absolute value of ``x``. + +.. c:macro:: Py_MIN(x, y) + + Return the minimum value between ``x`` and ``y``. + +.. c:macro:: Py_MAX(x, y) + + Return the maximum value between ``x`` and ``y``. + +.. c:macro:: Py_STRINGIFY(x) + + Convert ``x`` to a C string. E.g. ``Py_STRINGIFY(123)`` returns + ``"123"``. + +.. c:macro:: Py_MEMBER_SIZE(type, member) + + Return the size of a structure (``type``) ``member`` in bytes. + +.. c:macro:: Py_CHARMASK(c) + + Argument must be a character or an integer in the range [-128, 127] or [0, + 255]. This macro returns ``c`` cast to an ``unsigned char``. + + .. _api-objects: Objects, Types and Reference Counts diff --git a/Include/pymacro.h b/Include/pymacro.h index 69577b73651..3f6ddbe9977 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -95,4 +95,6 @@ #define Py_UNUSED(name) _unused_ ## name #endif +#define Py_UNREACHABLE() abort() + #endif /* Py_PYMACRO_H */ diff --git a/Misc/NEWS.d/next/C API/2017-09-05-17-51-12.bpo-31338.LjA43Y.rst b/Misc/NEWS.d/next/C API/2017-09-05-17-51-12.bpo-31338.LjA43Y.rst new file mode 100644 index 00000000000..01878e5d43f --- /dev/null +++ b/Misc/NEWS.d/next/C API/2017-09-05-17-51-12.bpo-31338.LjA43Y.rst @@ -0,0 +1,3 @@ +Added the ``Py_UNREACHABLE()`` macro for code paths which are never expected +to be reached. This and a few other useful macros are now documented in the +C API manual. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 1b68ff3b372..619ac84bf74 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1453,8 +1453,7 @@ diff_to_bool(int diff, int op) case Py_LT: istrue = diff < 0; break; case Py_GT: istrue = diff > 0; break; default: - assert(! "op unknown"); - istrue = 0; /* To shut up compiler */ + Py_UNREACHABLE(); } result = istrue ? Py_True : Py_False; Py_INCREF(result); diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 3165b4e6d68..fb69f14b53d 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -750,8 +750,7 @@ _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key) if (entry->me_key == NULL || entry->me_key == key) return entry; } - assert(0); /* Never reached */ - return NULL; + Py_UNREACHABLE(); } /* Returns -1 on failure, 0 on success. */ diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index feb32a09078..386f2f11ba7 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -726,7 +726,7 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) The GIL and the table lock ensures that only one thread is allocating memory. */ - assert(0 && "should never happen"); + Py_UNREACHABLE(); } TABLES_UNLOCK(); } diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index c19620d6bdc..5d9fe5aa71a 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -105,8 +105,7 @@ sinpi(double x) r = sin(pi*(y-2.0)); break; default: - assert(0); /* should never get here */ - r = -1.23e200; /* silence gcc warning */ + Py_UNREACHABLE(); } return copysign(1.0, x)*r; } diff --git a/Objects/abstract.c b/Objects/abstract.c index 998bcb12b80..38484b79a1b 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1984,7 +1984,7 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation) goto Done; default: - assert(!"unknown operation"); + Py_UNREACHABLE(); } } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index d91cb7d8724..6a4eb67808a 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -868,7 +868,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, switch(c) { default: - assert(0 && "'type' not in [diuoxX]"); + Py_UNREACHABLE(); case 'd': case 'i': case 'u': diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 81c7f7f2436..6ba2cc975fc 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -643,8 +643,7 @@ lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index) perturb >>= PERTURB_SHIFT; i = mask & (i*5 + perturb + 1); } - assert(0); /* NOT REACHED */ - return DKIX_ERROR; + Py_UNREACHABLE(); } /* @@ -723,8 +722,7 @@ top: perturb >>= PERTURB_SHIFT; i = (i*5 + perturb + 1) & mask; } - assert(0); /* NOT REACHED */ - return 0; + Py_UNREACHABLE(); } /* Specialized version for string-only keys */ @@ -766,9 +764,7 @@ lookdict_unicode(PyDictObject *mp, PyObject *key, perturb >>= PERTURB_SHIFT; i = mask & (i*5 + perturb + 1); } - - assert(0); /* NOT REACHED */ - return 0; + Py_UNREACHABLE(); } /* Faster version of lookdict_unicode when it is known that no keys @@ -810,8 +806,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, perturb >>= PERTURB_SHIFT; i = mask & (i*5 + perturb + 1); } - assert(0); /* NOT REACHED */ - return 0; + Py_UNREACHABLE(); } /* Version of lookdict for split tables. @@ -856,8 +851,7 @@ lookdict_split(PyDictObject *mp, PyObject *key, perturb >>= PERTURB_SHIFT; i = mask & (i*5 + perturb + 1); } - assert(0); /* NOT REACHED */ - return 0; + Py_UNREACHABLE(); } int @@ -3603,7 +3597,7 @@ dictiter_reduce(dictiterobject *di) else if (Py_TYPE(di) == &PyDictIterValue_Type) element = dictiter_iternextvalue(&tmp); else - assert(0); + Py_UNREACHABLE(); if (element) { if (PyList_Append(list, element)) { Py_DECREF(element); diff --git a/Objects/longobject.c b/Objects/longobject.c index 4862b76da6b..3b07585669e 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1806,8 +1806,7 @@ long_format_binary(PyObject *aa, int base, int alternate, bits = 1; break; default: - assert(0); /* shouldn't ever get here */ - bits = 0; /* to silence gcc warning */ + Py_UNREACHABLE(); } /* Compute exact length 'sz' of output string. */ @@ -2169,8 +2168,8 @@ PyLong_FromString(const char *str, char **pend, int base) } } if (str[0] == '_') { - /* May not start with underscores. */ - goto onError; + /* May not start with underscores. */ + goto onError; } start = str; diff --git a/Objects/stringlib/eq.h b/Objects/stringlib/eq.h index f8fd384a372..ff22f913712 100644 --- a/Objects/stringlib/eq.h +++ b/Objects/stringlib/eq.h @@ -10,8 +10,7 @@ unicode_eq(PyObject *aa, PyObject *bb) PyUnicodeObject *b = (PyUnicodeObject *)bb; if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) { - assert(0 && "unicode_eq ready fail"); - return 0; + Py_UNREACHABLE(); } if (PyUnicode_GET_LENGTH(a) != PyUnicode_GET_LENGTH(b)) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c4d93fca045..bb1c0830fc5 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -768,7 +768,7 @@ make_bloom_mask(int kind, void* ptr, Py_ssize_t len) BLOOM_UPDATE(Py_UCS4, mask, ptr, len); break; default: - assert(0); + Py_UNREACHABLE(); } return mask; @@ -869,8 +869,7 @@ findchar(const void *s, int kind, else return ucs4lib_rfind_char((Py_UCS4 *) s, size, ch); default: - assert(0); - return -1; + Py_UNREACHABLE(); } } @@ -1520,8 +1519,7 @@ _copy_characters(PyObject *to, Py_ssize_t to_start, ); } else { - assert(0); - return -1; + Py_UNREACHABLE(); } } else { @@ -2079,7 +2077,7 @@ PyUnicode_FromWideChar(const wchar_t *u, Py_ssize_t size) #endif break; default: - assert(0 && "Impossible state"); + Py_UNREACHABLE(); } return unicode_result(unicode); @@ -2172,8 +2170,7 @@ kind_maxchar_limit(unsigned int kind) case PyUnicode_4BYTE_KIND: return 0x10000; default: - assert(0 && "invalid kind"); - return MAX_UNICODE; + Py_UNREACHABLE(); } } @@ -2317,8 +2314,7 @@ _PyUnicode_FindMaxChar(PyObject *unicode, Py_ssize_t start, Py_ssize_t end) case PyUnicode_4BYTE_KIND: return ucs4lib_find_max_char(startptr, endptr); default: - assert(0); - return 0; + Py_UNREACHABLE(); } } @@ -4068,7 +4064,7 @@ PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) *w = *four_bytes; if (w > wchar_end) { - assert(0 && "Miscalculated string end"); + Py_UNREACHABLE(); } } *w = 0; @@ -4120,7 +4116,7 @@ PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) #endif } else { - assert(0 && "This should never happen."); + Py_UNREACHABLE(); } } } @@ -5134,7 +5130,7 @@ _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size) #endif if (ch > 0xFF) { #if SIZEOF_WCHAR_T == 4 - assert(0); + Py_UNREACHABLE(); #else assert(ch > 0xFFFF && ch <= MAX_UNICODE); /* compute and append the two surrogates: */ @@ -5187,7 +5183,7 @@ _PyUnicode_AsUTF8String(PyObject *unicode, const char *errors) switch (kind) { default: - assert(0); + Py_UNREACHABLE(); case PyUnicode_1BYTE_KIND: /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */ assert(!PyUnicode_IS_ASCII(unicode)); @@ -9294,7 +9290,7 @@ any_find_slice(PyObject* s1, PyObject* s2, result = ucs4lib_find_slice(buf1, len1, buf2, len2, start, end); break; default: - assert(0); result = -2; + Py_UNREACHABLE(); } } else { @@ -9312,7 +9308,7 @@ any_find_slice(PyObject* s1, PyObject* s2, result = ucs4lib_rfind_slice(buf1, len1, buf2, len2, start, end); break; default: - assert(0); result = -2; + Py_UNREACHABLE(); } } @@ -9386,8 +9382,7 @@ _PyUnicode_InsertThousandsGrouping( (Py_UCS4 *) thousands_sep_data, thousands_sep_len); break; default: - assert(0); - return -1; + Py_UNREACHABLE(); } if (unicode != NULL && thousands_sep_kind != kind) { if (thousands_sep_kind < kind) @@ -9465,7 +9460,7 @@ PyUnicode_Count(PyObject *str, ); break; default: - assert(0); result = 0; + Py_UNREACHABLE(); } if (kind2 != kind1) @@ -9881,8 +9876,7 @@ case_operation(PyObject *self, memcpy(outdata, tmp, sizeof(Py_UCS4) * newlength); break; default: - assert(0); - break; + Py_UNREACHABLE(); } leave: PyMem_FREE(tmp); @@ -10105,7 +10099,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject **items, Py_ssize_t seqlen) for (; i_ < (length); ++i_, ++to_) *to_ = (value); \ break; \ } \ - default: assert(0); \ + default: Py_UNREACHABLE(); \ } \ } while (0) @@ -10229,8 +10223,7 @@ PyUnicode_Splitlines(PyObject *string, int keepends) PyUnicode_GET_LENGTH(string), keepends); break; default: - assert(0); - list = 0; + Py_UNREACHABLE(); } return list; } @@ -10275,8 +10268,7 @@ split(PyObject *self, PyUnicode_GET_LENGTH(self), maxcount ); default: - assert(0); - return NULL; + Py_UNREACHABLE(); } if (PyUnicode_READY(substring) == -1) @@ -10367,8 +10359,7 @@ rsplit(PyObject *self, PyUnicode_GET_LENGTH(self), maxcount ); default: - assert(0); - return NULL; + Py_UNREACHABLE(); } if (PyUnicode_READY(substring) == -1) @@ -10434,8 +10425,7 @@ anylib_find(int kind, PyObject *str1, void *buf1, Py_ssize_t len1, case PyUnicode_4BYTE_KIND: return ucs4lib_find(buf1, len1, buf2, len2, offset); } - assert(0); - return -1; + Py_UNREACHABLE(); } static Py_ssize_t @@ -10453,8 +10443,7 @@ anylib_count(int kind, PyObject *sstr, void* sbuf, Py_ssize_t slen, case PyUnicode_4BYTE_KIND: return ucs4lib_count(sbuf, slen, buf1, len1, maxcount); } - assert(0); - return 0; + Py_UNREACHABLE(); } static void @@ -10909,7 +10898,7 @@ unicode_compare(PyObject *str1, PyObject *str2) COMPARE(Py_UCS1, Py_UCS4); break; default: - assert(0); + Py_UNREACHABLE(); } break; } @@ -10928,7 +10917,7 @@ unicode_compare(PyObject *str1, PyObject *str2) COMPARE(Py_UCS2, Py_UCS4); break; default: - assert(0); + Py_UNREACHABLE(); } break; } @@ -10956,12 +10945,12 @@ unicode_compare(PyObject *str1, PyObject *str2) break; } default: - assert(0); + Py_UNREACHABLE(); } break; } default: - assert(0); + Py_UNREACHABLE(); } if (len1 == len2) @@ -11285,8 +11274,7 @@ PyUnicode_Contains(PyObject *str, PyObject *substr) result = ucs4lib_find(buf1, len1, buf2, len2, 0) != -1; break; default: - result = -1; - assert(0); + Py_UNREACHABLE(); } if (kind2 != kind1) @@ -11511,7 +11499,7 @@ unicode_count(PyObject *self, PyObject *args) ); break; default: - assert(0); iresult = 0; + Py_UNREACHABLE(); } result = PyLong_FromSsize_t(iresult); @@ -12985,8 +12973,7 @@ PyUnicode_Partition(PyObject *str_obj, PyObject *sep_obj) out = ucs4lib_partition(str_obj, buf1, len1, sep_obj, buf2, len2); break; default: - assert(0); - out = 0; + Py_UNREACHABLE(); } if (kind2 != kind1) @@ -13043,8 +13030,7 @@ PyUnicode_RPartition(PyObject *str_obj, PyObject *sep_obj) out = ucs4lib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2); break; default: - assert(0); - out = 0; + Py_UNREACHABLE(); } if (kind2 != kind1) @@ -13627,8 +13613,7 @@ _PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, case PyUnicode_2BYTE_KIND: maxchar = 0xffff; break; case PyUnicode_4BYTE_KIND: maxchar = 0x10ffff; break; default: - assert(0 && "invalid kind"); - return -1; + Py_UNREACHABLE(); } return _PyUnicodeWriter_PrepareInternal(writer, 0, maxchar); @@ -13770,7 +13755,7 @@ _PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, break; } default: - assert(0); + Py_UNREACHABLE(); } writer->pos += len; @@ -14204,7 +14189,7 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) switch (type) { default: - assert(!"'type' not in [diuoxX]"); + Py_UNREACHABLE(); case 'd': case 'i': case 'u': @@ -14362,7 +14347,7 @@ mainformatlong(PyObject *v, switch(type) { default: - assert(0 && "'type' not in [diuoxX]"); + Py_UNREACHABLE(); case 'd': case 'i': case 'u': @@ -15373,8 +15358,7 @@ _Py_ReleaseInternedUnicodeStrings(void) for (i = 0; i < n; i++) { s = PyList_GET_ITEM(keys, i); if (PyUnicode_READY(s) == -1) { - assert(0 && "could not ready string"); - fprintf(stderr, "could not ready string\n"); + Py_UNREACHABLE(); } switch (PyUnicode_CHECK_INTERNED(s)) { case SSTATE_NOT_INTERNED: diff --git a/Parser/grammar1.c b/Parser/grammar1.c index 30a6f07cad9..9e9904158da 100644 --- a/Parser/grammar1.c +++ b/Parser/grammar1.c @@ -25,8 +25,7 @@ PyGrammar_FindDFA(grammar *g, int type) if (d->d_type == type) return d; } - assert(0); - /* NOTREACHED */ + Py_UNREACHABLE(); #endif } diff --git a/Python/ast.c b/Python/ast.c index 7d30e5f864f..fd42c0073de 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -100,8 +100,7 @@ expr_context_name(expr_context_ty ctx) case Param: return "Param"; default: - assert(0); - return "(unknown)"; + Py_UNREACHABLE(); } } @@ -759,8 +758,7 @@ num_stmts(const node *n) Py_FatalError(buf); } } - assert(0); - return 0; + Py_UNREACHABLE(); } /* Transform the CST rooted at node * to the appropriate AST diff --git a/Python/ceval.c b/Python/ceval.c index 08533a42bf2..5b810f29d12 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -274,7 +274,7 @@ PyEval_RestoreThread(PyThreadState *tstate) if (_Py_IsFinalizing() && !_Py_CURRENTLY_FINALIZING(tstate)) { drop_gil(tstate); PyThread_exit_thread(); - assert(0); /* unreachable */ + Py_UNREACHABLE(); } errno = err; } @@ -3430,7 +3430,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* This should never be reached. Every opcode should end with DISPATCH() or goto error. */ - assert(0); + Py_UNREACHABLE(); error: diff --git a/Python/compile.c b/Python/compile.c index e547c2fd591..df5070aad2a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1350,8 +1350,7 @@ get_const_value(expr_ty e) case NameConstant_kind: return e->v.NameConstant.value; default: - assert(!is_const(e)); - return NULL; + Py_UNREACHABLE(); } } diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 9192bfd6a67..2df749493bf 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -351,8 +351,7 @@ calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align, *n_lpadding = 0; else { /* We should never have an unspecified alignment. */ - *n_lpadding = 0; - assert(0); + Py_UNREACHABLE(); } *n_rpadding = *n_total - nchars - *n_lpadding; @@ -569,9 +568,7 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, break; default: /* Shouldn't get here, but treat it as '>' */ - spec->n_lpadding = n_padding; - assert(0); - break; + Py_UNREACHABLE(); } } diff --git a/Python/pyhash.c b/Python/pyhash.c index a2ec2309c70..8a6bd60c105 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -175,7 +175,7 @@ _Py_HashBytes(const void *src, Py_ssize_t len) case 2: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ case 1: hash = ((hash << 5) + hash) + *p++; break; default: - assert(0); + Py_UNREACHABLE(); } hash ^= len; hash ^= (Py_uhash_t) _Py_HashSecret.djbx33a.suffix; diff --git a/Python/pystrtod.c b/Python/pystrtod.c index 64d0c52e487..f19d2399b38 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -431,8 +431,8 @@ _Py_string_to_number_with_underscores( error: PyMem_Free(dup); PyErr_Format(PyExc_ValueError, - "could not convert string to %s: " - "%R", what, obj); + "could not convert string to %s: " + "%R", what, obj); return NULL; } @@ -1061,7 +1061,7 @@ format_float_short(double d, char format_code, something starting with a digit, an 'I', or 'N' */ strncpy(p, "ERR", 3); /* p += 3; */ - assert(0); + Py_UNREACHABLE(); } goto exit; } diff --git a/Python/pytime.c b/Python/pytime.c index 7edb534596e..8f275d29839 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -630,10 +630,7 @@ _PyTime_GetSystemClock(void) _PyTime_t t; if (pygettimeofday(&t, NULL, 0) < 0) { /* should not happen, _PyTime_Init() checked the clock at startup */ - assert(0); - - /* use a fixed value instead of a random value from the stack */ - t = 0; + Py_UNREACHABLE(); } return t; } @@ -663,7 +660,7 @@ pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise) return -1; } /* Hello, time traveler! */ - assert(0); + Py_UNREACHABLE(); } *tp = t * MS_TO_NS; @@ -771,10 +768,7 @@ _PyTime_GetMonotonicClock(void) if (pymonotonic(&t, NULL, 0) < 0) { /* should not happen, _PyTime_Init() checked that monotonic clock at startup */ - assert(0); - - /* use a fixed value instead of a random value from the stack */ - t = 0; + Py_UNREACHABLE(); } return t; } diff --git a/Python/wordcode_helpers.h b/Python/wordcode_helpers.h index cce81c1d24e..c8f7a0f41f9 100644 --- a/Python/wordcode_helpers.h +++ b/Python/wordcode_helpers.h @@ -39,6 +39,6 @@ write_op_arg(_Py_CODEUNIT *codestr, unsigned char opcode, *codestr++ = PACKOPARG(opcode, oparg & 0xff); break; default: - assert(0); + Py_UNREACHABLE(); } }