PEP 7: Remove Python 2.2 advice, add C syntax highlighting and green/red sidebars (#3702)

This commit is contained in:
Hugo van Kemenade 2024-03-29 15:05:04 +02:00 committed by GitHub
parent 11b538f659
commit 3cdfdd90c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 95 additions and 81 deletions

View File

@ -1,14 +1,12 @@
PEP: 7
Title: Style Guide for C Code
Version: $Revision$
Last-Modified: $Date$
Author: Guido van Rossum <guido@python.org>, Barry Warsaw <barry@python.org>
Status: Active
Type: Process
Content-Type: text/x-rst
Created: 05-Jul-2001
Post-History:
.. highlight:: c
Introduction
============
@ -77,36 +75,51 @@ Code lay-out
* Function definition style: function name in column 1, outermost
curly braces in column 1, blank line after local variable
declarations. ::
declarations.
static int
extra_ivars(PyTypeObject *type, PyTypeObject *base)
{
int t_size = PyType_BASICSIZE(type);
int b_size = PyType_BASICSIZE(base);
.. code-block::
:class: good
assert(t_size >= b_size); /* type smaller than base! */
...
return 1;
}
static int
extra_ivars(PyTypeObject *type, PyTypeObject *base)
{
int t_size = PyType_BASICSIZE(type);
int b_size = PyType_BASICSIZE(base);
assert(t_size >= b_size); /* type smaller than base! */
...
return 1;
}
* Code structure: one space between keywords like ``if``, ``for`` and
the following left paren; no spaces inside the paren; braces are
required everywhere, even where C permits them to be omitted, but do
not add them to code you are not otherwise modifying. All new C
code requires braces. Braces should be formatted as shown::
code requires braces. Braces should be formatted as shown:
if (mro != NULL) {
...
}
else {
...
}
.. code-block::
:class: good
* The return statement should *not* get redundant parentheses::
if (mro != NULL) {
...
}
else {
...
}
return albatross; /* correct */
return(albatross); /* incorrect */
* The return statement should *not* get redundant parentheses:
.. code-block::
:class: bad
return(albatross); /* incorrect */
Instead:
.. code-block::
:class: good
return albatross; /* correct */
* Function and macro call style: ``foo(a, b, c)`` -- no space before
the open paren, no spaces inside the parens, no spaces before
@ -118,39 +131,48 @@ Code lay-out
* Breaking long lines: if you can, break after commas in the outermost
argument list. Always indent continuation lines appropriately,
e.g.::
e.g.:
PyErr_Format(PyExc_TypeError,
"cannot create '%.100s' instances",
type->tp_name);
.. code-block::
:class: good
PyErr_Format(PyExc_TypeError,
"cannot create '%.100s' instances",
type->tp_name);
* When you break a long expression at a binary operator, the
operator goes at the end of the previous line, and braces should be
formatted as shown. E.g.::
formatted as shown. E.g.:
if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
type->tp_dictoffset == b_size &&
(size_t)t_size == b_size + sizeof(PyObject *))
{
return 0; /* "Forgive" adding a __dict__ only */
}
.. code-block::
:class: good
if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
type->tp_dictoffset == b_size &&
(size_t)t_size == b_size + sizeof(PyObject *))
{
return 0; /* "Forgive" adding a __dict__ only */
}
* Vertically align line continuation characters in multi-line macros.
* Macros intended to be used as a statement should use the
``do { ... } while (0)`` macro idiom,
without a final semicolon.
Example::
Example:
#define ADD_INT_MACRO(MOD, INT) \
do { \
if (PyModule_AddIntConstant((MOD), (#INT), (INT)) < 0) { \
goto error; \
} \
} while (0)
.. code-block::
:class: good
// To be used like a statement with a semicolon:
ADD_INT_MACRO(m, SOME_CONSTANT);
#define ADD_INT_MACRO(MOD, INT) \
do { \
if (PyModule_AddIntConstant((MOD), (#INT), (INT)) < 0) { \
goto error; \
} \
} while (0)
// To be used like a statement with a semicolon:
ADD_INT_MACRO(m, SOME_CONSTANT);
* ``#undef`` file local macros after use.
@ -160,15 +182,18 @@ Code lay-out
* Comments go before the code they describe.
* All functions and global variables should be declared static unless
they are to be part of a published interface
they are to be part of a published interface.
* For external functions and variables, we always have a declaration
in an appropriate header file in the "Include" directory, which uses
the ``PyAPI_FUNC()`` macro and ``PyAPI_DATA()`` macro, like this::
the ``PyAPI_FUNC()`` macro and ``PyAPI_DATA()`` macro, like this:
PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
.. code-block::
:class: good
PyAPI_DATA(PyTypeObject) PySuper_Type;
PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
PyAPI_DATA(PyTypeObject) PySuper_Type;
Naming conventions
@ -200,44 +225,44 @@ Documentation Strings
to support building Python without docstrings (``./configure
--without-doc-strings``).
For C code that needs to support versions of Python older than 2.3,
you can include this after including ``Python.h``::
#ifndef PyDoc_STR
#define PyDoc_VAR(name) static char name[]
#define PyDoc_STR(str) (str)
#define PyDoc_STRVAR(name, str) PyDoc_VAR(name) = PyDoc_STR(str)
#endif
* The first line of each function docstring should be a "signature
line" that gives a brief synopsis of the arguments and return value.
For example::
For example:
PyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool\n\n\
Determine whether name and value make a valid pair.");
.. code-block::
:class: good
PyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool\n\n\
Determine whether name and value make a valid pair.");
Always include a blank line between the signature line and the text
of the description.
If the return value for the function is always None (because there
If the return value for the function is always ``None`` (because there
is no meaningful return value), do not include the indication of the
return type.
* When writing multi-line docstrings, be sure to always use backslash
continuations, as in the example above, or string literal
concatenation::
concatenation:
PyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool\n\n"
"Determine whether name and value make a valid pair.");
.. code-block::
:class: good
Though some C compilers accept string literals without either::
PyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool\n\n"
"Determine whether name and value make a valid pair.");
/* BAD -- don't do this! */
PyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool\n\n
Determine whether name and value make a valid pair.");
Though some C compilers accept string literals without either:
.. code-block::
:class: bad
/* BAD -- don't do this! */
PyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool\n\n
Determine whether name and value make a valid pair.");
not all do; the MSVC compiler is known to complain about this.
@ -246,14 +271,3 @@ Copyright
=========
This document has been placed in the public domain.
..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End: