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
Merged
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
62 changes: 57 additions & 5 deletions 62 Doc/c-api/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions 2 Include/pymacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,6 @@
#define Py_UNUSED(name) _unused_ ## name
#endif

#define Py_UNREACHABLE() abort()

#endif /* Py_PYMACRO_H */
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 1 addition & 2 deletions 3 Modules/_datetimemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions 3 Modules/_pickle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
2 changes: 1 addition & 1 deletion 2 Modules/_tracemalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
3 changes: 1 addition & 2 deletions 3 Modules/mathmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion 2 Objects/abstract.c
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,7 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
goto Done;

default:
assert(!"unknown operation");
Py_UNREACHABLE();
}
}

Expand Down
2 changes: 1 addition & 1 deletion 2 Objects/bytesobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand Down
18 changes: 6 additions & 12 deletions 18 Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

/*
Expand Down Expand Up @@ -723,8 +722,7 @@ lookdict(PyDictObject *mp, PyObject *key,
perturb >>= PERTURB_SHIFT;
i = (i*5 + perturb + 1) & mask;
}
assert(0); /* NOT REACHED */
return 0;
Py_UNREACHABLE();
}

/* Specialized version for string-only keys */
Expand Down Expand Up @@ -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 <dummy> keys
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 3 additions & 4 deletions 7 Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions 3 Objects/stringlib/eq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.