python-peps/pep-0007/index.html

341 lines
25 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 7 Style Guide for C Code | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0007/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 7 Style Guide for C Code | peps.python.org'>
<meta property="og:description" content="This document gives coding conventions for the C code comprising the C implementation of Python. Please see the companion informational PEP describing style guidelines for Python code.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0007/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="This document gives coding conventions for the C code comprising the C implementation of Python. Please see the companion informational PEP describing style guidelines for Python code.">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 7</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 7 Style Guide for C Code</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Guido van Rossum &lt;guido&#32;&#97;t&#32;python.org&gt;, Barry Warsaw &lt;barry&#32;&#97;t&#32;python.org&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Currently valid informational guidance, or an in-use process">Active</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Normative PEP describing or proposing a change to a Python community process, workflow or governance">Process</abbr></dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even">05-Jul-2001</dd>
<dt class="field-odd">Post-History<span class="colon">:</span></dt>
<dd class="field-odd"><p></p></dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#c-dialect">C dialect</a></li>
<li><a class="reference internal" href="#code-lay-out">Code lay-out</a></li>
<li><a class="reference internal" href="#naming-conventions">Naming conventions</a></li>
<li><a class="reference internal" href="#documentation-strings">Documentation Strings</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="introduction">
<h2><a class="toc-backref" href="#introduction" role="doc-backlink">Introduction</a></h2>
<p>This document gives coding conventions for the C code comprising the C
implementation of Python. Please see the companion informational PEP
describing <a class="pep reference internal" href="../pep-0008/" title="PEP 8 Style Guide for Python Code">style guidelines for Python code</a>.</p>
<p>Note, rules are there to be broken. Two good reasons to break a
particular rule:</p>
<ol class="arabic simple">
<li>When applying the rule would make the code less readable, even for
someone who is used to reading code that follows the rules.</li>
<li>To be consistent with surrounding code that also breaks it (maybe
for historic reasons) although this is also an opportunity to
clean up someone elses mess (in true XP style).</li>
</ol>
</section>
<section id="c-dialect">
<h2><a class="toc-backref" href="#c-dialect" role="doc-backlink">C dialect</a></h2>
<ul class="simple">
<li>Python 3.11 and newer versions use C11 without <a class="reference external" href="https://en.wikipedia.org/wiki/C11_%28C_standard_revision%29#Optional_features">optional features</a>.
The public C API should be compatible with C++.</li>
<li>Python 3.6 to 3.10 use C89 with several select C99 features:<ul>
<li>Standard integer types in <code class="docutils literal notranslate"><span class="pre">&lt;stdint.h&gt;</span></code> and <code class="docutils literal notranslate"><span class="pre">&lt;inttypes.h&gt;</span></code>. We
require the fixed width integer types.</li>
<li><code class="docutils literal notranslate"><span class="pre">static</span> <span class="pre">inline</span></code> functions</li>
<li>designated initializers (especially nice for type declarations)</li>
<li>intermingled declarations</li>
<li>booleans</li>
<li>C++-style line comments</li>
</ul>
</li>
<li>Python versions before 3.6 used ANSI/ISO standard C (the 1989 version
of the standard). This meant (amongst many other things) that all
declarations must be at the top of a block (not necessarily at the
top of function).</li>
<li>Dont use compiler-specific extensions, such as those of GCC or MSVC
(e.g. dont write multi-line strings without trailing backslashes).</li>
<li>All function declarations and definitions must use full prototypes
(i.e. specify the types of all arguments).</li>
<li>No compiler warnings with major compilers (gcc, VC++, a few others).</li>
<li><code class="docutils literal notranslate"><span class="pre">static</span> <span class="pre">inline</span></code> functions should be preferred over macros in new
code.</li>
</ul>
</section>
<section id="code-lay-out">
<h2><a class="toc-backref" href="#code-lay-out" role="doc-backlink">Code lay-out</a></h2>
<ul>
<li>Use 4-space indents and no tabs at all.</li>
<li>No line should be longer than 79 characters. If this and the
previous rule together dont give you enough room to code, your code
is too complicated consider using subroutines.</li>
<li>No line should end in whitespace. If you think you need significant
trailing whitespace, think again somebodys editor might delete
it as a matter of routine.</li>
<li>Function definition style: function name in column 1, outermost
curly braces in column 1, blank line after local variable
declarations.<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">int</span>
<span class="nf">extra_ivars</span><span class="p">(</span><span class="n">PyTypeObject</span><span class="w"> </span><span class="o">*</span><span class="n">type</span><span class="p">,</span><span class="w"> </span><span class="n">PyTypeObject</span><span class="w"> </span><span class="o">*</span><span class="n">base</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">t_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyType_BASICSIZE</span><span class="p">(</span><span class="n">type</span><span class="p">);</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">b_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyType_BASICSIZE</span><span class="p">(</span><span class="n">base</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">t_size</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">b_size</span><span class="p">);</span><span class="w"> </span><span class="cm">/* type smaller than base! */</span>
<span class="w"> </span><span class="p">...</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li>Code structure: one space between keywords like <code class="docutils literal notranslate"><span class="pre">if</span></code>, <code class="docutils literal notranslate"><span class="pre">for</span></code> 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:<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">mro</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">...</span>
<span class="p">}</span>
<span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">...</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li>The return statement should <em>not</em> get redundant parentheses:<div class="bad highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">return</span><span class="p">(</span><span class="n">albatross</span><span class="p">);</span><span class="w"> </span><span class="cm">/* incorrect */</span>
</pre></div>
</div>
<p>Instead:</p>
<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">return</span><span class="w"> </span><span class="n">albatross</span><span class="p">;</span><span class="w"> </span><span class="cm">/* correct */</span>
</pre></div>
</div>
</li>
<li>Function and macro call style: <code class="docutils literal notranslate"><span class="pre">foo(a,</span> <span class="pre">b,</span> <span class="pre">c)</span></code> no space before
the open paren, no spaces inside the parens, no spaces before
commas, one space after each comma.</li>
<li>Always put spaces around assignment, Boolean and comparison
operators. In expressions using a lot of operators, add spaces
around the outermost (lowest-priority) operators.</li>
<li>Breaking long lines: if you can, break after commas in the outermost
argument list. Always indent continuation lines appropriately,
e.g.:<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyErr_Format</span><span class="p">(</span><span class="n">PyExc_TypeError</span><span class="p">,</span>
<span class="w"> </span><span class="s">&quot;cannot create &#39;%.100s&#39; instances&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="n">type</span><span class="o">-&gt;</span><span class="n">tp_name</span><span class="p">);</span>
</pre></div>
</div>
</li>
<li>When you break a long expression at a binary operator, braces
should be formatted as shown:<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">type</span><span class="o">-&gt;</span><span class="n">tp_dictoffset</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">base</span><span class="o">-&gt;</span><span class="n">tp_dictoffset</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">type</span><span class="o">-&gt;</span><span class="n">tp_dictoffset</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">b_size</span>
<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span><span class="kt">size_t</span><span class="p">)</span><span class="n">t_size</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">b_size</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="p">))</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="cm">/* &quot;Forgive&quot; adding a __dict__ only */</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Its OK to put operators at ends of lines, especially to be
consistent with surrounding code.
(See <a class="reference internal" href="../pep-0008/#pep8-operator-linebreak"><span class="std std-ref">PEP 8</span></a> for a longer discussion.)</p>
</li>
<li>Vertically align line continuation characters in multi-line macros.</li>
<li>Macros intended to be used as a statement should use the
<code class="docutils literal notranslate"><span class="pre">do</span> <span class="pre">{</span> <span class="pre">...</span> <span class="pre">}</span> <span class="pre">while</span> <span class="pre">(0)</span></code> macro idiom,
without a final semicolon.
Example:<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define ADD_INT_MACRO(MOD, INT) \</span>
<span class="cp"> do { \</span>
<span class="cp"> if (PyModule_AddIntConstant((MOD), (#INT), (INT)) &lt; 0) { \</span>
<span class="cp"> goto error; \</span>
<span class="cp"> } \</span>
<span class="cp"> } while (0)</span>
<span class="c1">// To be used like a statement with a semicolon:</span>
<span class="n">ADD_INT_MACRO</span><span class="p">(</span><span class="n">m</span><span class="p">,</span><span class="w"> </span><span class="n">SOME_CONSTANT</span><span class="p">);</span>
</pre></div>
</div>
</li>
<li><code class="docutils literal notranslate"><span class="pre">#undef</span></code> file local macros after use.</li>
<li>Put blank lines around functions, structure definitions, and major
sections inside functions.</li>
<li>Comments go before the code they describe.</li>
<li>All functions and global variables should be declared static unless
they are to be part of a published interface.</li>
<li>For external functions and variables, we always have a declaration
in an appropriate header file in the “Include” directory, which uses
the <code class="docutils literal notranslate"><span class="pre">PyAPI_FUNC()</span></code> macro and <code class="docutils literal notranslate"><span class="pre">PyAPI_DATA()</span></code> macro, like this:<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyAPI_FUNC</span><span class="p">(</span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="n">PyObject_Repr</span><span class="p">(</span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="p">);</span>
<span class="n">PyAPI_DATA</span><span class="p">(</span><span class="n">PyTypeObject</span><span class="p">)</span><span class="w"> </span><span class="n">PySuper_Type</span><span class="p">;</span>
</pre></div>
</div>
</li>
</ul>
</section>
<section id="naming-conventions">
<h2><a class="toc-backref" href="#naming-conventions" role="doc-backlink">Naming conventions</a></h2>
<ul class="simple">
<li>Use a <code class="docutils literal notranslate"><span class="pre">Py</span></code> prefix for public functions; never for static
functions. The <code class="docutils literal notranslate"><span class="pre">Py_</span></code> prefix is reserved for global service
routines like <code class="docutils literal notranslate"><span class="pre">Py_FatalError</span></code>; specific groups of routines
(e.g. specific object type APIs) use a longer prefix,
e.g. <code class="docutils literal notranslate"><span class="pre">PyString_</span></code> for string functions.</li>
<li>Public functions and variables use MixedCase with underscores, like
this: <code class="docutils literal notranslate"><span class="pre">PyObject_GetAttr</span></code>, <code class="docutils literal notranslate"><span class="pre">Py_BuildValue</span></code>, <code class="docutils literal notranslate"><span class="pre">PyExc_TypeError</span></code>.</li>
<li>Occasionally an “internal” function has to be visible to the loader;
we use the <code class="docutils literal notranslate"><span class="pre">_Py</span></code> prefix for this, e.g.: <code class="docutils literal notranslate"><span class="pre">_PyObject_Dump</span></code>.</li>
<li>Macros should have a MixedCase prefix and then use upper case, for
example: <code class="docutils literal notranslate"><span class="pre">PyString_AS_STRING</span></code>, <code class="docutils literal notranslate"><span class="pre">Py_PRINT_RAW</span></code>.</li>
<li>Macro parameters should use <code class="docutils literal notranslate"><span class="pre">ALL_CAPS</span></code> style,
so they are easily distinguishable from C variables and struct members.</li>
</ul>
</section>
<section id="documentation-strings">
<h2><a class="toc-backref" href="#documentation-strings" role="doc-backlink">Documentation Strings</a></h2>
<ul>
<li>Use the <code class="docutils literal notranslate"><span class="pre">PyDoc_STR()</span></code> or <code class="docutils literal notranslate"><span class="pre">PyDoc_STRVAR()</span></code> macro for docstrings
to support building Python without docstrings (<code class="docutils literal notranslate"><span class="pre">./configure</span>
<span class="pre">--without-doc-strings</span></code>).</li>
<li>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:<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyDoc_STRVAR</span><span class="p">(</span><span class="n">myfunction__doc__</span><span class="p">,</span>
<span class="s">&quot;myfunction(name, value) -&gt; bool</span><span class="se">\n\n</span><span class="s">\</span>
<span class="s">Determine whether name and value make a valid pair.&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>Always include a blank line between the signature line and the text
of the description.</p>
<p>If the return value for the function is always <code class="docutils literal notranslate"><span class="pre">None</span></code> (because there
is no meaningful return value), do not include the indication of the
return type.</p>
</li>
<li>When writing multi-line docstrings, be sure to always use backslash
continuations, as in the example above, or string literal
concatenation:<div class="good highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyDoc_STRVAR</span><span class="p">(</span><span class="n">myfunction__doc__</span><span class="p">,</span>
<span class="s">&quot;myfunction(name, value) -&gt; bool</span><span class="se">\n\n</span><span class="s">&quot;</span>
<span class="s">&quot;Determine whether name and value make a valid pair.&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>Though some C compilers accept string literals without either:</p>
<div class="bad highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/* BAD -- don&#39;t do this! */</span>
<span class="n">PyDoc_STRVAR</span><span class="p">(</span><span class="n">myfunction__doc__</span><span class="p">,</span>
<span class="s">&quot;myfunction(name, value) -&gt; bool</span><span class="se">\n\n</span>
<span class="n">Determine</span><span class="w"> </span><span class="n">whether</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="n">and</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="n">make</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">valid</span><span class="w"> </span><span class="n">pair</span><span class="p">.</span><span class="s">&quot;);</span>
</pre></div>
</div>
<p>not all do; the MSVC compiler is known to complain about this.</p>
</li>
</ul>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0007.rst">https://github.com/python/peps/blob/main/peps/pep-0007.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0007.rst">2024-09-09 14:02:27 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#c-dialect">C dialect</a></li>
<li><a class="reference internal" href="#code-lay-out">Code lay-out</a></li>
<li><a class="reference internal" href="#naming-conventions">Naming conventions</a></li>
<li><a class="reference internal" href="#documentation-strings">Documentation Strings</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0007.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>