1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
- <meta property="og:title" content="Argument Clinic How-To" />
- <meta property="og:type" content="website" />
- <meta property="og:url" content="https://docs.python.org/3/howto/clinic.html" />
- <meta property="og:site_name" content="Python documentation" />
- <meta property="og:description" content="author, Larry Hastings,. Source code: Tools/clinic/clinic.py. Abstract: Argument Clinic is a preprocessor for CPython C files. It was introduced in Python 3.4 with PEP 436, in order to provide intr..." />
- <meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
- <meta property="og:image:alt" content="Python documentation" />
- <meta name="description" content="author, Larry Hastings,. Source code: Tools/clinic/clinic.py. Abstract: Argument Clinic is a preprocessor for CPython C files. It was introduced in Python 3.4 with PEP 436, in order to provide intr..." />
- <meta property="og:image:width" content="200" />
- <meta property="og:image:height" content="200" />
- <meta name="theme-color" content="#3776ab" />
- <title>Argument Clinic How-To — Python 3.12.0 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
-
- <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
- <link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?digest=b37c26da2f7529d09fe70b41c4b2133fe4931a90" />
- <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css" />
-
- <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
-
- <script src="../_static/sidebar.js"></script>
-
- <link rel="search" type="application/opensearchdescription+xml"
- title="Search within Python 3.12.0 documentation"
- href="../_static/opensearch.xml"/>
- <link rel="author" title="About these documents" href="../about.html" />
- <link rel="index" title="Index" href="../genindex.html" />
- <link rel="search" title="Search" href="../search.html" />
- <link rel="copyright" title="Copyright" href="../copyright.html" />
- <link rel="next" title="Instrumenting CPython with DTrace and SystemTap" href="instrumentation.html" />
- <link rel="prev" title="An introduction to the ipaddress module" href="ipaddress.html" />
- <link rel="canonical" href="https://docs.python.org/3/howto/clinic.html" />
-
-
-
-
- <style>
- @media only screen {
- table.full-width-table {
- width: 100%;
- }
- }
- </style>
- <link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
- <link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
- <script type="text/javascript" src="../_static/copybutton.js"></script>
- <script type="text/javascript" src="../_static/menu.js"></script>
- <script type="text/javascript" src="../_static/themetoggle.js"></script>
- </head>
- <body>
- <div class="mobile-nav">
- <input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
- aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
- <nav class="nav-content" role="navigation">
- <label for="menuToggler" class="toggler__label">
- <span></span>
- </label>
- <span class="nav-items-wrapper">
- <a href="https://www.python.org/" class="nav-logo">
- <img src="../_static/py.svg" alt="Logo"/>
- </a>
- <span class="version_switcher_placeholder"></span>
- <form role="search" class="search" action="../search.html" method="get">
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
- <path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
- </svg>
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
- <input type="submit" value="Go"/>
- </form>
- </span>
- </nav>
- <div class="menu-wrapper">
- <nav class="menu" role="navigation" aria-label="main navigation">
- <div class="language_switcher_placeholder"></div>
-
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label>
- <div>
- <h3><a href="../contents.html">Table of Contents</a></h3>
- <ul>
- <li><a class="reference internal" href="#">Argument Clinic How-To</a><ul>
- <li><a class="reference internal" href="#background">Background</a><ul>
- <li><a class="reference internal" href="#basic-concepts">Basic concepts</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#reference">Reference</a><ul>
- <li><a class="reference internal" href="#terminology">Terminology</a></li>
- <li><a class="reference internal" href="#command-line-interface">Command-line interface</a></li>
- <li><a class="reference internal" href="#module-clinic">Classes for extending Argument Clinic</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#tutorial">Tutorial</a></li>
- <li><a class="reference internal" href="#how-to-guides">How-to guides</a><ul>
- <li><a class="reference internal" href="#how-to-rename-c-functions-and-variables-generated-by-argument-clinic">How to rename C functions and variables generated by Argument Clinic</a></li>
- <li><a class="reference internal" href="#how-to-convert-functions-using-pyarg-unpacktuple">How to convert functions using <code class="docutils literal notranslate"><span class="pre">PyArg_UnpackTuple</span></code></a></li>
- <li><a class="reference internal" href="#how-to-use-optional-groups">How to use optional groups</a></li>
- <li><a class="reference internal" href="#how-to-use-real-argument-clinic-converters-instead-of-legacy-converters">How to use real Argument Clinic converters, instead of “legacy converters”</a></li>
- <li><a class="reference internal" href="#how-to-use-the-py-buffer-converter">How to use the <code class="docutils literal notranslate"><span class="pre">Py_buffer</span></code> converter</a></li>
- <li><a class="reference internal" href="#how-to-use-advanced-converters">How to use advanced converters</a></li>
- <li><a class="reference internal" href="#how-to-assign-default-values-to-parameter">How to assign default values to parameter</a><ul>
- <li><a class="reference internal" href="#the-null-default-value">The <code class="docutils literal notranslate"><span class="pre">NULL</span></code> default value</a></li>
- <li><a class="reference internal" href="#symbolic-default-values">Symbolic default values</a></li>
- <li><a class="reference internal" href="#expressions-as-default-values">Expressions as default values</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#how-to-use-return-converters">How to use return converters</a></li>
- <li><a class="reference internal" href="#how-to-clone-existing-functions">How to clone existing functions</a></li>
- <li><a class="reference internal" href="#how-to-call-python-code">How to call Python code</a></li>
- <li><a class="reference internal" href="#how-to-use-the-self-converter">How to use the “self converter”</a></li>
- <li><a class="reference internal" href="#how-to-use-the-defining-class-converter">How to use the “defining class” converter</a></li>
- <li><a class="reference internal" href="#how-to-write-a-custom-converter">How to write a custom converter</a></li>
- <li><a class="reference internal" href="#how-to-write-a-custom-return-converter">How to write a custom return converter</a></li>
- <li><a class="reference internal" href="#how-to-convert-meth-o-and-meth-noargs-functions">How to convert <code class="docutils literal notranslate"><span class="pre">METH_O</span></code> and <code class="docutils literal notranslate"><span class="pre">METH_NOARGS</span></code> functions</a></li>
- <li><a class="reference internal" href="#how-to-convert-tp-new-and-tp-init-functions">How to convert <code class="docutils literal notranslate"><span class="pre">tp_new</span></code> and <code class="docutils literal notranslate"><span class="pre">tp_init</span></code> functions</a></li>
- <li><a class="reference internal" href="#how-to-change-and-redirect-clinic-s-output">How to change and redirect Clinic’s output</a></li>
- <li><a class="reference internal" href="#how-to-use-the-ifdef-trick">How to use the <code class="docutils literal notranslate"><span class="pre">#ifdef</span></code> trick</a></li>
- <li><a class="reference internal" href="#how-to-use-argument-clinic-in-python-files">How to use Argument Clinic in Python files</a></li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- </div>
- <div>
- <h4>Previous topic</h4>
- <p class="topless"><a href="ipaddress.html"
- title="previous chapter">An introduction to the ipaddress module</a></p>
- </div>
- <div>
- <h4>Next topic</h4>
- <p class="topless"><a href="instrumentation.html"
- title="next chapter">Instrumenting CPython with DTrace and SystemTap</a></p>
- </div>
- <div role="note" aria-label="source link">
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../bugs.html">Report a Bug</a></li>
- <li>
- <a href="https://github.com/python/cpython/blob/main/Doc/howto/clinic.rst"
- rel="nofollow">Show Source
- </a>
- </li>
- </ul>
- </div>
- </nav>
- </div>
- </div>
-
- <div class="related" role="navigation" aria-label="related navigation">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- accesskey="I">index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="instrumentation.html" title="Instrumenting CPython with DTrace and SystemTap"
- accesskey="N">next</a> |</li>
- <li class="right" >
- <a href="ipaddress.html" title="An introduction to the ipaddress module"
- accesskey="P">previous</a> |</li>
- <li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
- <li><a href="https://www.python.org/">Python</a> »</li>
- <li class="switchers">
- <div class="language_switcher_placeholder"></div>
- <div class="version_switcher_placeholder"></div>
- </li>
- <li>
-
- </li>
- <li id="cpython-language-and-version">
- <a href="../index.html">3.12.0 Documentation</a> »
- </li>
- <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python HOWTOs</a> »</li>
- <li class="nav-item nav-item-this"><a href="">Argument Clinic How-To</a></li>
- <li class="right">
-
- <div class="inline-search" role="search">
- <form class="inline-search" action="../search.html" method="get">
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
- <input type="submit" value="Go" />
- </form>
- </div>
- |
- </li>
- <li class="right">
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label> |</li>
-
- </ul>
- </div>
- <div class="document">
- <div class="documentwrapper">
- <div class="bodywrapper">
- <div class="body" role="main">
-
- <section id="argument-clinic-how-to">
- <span id="howto-clinic"></span><h1>Argument Clinic How-To<a class="headerlink" href="#argument-clinic-how-to" title="Permalink to this headline">¶</a></h1>
- <dl class="field-list simple">
- <dt class="field-odd">author</dt>
- <dd class="field-odd"><p>Larry Hastings</p>
- </dd>
- </dl>
- <p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.12/Tools/clinic/clinic.py">Tools/clinic/clinic.py</a>.</p>
- <div class="topic">
- <p class="topic-title">Abstract</p>
- <p>Argument Clinic is a preprocessor for CPython C files.
- It was introduced in Python 3.4 with <span class="target" id="index-0"></span><a class="pep reference external" href="https://peps.python.org/pep-0436/"><strong>PEP 436</strong></a>,
- in order to provide introspection signatures,
- and to generate performant and tailor-made boilerplate code
- for argument parsing in CPython builtins,
- module level functions, and class methods.
- This document is divided in four major sections:</p>
- <ul class="simple">
- <li><p><a class="reference internal" href="#clinic-background"><span class="std std-ref">Background</span></a> talks about the basic concepts and goals of
- Argument Clinic.</p></li>
- <li><p><a class="reference internal" href="#clinic-reference"><span class="std std-ref">Reference</span></a> describes the command-line interface and Argument
- Clinic terminology.</p></li>
- <li><p><a class="reference internal" href="#clinic-tutorial"><span class="std std-ref">Tutorial</span></a> guides you through all the steps required to
- adapt an existing C function to Argument Clinic.</p></li>
- <li><p><a class="reference internal" href="#clinic-howtos"><span class="std std-ref">How-to guides</span></a> details how to handle specific tasks.</p></li>
- </ul>
- </div>
- <div class="admonition note">
- <p class="admonition-title">Note</p>
- <p>Argument Clinic is considered internal-only
- for CPython. Its use is not supported for files outside
- CPython, and no guarantees are made regarding backwards
- compatibility for future versions. In other words: if you
- maintain an external C extension for CPython, you’re welcome
- to experiment with Argument Clinic in your own code. But the
- version of Argument Clinic that ships with the next version
- of CPython <em>could</em> be totally incompatible and break all your code.</p>
- </div>
- <section id="background">
- <span id="clinic-background"></span><h2>Background<a class="headerlink" href="#background" title="Permalink to this headline">¶</a></h2>
- <section id="basic-concepts">
- <h3>Basic concepts<a class="headerlink" href="#basic-concepts" title="Permalink to this headline">¶</a></h3>
- <p>When Argument Clinic is run on a file, either via the <a class="reference internal" href="#clinic-cli"><span class="std std-ref">Command-line interface</span></a>
- or via <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">clinic</span></code>, it will scan over the input files looking for
- <a class="reference internal" href="#term-start-line"><span class="xref std std-term">start lines</span></a>:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>/*[clinic input]
- </pre></div>
- </div>
- <p>When it finds one, it reads everything up to the <a class="reference internal" href="#term-end-line"><span class="xref std std-term">end line</span></a>:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>[clinic start generated code]*/
- </pre></div>
- </div>
- <p>Everything in between these two lines is Argument Clinic <a class="reference internal" href="#term-input"><span class="xref std std-term">input</span></a>.
- When Argument Clinic parses input, it generates <a class="reference internal" href="#term-output"><span class="xref std std-term">output</span></a>.
- The output is rewritten into the C file immediately after the input,
- followed by a <a class="reference internal" href="#term-checksum-line"><span class="xref std std-term">checksum line</span></a>.
- All of these lines, including the <a class="reference internal" href="#term-start-line"><span class="xref std std-term">start line</span></a> and <a class="reference internal" href="#term-checksum-line"><span class="xref std std-term">checksum line</span></a>,
- are collectively called an Argument Clinic <a class="reference internal" href="#term-block"><span class="xref std std-term">block</span></a>:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>/*[clinic input]
- ... clinic input goes here ...
- [clinic start generated code]*/
- ... clinic output goes here ...
- /*[clinic end generated code: ...]*/
- </pre></div>
- </div>
- <p>If you run Argument Clinic on the same file a second time, Argument Clinic
- will discard the old <a class="reference internal" href="#term-output"><span class="xref std std-term">output</span></a> and write out the new output with a fresh
- <a class="reference internal" href="#term-checksum-line"><span class="xref std std-term">checksum line</span></a>.
- If the <a class="reference internal" href="#term-input"><span class="xref std std-term">input</span></a> hasn’t changed, the output won’t change either.</p>
- <div class="admonition note">
- <p class="admonition-title">Note</p>
- <p>You should never modify the output of an Argument Clinic block,
- as any change will be lost in future Argument Clinic runs;
- Argument Clinic will detect an output checksum mismatch and regenerate the
- correct output.
- If you are not happy with the generated output,
- you should instead change the input until it produces the output you want.</p>
- </div>
- </section>
- </section>
- <section id="reference">
- <span id="clinic-reference"></span><h2>Reference<a class="headerlink" href="#reference" title="Permalink to this headline">¶</a></h2>
- <section id="terminology">
- <span id="clinic-terminology"></span><h3>Terminology<a class="headerlink" href="#terminology" title="Permalink to this headline">¶</a></h3>
- <dl class="glossary simple">
- <dt id="term-start-line">start line<a class="headerlink" href="#term-start-line" title="Permalink to this term">¶</a></dt><dd><p>The line <code class="docutils literal notranslate"><span class="pre">/*[clinic</span> <span class="pre">input]</span></code>.
- This line marks the beginning of Argument Clinic input.
- Note that the <em>start line</em> opens a C block comment.</p>
- </dd>
- <dt id="term-end-line">end line<a class="headerlink" href="#term-end-line" title="Permalink to this term">¶</a></dt><dd><p>The line <code class="docutils literal notranslate"><span class="pre">[clinic</span> <span class="pre">start</span> <span class="pre">generated</span> <span class="pre">code]*/</span></code>.
- The <em>end line</em> marks the _end_ of Argument Clinic <a class="reference internal" href="#term-input"><span class="xref std std-term">input</span></a>,
- but at the same time marks the _start_ of Argument Clinic <a class="reference internal" href="#term-output"><span class="xref std std-term">output</span></a>,
- thus the text <em>“clinic start start generated code”</em>
- Note that the <em>end line</em> closes the C block comment opened
- by the <em>start line</em>.</p>
- </dd>
- <dt id="term-checksum">checksum<a class="headerlink" href="#term-checksum" title="Permalink to this term">¶</a></dt><dd><p>A hash to distinguish unique <a class="reference internal" href="#term-input"><span class="xref std std-term">inputs</span></a>
- and <a class="reference internal" href="#term-output"><span class="xref std std-term">outputs</span></a>.</p>
- </dd>
- <dt id="term-checksum-line">checksum line<a class="headerlink" href="#term-checksum-line" title="Permalink to this term">¶</a></dt><dd><p>A line that looks like <code class="docutils literal notranslate"><span class="pre">/*[clinic</span> <span class="pre">end</span> <span class="pre">generated</span> <span class="pre">code:</span> <span class="pre">...]*/</span></code>.
- The three dots will be replaced by a <a class="reference internal" href="#term-checksum"><span class="xref std std-term">checksum</span></a> generated from the
- <a class="reference internal" href="#term-input"><span class="xref std std-term">input</span></a>, and a <a class="reference internal" href="#term-checksum"><span class="xref std std-term">checksum</span></a> generated from the <a class="reference internal" href="#term-output"><span class="xref std std-term">output</span></a>.
- The checksum line marks the end of Argument Clinic generated code,
- and is used by Argument Clinic to determine if it needs to regenerate
- output.</p>
- </dd>
- <dt id="term-input">input<a class="headerlink" href="#term-input" title="Permalink to this term">¶</a></dt><dd><p>The text between the <a class="reference internal" href="#term-start-line"><span class="xref std std-term">start line</span></a> and the <a class="reference internal" href="#term-end-line"><span class="xref std std-term">end line</span></a>.
- Note that the start and end lines open and close a C block comment;
- the <em>input</em> is thus a part of that same C block comment.</p>
- </dd>
- <dt id="term-output">output<a class="headerlink" href="#term-output" title="Permalink to this term">¶</a></dt><dd><p>The text between the <a class="reference internal" href="#term-end-line"><span class="xref std std-term">end line</span></a> and the <a class="reference internal" href="#term-checksum-line"><span class="xref std std-term">checksum line</span></a>.</p>
- </dd>
- <dt id="term-block">block<a class="headerlink" href="#term-block" title="Permalink to this term">¶</a></dt><dd><p>All text from the <a class="reference internal" href="#term-start-line"><span class="xref std std-term">start line</span></a> to the <a class="reference internal" href="#term-checksum-line"><span class="xref std std-term">checksum line</span></a> inclusively.</p>
- </dd>
- </dl>
- </section>
- <section id="command-line-interface">
- <span id="clinic-cli"></span><h3>Command-line interface<a class="headerlink" href="#command-line-interface" title="Permalink to this headline">¶</a></h3>
- <p>The Argument Clinic <abbr title="Command-Line Interface">CLI</abbr> is typically used to
- process a single source file, like this:</p>
- <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>python3<span class="w"> </span>./Tools/clinic/clinic.py<span class="w"> </span>foo.c
- </pre></div>
- </div>
- <p>The CLI supports the following options:</p>
- <dl class="std option">
- <dt class="sig sig-object std" id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-h">
- <span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-h"></span><span id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-help"></span><span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-help"></span><span class="sig-name descname"><span class="pre">-h</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--help</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-h" title="Permalink to this definition">¶</a></dt>
- <dd><p>Print CLI usage.</p>
- </dd></dl>
- <dl class="std option">
- <dt class="sig sig-object std" id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-f">
- <span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-f"></span><span id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-force"></span><span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-force"></span><span class="sig-name descname"><span class="pre">-f</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--force</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-f" title="Permalink to this definition">¶</a></dt>
- <dd><p>Force output regeneration.</p>
- </dd></dl>
- <dl class="std option">
- <dt class="sig sig-object std" id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-o">
- <span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-o"></span><span id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-output"></span><span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-output"></span><span class="sig-name descname"><span class="pre">-o</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--output</span></span><span class="sig-prename descclassname"> <span class="pre">OUTPUT</span></span><a class="headerlink" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-o" title="Permalink to this definition">¶</a></dt>
- <dd><p>Redirect file output to OUTPUT</p>
- </dd></dl>
- <dl class="std option">
- <dt class="sig sig-object std" id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-v">
- <span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-v"></span><span id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-verbose"></span><span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-verbose"></span><span class="sig-name descname"><span class="pre">-v</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--verbose</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-v" title="Permalink to this definition">¶</a></dt>
- <dd><p>Enable verbose mode.</p>
- </dd></dl>
- <dl class="std option">
- <dt class="sig sig-object std" id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-converters">
- <span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-converters"></span><span class="sig-name descname"><span class="pre">--converters</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-converters" title="Permalink to this definition">¶</a></dt>
- <dd><p>Print a list of all supported converters and return converters.</p>
- </dd></dl>
- <dl class="std option">
- <dt class="sig sig-object std" id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-make">
- <span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-make"></span><span class="sig-name descname"><span class="pre">--make</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-make" title="Permalink to this definition">¶</a></dt>
- <dd><p>Walk <a class="reference internal" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-srcdir"><code class="xref std std-option docutils literal notranslate"><span class="pre">--srcdir</span></code></a> to run over all relevant files.</p>
- </dd></dl>
- <dl class="std option">
- <dt class="sig sig-object std" id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-srcdir">
- <span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-srcdir"></span><span class="sig-name descname"><span class="pre">--srcdir</span></span><span class="sig-prename descclassname"> <span class="pre">SRCDIR</span></span><a class="headerlink" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-srcdir" title="Permalink to this definition">¶</a></dt>
- <dd><p>The directory tree to walk in <a class="reference internal" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-make"><code class="xref std std-option docutils literal notranslate"><span class="pre">--make</span></code></a> mode.</p>
- </dd></dl>
- <dl class="std option">
- <dt class="sig sig-object std" id="cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-arg-FILE">
- <span id="cmdoption-tools-clinic-clinic-py-h-f-o-output-v-converters-make-srcdir-srcdir-file-arg-file"></span><span class="sig-name descname"><span class="pre">FILE</span></span><span class="sig-prename descclassname"> <span class="pre">...</span></span><a class="headerlink" href="#cmdoption-.-Tools-clinic-clinic.py-h-f-o-OUTPUT-v-converters-make-srcdir-SRCDIR-FILE-...-arg-FILE" title="Permalink to this definition">¶</a></dt>
- <dd><p>The list of files to process.</p>
- </dd></dl>
- </section>
- <section id="module-clinic">
- <span id="classes-for-extending-argument-clinic"></span><span id="clinic-classes"></span><h3>Classes for extending Argument Clinic<a class="headerlink" href="#module-clinic" title="Permalink to this headline">¶</a></h3>
- <dl class="py class">
- <dt class="sig sig-object py" id="clinic.CConverter">
- <em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">clinic.</span></span><span class="sig-name descname"><span class="pre">CConverter</span></span><a class="headerlink" href="#clinic.CConverter" title="Permalink to this definition">¶</a></dt>
- <dd><p>The base class for all converters.
- See <a class="reference internal" href="#clinic-howto-custom-converter"><span class="std std-ref">How to write a custom converter</span></a> for how to subclass this class.</p>
- <dl class="py attribute">
- <dt class="sig sig-object py" id="clinic.CConverter.type">
- <span class="sig-name descname"><span class="pre">type</span></span><a class="headerlink" href="#clinic.CConverter.type" title="Permalink to this definition">¶</a></dt>
- <dd><p>The C type to use for this variable.
- <code class="xref py py-attr docutils literal notranslate"><span class="pre">type</span></code> should be a Python string specifying the type,
- e.g. <code class="docutils literal notranslate"><span class="pre">'int'</span></code>.
- If this is a pointer type, the type string should end with <code class="docutils literal notranslate"><span class="pre">'</span> <span class="pre">*'</span></code>.</p>
- </dd></dl>
- <dl class="py attribute">
- <dt class="sig sig-object py" id="clinic.CConverter.default">
- <span class="sig-name descname"><span class="pre">default</span></span><a class="headerlink" href="#clinic.CConverter.default" title="Permalink to this definition">¶</a></dt>
- <dd><p>The Python default value for this parameter, as a Python value.
- Or the magic value <code class="docutils literal notranslate"><span class="pre">unspecified</span></code> if there is no default.</p>
- </dd></dl>
- <dl class="py attribute">
- <dt class="sig sig-object py" id="clinic.CConverter.py_default">
- <span class="sig-name descname"><span class="pre">py_default</span></span><a class="headerlink" href="#clinic.CConverter.py_default" title="Permalink to this definition">¶</a></dt>
- <dd><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">default</span></code> as it should appear in Python code,
- as a string.
- Or <code class="docutils literal notranslate"><span class="pre">None</span></code> if there is no default.</p>
- </dd></dl>
- <dl class="py attribute">
- <dt class="sig sig-object py" id="clinic.CConverter.c_default">
- <span class="sig-name descname"><span class="pre">c_default</span></span><a class="headerlink" href="#clinic.CConverter.c_default" title="Permalink to this definition">¶</a></dt>
- <dd><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">default</span></code> as it should appear in C code,
- as a string.
- Or <code class="docutils literal notranslate"><span class="pre">None</span></code> if there is no default.</p>
- </dd></dl>
- <dl class="py attribute">
- <dt class="sig sig-object py" id="clinic.CConverter.c_ignored_default">
- <span class="sig-name descname"><span class="pre">c_ignored_default</span></span><a class="headerlink" href="#clinic.CConverter.c_ignored_default" title="Permalink to this definition">¶</a></dt>
- <dd><p>The default value used to initialize the C variable when
- there is no default, but not specifying a default may
- result in an “uninitialized variable” warning. This can
- easily happen when using option groups—although
- properly written code will never actually use this value,
- the variable does get passed in to the impl, and the
- C compiler will complain about the “use” of the
- uninitialized value. This value should always be a
- non-empty string.</p>
- </dd></dl>
- <dl class="py attribute">
- <dt class="sig sig-object py" id="clinic.CConverter.converter">
- <span class="sig-name descname"><span class="pre">converter</span></span><a class="headerlink" href="#clinic.CConverter.converter" title="Permalink to this definition">¶</a></dt>
- <dd><p>The name of the C converter function, as a string.</p>
- </dd></dl>
- <dl class="py attribute">
- <dt class="sig sig-object py" id="clinic.CConverter.impl_by_reference">
- <span class="sig-name descname"><span class="pre">impl_by_reference</span></span><a class="headerlink" href="#clinic.CConverter.impl_by_reference" title="Permalink to this definition">¶</a></dt>
- <dd><p>A boolean value. If true,
- Argument Clinic will add a <code class="docutils literal notranslate"><span class="pre">&</span></code> in front of the name of
- the variable when passing it into the impl function.</p>
- </dd></dl>
- <dl class="py attribute">
- <dt class="sig sig-object py" id="clinic.CConverter.parse_by_reference">
- <span class="sig-name descname"><span class="pre">parse_by_reference</span></span><a class="headerlink" href="#clinic.CConverter.parse_by_reference" title="Permalink to this definition">¶</a></dt>
- <dd><p>A boolean value. If true,
- Argument Clinic will add a <code class="docutils literal notranslate"><span class="pre">&</span></code> in front of the name of
- the variable when passing it into <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a>.</p>
- </dd></dl>
- </dd></dl>
- </section>
- </section>
- <section id="tutorial">
- <span id="clinic-tutorial"></span><h2>Tutorial<a class="headerlink" href="#tutorial" title="Permalink to this headline">¶</a></h2>
- <p>The best way to get a sense of how Argument Clinic works is to
- convert a function to work with it. Here, then, are the bare
- minimum steps you’d need to follow to convert a function to
- work with Argument Clinic. Note that for code you plan to
- check in to CPython, you really should take the conversion farther,
- using some of the <a class="reference internal" href="#clinic-howtos"><span class="std std-ref">advanced concepts</span></a>
- you’ll see later on in the document,
- like <a class="reference internal" href="#clinic-howto-return-converters"><span class="std std-ref">How to use return converters</span></a>
- and <a class="reference internal" href="#clinic-howto-self-converter"><span class="std std-ref">How to use the “self converter”</span></a>.
- But we’ll keep it simple for this walkthrough so you can learn.</p>
- <p>First, make sure you’re working with a freshly updated checkout
- of the CPython trunk.</p>
- <p>Next, find a Python builtin that calls either <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a>
- or <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTupleAndKeywords" title="PyArg_ParseTupleAndKeywords"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code></a>, and hasn’t been converted
- to work with Argument Clinic yet.
- For this tutorial, we’ll be using
- <a class="reference internal" href="../library/pickle.html#pickle.Pickler.dump" title="pickle.Pickler.dump"><code class="xref py py-meth docutils literal notranslate"><span class="pre">_pickle.Pickler.dump</span></code></a>.</p>
- <p>If the call to the <code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_Parse*()</span></code> function uses any of the
- following format units…:</p>
- <blockquote>
- <div><div class="highlight-none notranslate"><div class="highlight"><pre><span></span>O&
- O!
- es
- es#
- et
- et#
- </pre></div>
- </div>
- </div></blockquote>
- <p>… or if it has multiple calls to <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a>,
- you should choose a different function.
- (See <a class="reference internal" href="#clinic-howto-advanced-converters"><span class="std std-ref">How to use advanced converters</span></a> for those scenarios.)</p>
- <p>Also, if the function has multiple calls to <code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code>
- or <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTupleAndKeywords" title="PyArg_ParseTupleAndKeywords"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code></a> where it supports different
- types for the same argument, or if the function uses something besides
- <code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_Parse*()</span></code> functions to parse its arguments, it probably
- isn’t suitable for conversion to Argument Clinic. Argument Clinic
- doesn’t support generic functions or polymorphic parameters.</p>
- <p>Next, add the following boilerplate above the function,
- creating our input block:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>Cut the docstring and paste it in between the <code class="docutils literal notranslate"><span class="pre">[clinic]</span></code> lines,
- removing all the junk that makes it a properly quoted C string.
- When you’re done you should have just the text, based at the left
- margin, with no line wider than 80 characters.
- Argument Clinic will preserve indents inside the docstring.</p>
- <p>If the old docstring had a first line that looked like a function
- signature, throw that line away; The docstring doesn’t need it anymore —
- when you use <a class="reference internal" href="../library/functions.html#help" title="help"><code class="xref py py-func docutils literal notranslate"><span class="pre">help()</span></code></a> on your builtin in the future,
- the first line will be built automatically based on the function’s signature.</p>
- <p>Example docstring summary line:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>If your docstring doesn’t have a “summary” line, Argument Clinic will
- complain, so let’s make sure it has one. The “summary” line should
- be a paragraph consisting of a single 80-column line
- at the beginning of the docstring.
- (See <span class="target" id="index-1"></span><a class="pep reference external" href="https://peps.python.org/pep-0257/"><strong>PEP 257</strong></a> regarding docstring conventions.)</p>
- <p>Our example docstring consists solely of a summary line, so the sample
- code doesn’t have to change for this step.</p>
- <p>Now, above the docstring, enter the name of the function, followed
- by a blank line. This should be the Python name of the function,
- and should be the full dotted path to the function —
- it should start with the name of the module,
- include any sub-modules, and if the function is a method on
- a class it should include the class name too.</p>
- <p>In our example, <code class="xref py py-mod docutils literal notranslate"><span class="pre">_pickle</span></code> is the module, <code class="xref py py-class docutils literal notranslate"><span class="pre">Pickler</span></code> is the class,
- and <code class="xref py py-meth docutils literal notranslate"><span class="pre">dump()</span></code> is the method, so the name becomes
- <code class="xref py py-meth docutils literal notranslate"><span class="pre">_pickle.Pickler.dump()</span></code>:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>If this is the first time that module or class has been used with Argument
- Clinic in this C file,
- you must declare the module and/or class. Proper Argument Clinic hygiene
- prefers declaring these in a separate block somewhere near the
- top of the C file, in the same way that include files and statics go at
- the top.
- In our sample code we’ll just show the two blocks next to each other.</p>
- <p>The name of the class and module should be the same as the one
- seen by Python. Check the name defined in the <a class="reference internal" href="../c-api/module.html#c.PyModuleDef" title="PyModuleDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyModuleDef</span></code></a>
- or <a class="reference internal" href="../c-api/type.html#c.PyTypeObject" title="PyTypeObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyTypeObject</span></code></a> as appropriate.</p>
- <p>When you declare a class, you must also specify two aspects of its type
- in C: the type declaration you’d use for a pointer to an instance of
- this class, and a pointer to the <code class="xref c c-type docutils literal notranslate"><span class="pre">PyTypeObject</span></code> for this class:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">module _pickle</span>
- <span class="cm">class _pickle.Pickler "PicklerObject *" "&Pickler_Type"</span>
- <span class="cm">[clinic start generated code]*/</span>
- <span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>Declare each of the parameters to the function. Each parameter
- should get its own line. All the parameter lines should be
- indented from the function name and the docstring.
- The general form of these parameter lines is as follows:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>name_of_parameter: converter
- </pre></div>
- </div>
- <p>If the parameter has a default value, add that after the
- converter:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>name_of_parameter: converter = default_value
- </pre></div>
- </div>
- <p>Argument Clinic’s support for “default values” is quite sophisticated;
- see <a class="reference internal" href="#clinic-howto-default-values"><span class="std std-ref">How to assign default values to parameter</span></a> for more information.</p>
- <p>Next, add a blank line below the parameters.</p>
- <p>What’s a “converter”?
- It establishes both the type of the variable used in C,
- and the method to convert the Python value into a C value at runtime.
- For now you’re going to use what’s called a “legacy converter” —
- a convenience syntax intended to make porting old code into Argument
- Clinic easier.</p>
- <p>For each parameter, copy the “format unit” for that
- parameter from the <a class="reference internal" href="../c-api/arg.html#c.PyArg_Parse" title="PyArg_Parse"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_Parse()</span></code></a> format argument and
- specify <em>that</em> as its converter, as a quoted string.
- The “format unit” is the formal name for the one-to-three
- character substring of the <em>format</em> parameter that tells
- the argument parsing function what the type of the variable
- is and how to convert it.
- For more on format units please see <a class="reference internal" href="../c-api/arg.html#arg-parsing"><span class="std std-ref">Parsing arguments and building values</span></a>.</p>
- <p>For multicharacter format units like <code class="docutils literal notranslate"><span class="pre">z#</span></code>,
- use the entire two-or-three character string.</p>
- <p>Sample:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">module _pickle</span>
- <span class="cm">class _pickle.Pickler "PicklerObject *" "&Pickler_Type"</span>
- <span class="cm">[clinic start generated code]*/</span>
- <span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm"> obj: 'O'</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>If your function has <code class="docutils literal notranslate"><span class="pre">|</span></code> in the format string,
- meaning some parameters have default values, you can ignore it.
- Argument Clinic infers which parameters are optional
- based on whether or not they have default values.</p>
- <p>If your function has <code class="docutils literal notranslate"><span class="pre">$</span></code> in the format string,
- meaning it takes keyword-only arguments,
- specify <code class="docutils literal notranslate"><span class="pre">*</span></code> on a line by itself before the first keyword-only argument,
- indented the same as the parameter lines.</p>
- <p><code class="xref py py-meth docutils literal notranslate"><span class="pre">_pickle.Pickler.dump()</span></code> has neither, so our sample is unchanged.</p>
- <p>Next, if the existing C function calls <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a>
- (as opposed to <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTupleAndKeywords" title="PyArg_ParseTupleAndKeywords"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code></a>), then all its
- arguments are positional-only.</p>
- <p>To mark parameters as positional-only in Argument Clinic,
- add a <code class="docutils literal notranslate"><span class="pre">/</span></code> on a line by itself after the last positional-only parameter,
- indented the same as the parameter lines.</p>
- <p>Sample:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">module _pickle</span>
- <span class="cm">class _pickle.Pickler "PicklerObject *" "&Pickler_Type"</span>
- <span class="cm">[clinic start generated code]*/</span>
- <span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm"> obj: 'O'</span>
- <span class="cm"> /</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>It can be helpful to write a per-parameter docstring for each parameter.
- Since per-parameter docstrings are optional,
- you can skip this step if you prefer.</p>
- <p>Nevertheless, here’s how to add a per-parameter docstring.
- The first line of the per-parameter docstring
- must be indented further than the parameter definition.
- The left margin of this first line establishes
- the left margin for the whole per-parameter docstring;
- all the text you write will be outdented by this amount.
- You can write as much text as you like, across multiple lines if you wish.</p>
- <p>Sample:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">module _pickle</span>
- <span class="cm">class _pickle.Pickler "PicklerObject *" "&Pickler_Type"</span>
- <span class="cm">[clinic start generated code]*/</span>
- <span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm"> obj: 'O'</span>
- <span class="cm"> The object to be pickled.</span>
- <span class="cm"> /</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>Save and close the file, then run <code class="docutils literal notranslate"><span class="pre">Tools/clinic/clinic.py</span></code> on it.
- With luck everything worked—your block now has output,
- and a <code class="file docutils literal notranslate"><span class="pre">.c.h</span></code> file has been generated!
- Reload the file in your text editor to see the generated code:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm"> obj: 'O'</span>
- <span class="cm"> The object to be pickled.</span>
- <span class="cm"> /</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- <span class="k">static</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
- <span class="n">_pickle_Pickler_dump</span><span class="p">(</span><span class="n">PicklerObject</span><span class="w"> </span><span class="o">*</span><span class="n">self</span><span class="p">,</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">)</span>
- <span class="cm">/*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/</span>
- </pre></div>
- </div>
- <p>Obviously, if Argument Clinic didn’t produce any output,
- it’s because it found an error in your input.
- Keep fixing your errors and retrying until Argument Clinic processes your file
- without complaint.</p>
- <p>For readability, most of the glue code has been generated to a <code class="file docutils literal notranslate"><span class="pre">.c.h</span></code>
- file. You’ll need to include that in your original <code class="file docutils literal notranslate"><span class="pre">.c</span></code> file,
- typically right after the clinic module block:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">"clinic/_pickle.c.h"</span>
- </pre></div>
- </div>
- <p>Double-check that the argument-parsing code Argument Clinic generated
- looks basically the same as the existing code.</p>
- <p>First, ensure both places use the same argument-parsing function.
- The existing code must call either
- <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a> or <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTupleAndKeywords" title="PyArg_ParseTupleAndKeywords"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code></a>;
- ensure that the code generated by Argument Clinic calls the
- <em>exact</em> same function.</p>
- <p>Second, the format string passed in to <code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code> or
- <code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code> should be <em>exactly</em> the same
- as the hand-written one in the existing function,
- up to the colon or semi-colon.</p>
- <p>Argument Clinic always generates its format strings
- with a <code class="docutils literal notranslate"><span class="pre">:</span></code> followed by the name of the function.
- If the existing code’s format string ends with <code class="docutils literal notranslate"><span class="pre">;</span></code>,
- to provide usage help, this change is harmless — don’t worry about it.</p>
- <p>Third, for parameters whose format units require two arguments,
- like a length variable, an encoding string, or a pointer
- to a conversion function, ensure that the second argument is
- <em>exactly</em> the same between the two invocations.</p>
- <p>Fourth, inside the output portion of the block,
- you’ll find a preprocessor macro defining the appropriate static
- <a class="reference internal" href="../c-api/structures.html#c.PyMethodDef" title="PyMethodDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code></a> structure for this builtin:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define __PICKLE_PICKLER_DUMP_METHODDEF \</span>
- <span class="cp">{"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__},</span>
- </pre></div>
- </div>
- <p>This static structure should be <em>exactly</em> the same as the existing static
- <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code> structure for this builtin.</p>
- <p>If any of these items differ in <em>any way</em>,
- adjust your Argument Clinic function specification and rerun
- <code class="docutils literal notranslate"><span class="pre">Tools/clinic/clinic.py</span></code> until they <em>are</em> the same.</p>
- <p>Notice that the last line of its output is the declaration
- of your “impl” function. This is where the builtin’s implementation goes.
- Delete the existing prototype of the function you’re modifying, but leave
- the opening curly brace. Now delete its argument parsing code and the
- declarations of all the variables it dumps the arguments into.
- Notice how the Python arguments are now arguments to this impl function;
- if the implementation used different names for these variables, fix it.</p>
- <p>Let’s reiterate, just because it’s kind of weird.
- Your code should now look like this:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="n">return_type</span>
- <span class="nf">your_function_impl</span><span class="p">(...)</span>
- <span class="cm">/*[clinic end generated code: input=..., output=...]*/</span>
- <span class="p">{</span>
- <span class="p">...</span>
- </pre></div>
- </div>
- <p>Argument Clinic generated the checksum line and the function prototype just
- above it. You should write the opening and closing curly braces for the
- function, and the implementation inside.</p>
- <p>Sample:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">module _pickle</span>
- <span class="cm">class _pickle.Pickler "PicklerObject *" "&Pickler_Type"</span>
- <span class="cm">[clinic start generated code]*/</span>
- <span class="cm">/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/</span>
- <span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm"> obj: 'O'</span>
- <span class="cm"> The object to be pickled.</span>
- <span class="cm"> /</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- <span class="n">PyDoc_STRVAR</span><span class="p">(</span><span class="n">__pickle_Pickler_dump__doc__</span><span class="p">,</span>
- <span class="s">"Write a pickled representation of obj to the open file.</span><span class="se">\n</span><span class="s">"</span>
- <span class="s">"</span><span class="se">\n</span><span class="s">"</span>
- <span class="p">...</span>
- <span class="k">static</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
- <span class="n">_pickle_Pickler_dump_impl</span><span class="p">(</span><span class="n">PicklerObject</span><span class="w"> </span><span class="o">*</span><span class="n">self</span><span class="p">,</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">)</span>
- <span class="cm">/*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/</span>
- <span class="p">{</span>
- <span class="w"> </span><span class="cm">/* Check whether the Pickler was initialized correctly (issue3664).</span>
- <span class="cm"> Developers often forget to call __init__() in their subclasses, which</span>
- <span class="cm"> would trigger a segfault without this check. */</span>
- <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">write</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="n">PyErr_Format</span><span class="p">(</span><span class="n">PicklingError</span><span class="p">,</span>
- <span class="w"> </span><span class="s">"Pickler.__init__() was not called by %s.__init__()"</span><span class="p">,</span>
- <span class="w"> </span><span class="n">Py_TYPE</span><span class="p">(</span><span class="n">self</span><span class="p">)</span><span class="o">-></span><span class="n">tp_name</span><span class="p">);</span>
- <span class="w"> </span><span class="k">return</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="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">_Pickler_ClearBuffer</span><span class="p">(</span><span class="n">self</span><span class="p">)</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
- <span class="w"> </span><span class="k">return</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>
- </pre></div>
- </div>
- <p>Remember the macro with the <a class="reference internal" href="../c-api/structures.html#c.PyMethodDef" title="PyMethodDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code></a> structure for this function?
- Find the existing <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code> structure for this
- function and replace it with a reference to the macro. If the builtin
- is at module scope, this will probably be very near the end of the file;
- if the builtin is a class method, this will probably be below but relatively
- near to the implementation.</p>
- <p>Note that the body of the macro contains a trailing comma; when you
- replace the existing static <code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code> structure with the macro,
- <em>don’t</em> add a comma to the end.</p>
- <p>Sample:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyMethodDef</span><span class="w"> </span><span class="n">Pickler_methods</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
- <span class="w"> </span><span class="n">__PICKLE_PICKLER_DUMP_METHODDEF</span>
- <span class="w"> </span><span class="n">__PICKLE_PICKLER_CLEAR_MEMO_METHODDEF</span>
- <span class="w"> </span><span class="p">{</span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">}</span><span class="w"> </span><span class="cm">/* sentinel */</span>
- <span class="p">};</span>
- </pre></div>
- </div>
- <p>Argument Clinic may generate new instances of <code class="docutils literal notranslate"><span class="pre">_Py_ID</span></code>. For example:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="o">&</span><span class="n">_Py_ID</span><span class="p">(</span><span class="n">new_unique_py_id</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>If it does, you’ll have to run <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">regen-global-objects</span></code>
- to regenerate the list of precompiled identifiers at this point.</p>
- <p>Finally, compile, then run the relevant portions of the regression-test suite.
- This change should not introduce any new compile-time warnings or errors,
- and there should be no externally visible change to Python’s behavior,
- except for one difference: <a class="reference internal" href="../library/inspect.html#inspect.signature" title="inspect.signature"><code class="xref py py-func docutils literal notranslate"><span class="pre">inspect.signature()</span></code></a> run on your function
- should now provide a valid signature!</p>
- <p>Congratulations, you’ve ported your first function to work with Argument Clinic!</p>
- </section>
- <section id="how-to-guides">
- <span id="clinic-howtos"></span><h2>How-to guides<a class="headerlink" href="#how-to-guides" title="Permalink to this headline">¶</a></h2>
- <section id="how-to-rename-c-functions-and-variables-generated-by-argument-clinic">
- <h3>How to rename C functions and variables generated by Argument Clinic<a class="headerlink" href="#how-to-rename-c-functions-and-variables-generated-by-argument-clinic" title="Permalink to this headline">¶</a></h3>
- <p>Argument Clinic automatically names the functions it generates for you.
- Occasionally this may cause a problem, if the generated name collides with
- the name of an existing C function. There’s an easy solution: override the names
- used for the C functions. Just add the keyword <code class="docutils literal notranslate"><span class="pre">"as"</span></code>
- to your function declaration line, followed by the function name you wish to use.
- Argument Clinic will use that function name for the base (generated) function,
- then add <code class="docutils literal notranslate"><span class="pre">"_impl"</span></code> to the end and use that for the name of the impl function.</p>
- <p>For example, if we wanted to rename the C function names generated for
- <a class="reference internal" href="../library/pickle.html#pickle.Pickler.dump" title="pickle.Pickler.dump"><code class="xref py py-meth docutils literal notranslate"><span class="pre">pickle.Pickler.dump()</span></code></a>, it’d look like this:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">pickle.Pickler.dump as pickler_dumper</span>
- <span class="cm">...</span>
- </pre></div>
- </div>
- <p>The base function would now be named <code class="xref c c-func docutils literal notranslate"><span class="pre">pickler_dumper()</span></code>,
- and the impl function would now be named <code class="xref c c-func docutils literal notranslate"><span class="pre">pickler_dumper_impl()</span></code>.</p>
- <p>Similarly, you may have a problem where you want to give a parameter
- a specific Python name, but that name may be inconvenient in C. Argument
- Clinic allows you to give a parameter different names in Python and in C,
- using the same <code class="docutils literal notranslate"><span class="pre">"as"</span></code> syntax:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">pickle.Pickler.dump</span>
- <span class="cm"> obj: object</span>
- <span class="cm"> file as file_obj: object</span>
- <span class="cm"> protocol: object = NULL</span>
- <span class="cm"> *</span>
- <span class="cm"> fix_imports: bool = True</span>
- </pre></div>
- </div>
- <p>Here, the name used in Python (in the signature and the <code class="docutils literal notranslate"><span class="pre">keywords</span></code>
- array) would be <em>file</em>, but the C variable would be named <code class="docutils literal notranslate"><span class="pre">file_obj</span></code>.</p>
- <p>You can use this to rename the <em>self</em> parameter too!</p>
- </section>
- <section id="how-to-convert-functions-using-pyarg-unpacktuple">
- <h3>How to convert functions using <code class="docutils literal notranslate"><span class="pre">PyArg_UnpackTuple</span></code><a class="headerlink" href="#how-to-convert-functions-using-pyarg-unpacktuple" title="Permalink to this headline">¶</a></h3>
- <p>To convert a function parsing its arguments with <a class="reference internal" href="../c-api/arg.html#c.PyArg_UnpackTuple" title="PyArg_UnpackTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_UnpackTuple()</span></code></a>,
- simply write out all the arguments, specifying each as an <code class="docutils literal notranslate"><span class="pre">object</span></code>. You
- may specify the <em>type</em> argument to cast the type as appropriate. All
- arguments should be marked positional-only (add a <code class="docutils literal notranslate"><span class="pre">/</span></code> on a line by itself
- after the last argument).</p>
- <p>Currently the generated code will use <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a>, but this
- will change soon.</p>
- </section>
- <section id="how-to-use-optional-groups">
- <h3>How to use optional groups<a class="headerlink" href="#how-to-use-optional-groups" title="Permalink to this headline">¶</a></h3>
- <p>Some legacy functions have a tricky approach to parsing their arguments:
- they count the number of positional arguments, then use a <code class="docutils literal notranslate"><span class="pre">switch</span></code> statement
- to call one of several different <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a> calls depending on
- how many positional arguments there are. (These functions cannot accept
- keyword-only arguments.) This approach was used to simulate optional
- arguments back before <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTupleAndKeywords" title="PyArg_ParseTupleAndKeywords"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code></a> was created.</p>
- <p>While functions using this approach can often be converted to
- use <code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code>, optional arguments, and default values,
- it’s not always possible. Some of these legacy functions have
- behaviors <code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code> doesn’t directly support.
- The most obvious example is the builtin function <a class="reference internal" href="../library/stdtypes.html#range" title="range"><code class="xref py py-func docutils literal notranslate"><span class="pre">range()</span></code></a>, which has
- an optional argument on the <em>left</em> side of its required argument!
- Another example is <a class="reference internal" href="../library/curses.html#curses.window.addch" title="curses.window.addch"><code class="xref py py-meth docutils literal notranslate"><span class="pre">curses.window.addch()</span></code></a>, which has a group of two
- arguments that must always be specified together. (The arguments are
- called <em>x</em> and <em>y</em>; if you call the function passing in <em>x</em>,
- you must also pass in <em>y</em> — and if you don’t pass in <em>x</em> you may not
- pass in <em>y</em> either.)</p>
- <p>In any case, the goal of Argument Clinic is to support argument parsing
- for all existing CPython builtins without changing their semantics.
- Therefore Argument Clinic supports
- this alternate approach to parsing, using what are called <em>optional groups</em>.
- Optional groups are groups of arguments that must all be passed in together.
- They can be to the left or the right of the required arguments. They
- can <em>only</em> be used with positional-only parameters.</p>
- <div class="admonition note">
- <p class="admonition-title">Note</p>
- <p>Optional groups are <em>only</em> intended for use when converting
- functions that make multiple calls to <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a>!
- Functions that use <em>any</em> other approach for parsing arguments
- should <em>almost never</em> be converted to Argument Clinic using
- optional groups. Functions using optional groups currently
- cannot have accurate signatures in Python, because Python just
- doesn’t understand the concept. Please avoid using optional
- groups wherever possible.</p>
- </div>
- <p>To specify an optional group, add a <code class="docutils literal notranslate"><span class="pre">[</span></code> on a line by itself before
- the parameters you wish to group together, and a <code class="docutils literal notranslate"><span class="pre">]</span></code> on a line by itself
- after these parameters. As an example, here’s how <a class="reference internal" href="../library/curses.html#curses.window.addch" title="curses.window.addch"><code class="xref py py-meth docutils literal notranslate"><span class="pre">curses.window.addch()</span></code></a>
- uses optional groups to make the first two parameters and the last
- parameter optional:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">curses.window.addch</span>
- <span class="cm"> [</span>
- <span class="cm"> x: int</span>
- <span class="cm"> X-coordinate.</span>
- <span class="cm"> y: int</span>
- <span class="cm"> Y-coordinate.</span>
- <span class="cm"> ]</span>
- <span class="cm"> ch: object</span>
- <span class="cm"> Character to add.</span>
- <span class="cm"> [</span>
- <span class="cm"> attr: long</span>
- <span class="cm"> Attributes for the character.</span>
- <span class="cm"> ]</span>
- <span class="cm"> /</span>
- <span class="cm">...</span>
- </pre></div>
- </div>
- <p>Notes:</p>
- <ul class="simple">
- <li><p>For every optional group, one additional parameter will be passed into the
- impl function representing the group. The parameter will be an int named
- <code class="docutils literal notranslate"><span class="pre">group_{direction}_{number}</span></code>,
- where <code class="docutils literal notranslate"><span class="pre">{direction}</span></code> is either <code class="docutils literal notranslate"><span class="pre">right</span></code> or <code class="docutils literal notranslate"><span class="pre">left</span></code> depending on whether the group
- is before or after the required parameters, and <code class="docutils literal notranslate"><span class="pre">{number}</span></code> is a monotonically
- increasing number (starting at 1) indicating how far away the group is from
- the required parameters. When the impl is called, this parameter will be set
- to zero if this group was unused, and set to non-zero if this group was used.
- (By used or unused, I mean whether or not the parameters received arguments
- in this invocation.)</p></li>
- <li><p>If there are no required arguments, the optional groups will behave
- as if they’re to the right of the required arguments.</p></li>
- <li><p>In the case of ambiguity, the argument parsing code
- favors parameters on the left (before the required parameters).</p></li>
- <li><p>Optional groups can only contain positional-only parameters.</p></li>
- <li><p>Optional groups are <em>only</em> intended for legacy code. Please do not
- use optional groups for new code.</p></li>
- </ul>
- </section>
- <section id="how-to-use-real-argument-clinic-converters-instead-of-legacy-converters">
- <h3>How to use real Argument Clinic converters, instead of “legacy converters”<a class="headerlink" href="#how-to-use-real-argument-clinic-converters-instead-of-legacy-converters" title="Permalink to this headline">¶</a></h3>
- <p>To save time, and to minimize how much you need to learn
- to achieve your first port to Argument Clinic, the walkthrough above tells
- you to use “legacy converters”. “Legacy converters” are a convenience,
- designed explicitly to make porting existing code to Argument Clinic
- easier. And to be clear, their use is acceptable when porting code for
- Python 3.4.</p>
- <p>However, in the long term we probably want all our blocks to
- use Argument Clinic’s real syntax for converters. Why? A couple
- reasons:</p>
- <ul class="simple">
- <li><p>The proper converters are far easier to read and clearer in their intent.</p></li>
- <li><p>There are some format units that are unsupported as “legacy converters”,
- because they require arguments, and the legacy converter syntax doesn’t
- support specifying arguments.</p></li>
- <li><p>In the future we may have a new argument parsing library that isn’t
- restricted to what <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a> supports; this flexibility
- won’t be available to parameters using legacy converters.</p></li>
- </ul>
- <p>Therefore, if you don’t mind a little extra effort, please use the normal
- converters instead of legacy converters.</p>
- <p>In a nutshell, the syntax for Argument Clinic (non-legacy) converters
- looks like a Python function call. However, if there are no explicit
- arguments to the function (all functions take their default values),
- you may omit the parentheses. Thus <code class="docutils literal notranslate"><span class="pre">bool</span></code> and <code class="docutils literal notranslate"><span class="pre">bool()</span></code> are exactly
- the same converters.</p>
- <p>All arguments to Argument Clinic converters are keyword-only.
- All Argument Clinic converters accept the following arguments:</p>
- <blockquote>
- <div><dl class="simple">
- <dt><em>c_default</em></dt><dd><p>The default value for this parameter when defined in C.
- Specifically, this will be the initializer for the variable declared
- in the “parse function”. See <a class="reference internal" href="#default-values"><span class="std std-ref">the section on default values</span></a>
- for how to use this.
- Specified as a string.</p>
- </dd>
- <dt><em>annotation</em></dt><dd><p>The annotation value for this parameter. Not currently supported,
- because <span class="target" id="index-2"></span><a class="pep reference external" href="https://peps.python.org/pep-0008/"><strong>PEP 8</strong></a> mandates that the Python library may not use
- annotations.</p>
- </dd>
- <dt><em>unused</em></dt><dd><p>Wrap the argument with <a class="reference internal" href="../c-api/intro.html#c.Py_UNUSED" title="Py_UNUSED"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_UNUSED</span></code></a> in the impl function signature.</p>
- </dd>
- </dl>
- </div></blockquote>
- <p>In addition, some converters accept additional arguments. Here is a list
- of these arguments, along with their meanings:</p>
- <blockquote>
- <div><dl>
- <dt><em>accept</em></dt><dd><p>A set of Python types (and possibly pseudo-types);
- this restricts the allowable Python argument to values of these types.
- (This is not a general-purpose facility; as a rule it only supports
- specific lists of types as shown in the legacy converter table.)</p>
- <p>To accept <code class="docutils literal notranslate"><span class="pre">None</span></code>, add <code class="docutils literal notranslate"><span class="pre">NoneType</span></code> to this set.</p>
- </dd>
- <dt><em>bitwise</em></dt><dd><p>Only supported for unsigned integers. The native integer value of this
- Python argument will be written to the parameter without any range checking,
- even for negative values.</p>
- </dd>
- <dt><em>converter</em></dt><dd><p>Only supported by the <code class="docutils literal notranslate"><span class="pre">object</span></code> converter. Specifies the name of a
- <a class="reference internal" href="../c-api/arg.html#o-ampersand"><span class="std std-ref">C “converter function”</span></a>
- to use to convert this object to a native type.</p>
- </dd>
- <dt><em>encoding</em></dt><dd><p>Only supported for strings. Specifies the encoding to use when converting
- this string from a Python str (Unicode) value into a C <code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">*</span></code> value.</p>
- </dd>
- <dt><em>subclass_of</em></dt><dd><p>Only supported for the <code class="docutils literal notranslate"><span class="pre">object</span></code> converter. Requires that the Python
- value be a subclass of a Python type, as expressed in C.</p>
- </dd>
- <dt><em>type</em></dt><dd><p>Only supported for the <code class="docutils literal notranslate"><span class="pre">object</span></code> and <code class="docutils literal notranslate"><span class="pre">self</span></code> converters. Specifies
- the C type that will be used to declare the variable. Default value is
- <code class="docutils literal notranslate"><span class="pre">"PyObject</span> <span class="pre">*"</span></code>.</p>
- </dd>
- <dt><em>zeroes</em></dt><dd><p>Only supported for strings. If true, embedded NUL bytes (<code class="docutils literal notranslate"><span class="pre">'\\0'</span></code>) are
- permitted inside the value. The length of the string will be passed in
- to the impl function, just after the string parameter, as a parameter named
- <code class="docutils literal notranslate"><span class="pre"><parameter_name>_length</span></code>.</p>
- </dd>
- </dl>
- </div></blockquote>
- <p>Please note, not every possible combination of arguments will work.
- Usually these arguments are implemented by specific <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a>
- <em>format units</em>, with specific behavior. For example, currently you cannot
- call <code class="docutils literal notranslate"><span class="pre">unsigned_short</span></code> without also specifying <code class="docutils literal notranslate"><span class="pre">bitwise=True</span></code>.
- Although it’s perfectly reasonable to think this would work, these semantics don’t
- map to any existing format unit. So Argument Clinic doesn’t support it. (Or, at
- least, not yet.)</p>
- <p>Below is a table showing the mapping of legacy converters into real
- Argument Clinic converters. On the left is the legacy converter,
- on the right is the text you’d replace it with.</p>
- <table class="docutils align-default">
- <colgroup>
- <col style="width: 10%" />
- <col style="width: 90%" />
- </colgroup>
- <tbody>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'B'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">unsigned_char(bitwise=True)</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'b'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">unsigned_char</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'c'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">char</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'C'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">int(accept={str})</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'d'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">double</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'D'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">Py_complex</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'es'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(encoding='name_of_encoding')</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'es#'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(encoding='name_of_encoding',</span> <span class="pre">zeroes=True)</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'et'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(encoding='name_of_encoding',</span> <span class="pre">accept={bytes,</span> <span class="pre">bytearray,</span> <span class="pre">str})</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'et#'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(encoding='name_of_encoding',</span> <span class="pre">accept={bytes,</span> <span class="pre">bytearray,</span> <span class="pre">str},</span> <span class="pre">zeroes=True)</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'f'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">float</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'h'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">short</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'H'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">unsigned_short(bitwise=True)</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'i'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">int</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'I'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">unsigned_int(bitwise=True)</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'k'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">unsigned_long(bitwise=True)</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'K'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">unsigned_long_long(bitwise=True)</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'l'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">long</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'L'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">long</span> <span class="pre">long</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'n'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'O'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">object</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'O!'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">object(subclass_of='&PySomething_Type')</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'O&'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">object(converter='name_of_c_function')</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'p'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">bool</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'S'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">PyBytesObject</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'s'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'s#'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(zeroes=True)</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'s*'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">Py_buffer(accept={buffer,</span> <span class="pre">str})</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'U'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">unicode</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'u'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">wchar_t</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'u#'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">wchar_t(zeroes=True)</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'w*'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">Py_buffer(accept={rwbuffer})</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'Y'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">PyByteArrayObject</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'y'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(accept={bytes})</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'y#'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(accept={robuffer},</span> <span class="pre">zeroes=True)</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'y*'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">Py_buffer</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'Z'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">wchar_t(accept={str,</span> <span class="pre">NoneType})</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'Z#'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">wchar_t(accept={str,</span> <span class="pre">NoneType},</span> <span class="pre">zeroes=True)</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'z'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(accept={str,</span> <span class="pre">NoneType})</span></code></p></td>
- </tr>
- <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'z#'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">str(accept={str,</span> <span class="pre">NoneType},</span> <span class="pre">zeroes=True)</span></code></p></td>
- </tr>
- <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'z*'</span></code></p></td>
- <td><p><code class="docutils literal notranslate"><span class="pre">Py_buffer(accept={buffer,</span> <span class="pre">str,</span> <span class="pre">NoneType})</span></code></p></td>
- </tr>
- </tbody>
- </table>
- <p>As an example, here’s our sample <code class="docutils literal notranslate"><span class="pre">pickle.Pickler.dump</span></code> using the proper
- converter:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">pickle.Pickler.dump</span>
- <span class="cm"> obj: object</span>
- <span class="cm"> The object to be pickled.</span>
- <span class="cm"> /</span>
- <span class="cm">Write a pickled representation of obj to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>One advantage of real converters is that they’re more flexible than legacy
- converters. For example, the <code class="docutils literal notranslate"><span class="pre">unsigned_int</span></code> converter (and all the
- <code class="docutils literal notranslate"><span class="pre">unsigned_</span></code> converters) can be specified without <code class="docutils literal notranslate"><span class="pre">bitwise=True</span></code>. Their
- default behavior performs range checking on the value, and they won’t accept
- negative numbers. You just can’t do that with a legacy converter!</p>
- <p>Argument Clinic will show you all the converters it has
- available. For each converter it’ll show you all the parameters
- it accepts, along with the default value for each parameter.
- Just run <code class="docutils literal notranslate"><span class="pre">Tools/clinic/clinic.py</span> <span class="pre">--converters</span></code> to see the full list.</p>
- </section>
- <section id="how-to-use-the-py-buffer-converter">
- <h3>How to use the <code class="docutils literal notranslate"><span class="pre">Py_buffer</span></code> converter<a class="headerlink" href="#how-to-use-the-py-buffer-converter" title="Permalink to this headline">¶</a></h3>
- <p>When using the <code class="docutils literal notranslate"><span class="pre">Py_buffer</span></code> converter
- (or the <code class="docutils literal notranslate"><span class="pre">'s*'</span></code>, <code class="docutils literal notranslate"><span class="pre">'w*'</span></code>, <code class="docutils literal notranslate"><span class="pre">'*y'</span></code>, or <code class="docutils literal notranslate"><span class="pre">'z*'</span></code> legacy converters),
- you <em>must</em> not call <a class="reference internal" href="../c-api/buffer.html#c.PyBuffer_Release" title="PyBuffer_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBuffer_Release()</span></code></a> on the provided buffer.
- Argument Clinic generates code that does it for you (in the parsing function).</p>
- </section>
- <section id="how-to-use-advanced-converters">
- <span id="clinic-howto-advanced-converters"></span><h3>How to use advanced converters<a class="headerlink" href="#how-to-use-advanced-converters" title="Permalink to this headline">¶</a></h3>
- <p>Remember those format units you skipped for your first
- time because they were advanced? Here’s how to handle those too.</p>
- <p>The trick is, all those format units take arguments—either
- conversion functions, or types, or strings specifying an encoding.
- (But “legacy converters” don’t support arguments. That’s why we
- skipped them for your first function.) The argument you specified
- to the format unit is now an argument to the converter; this
- argument is either <em>converter</em> (for <code class="docutils literal notranslate"><span class="pre">O&</span></code>), <em>subclass_of</em> (for <code class="docutils literal notranslate"><span class="pre">O!</span></code>),
- or <em>encoding</em> (for all the format units that start with <code class="docutils literal notranslate"><span class="pre">e</span></code>).</p>
- <p>When using <em>subclass_of</em>, you may also want to use the other
- custom argument for <code class="docutils literal notranslate"><span class="pre">object()</span></code>: <em>type</em>, which lets you set the type
- actually used for the parameter. For example, if you want to ensure
- that the object is a subclass of <a class="reference internal" href="../c-api/unicode.html#c.PyUnicode_Type" title="PyUnicode_Type"><code class="xref c c-var docutils literal notranslate"><span class="pre">PyUnicode_Type</span></code></a>, you probably want
- to use the converter <code class="docutils literal notranslate"><span class="pre">object(type='PyUnicodeObject</span> <span class="pre">*',</span> <span class="pre">subclass_of='&PyUnicode_Type')</span></code>.</p>
- <p>One possible problem with using Argument Clinic: it takes away some possible
- flexibility for the format units starting with <code class="docutils literal notranslate"><span class="pre">e</span></code>. When writing a
- <code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_Parse*()</span></code> call by hand, you could theoretically decide at runtime what
- encoding string to pass to that call. But now this string must
- be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate;
- it made supporting this format unit much easier, and may allow for future optimizations.
- This restriction doesn’t seem unreasonable; CPython itself always passes in static
- hard-coded encoding strings for parameters whose format units start with <code class="docutils literal notranslate"><span class="pre">e</span></code>.</p>
- </section>
- <section id="how-to-assign-default-values-to-parameter">
- <span id="default-values"></span><span id="clinic-howto-default-values"></span><h3>How to assign default values to parameter<a class="headerlink" href="#how-to-assign-default-values-to-parameter" title="Permalink to this headline">¶</a></h3>
- <p>Default values for parameters can be any of a number of values.
- At their simplest, they can be string, int, or float literals:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>foo: str = "abc"
- bar: int = 123
- bat: float = 45.6
- </pre></div>
- </div>
- <p>They can also use any of Python’s built-in constants:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>yep: bool = True
- nope: bool = False
- nada: object = None
- </pre></div>
- </div>
- <p>There’s also special support for a default value of <code class="docutils literal notranslate"><span class="pre">NULL</span></code>, and
- for simple expressions, documented in the following sections.</p>
- <section id="the-null-default-value">
- <h4>The <code class="docutils literal notranslate"><span class="pre">NULL</span></code> default value<a class="headerlink" href="#the-null-default-value" title="Permalink to this headline">¶</a></h4>
- <p>For string and object parameters, you can set them to <code class="docutils literal notranslate"><span class="pre">None</span></code> to indicate
- that there’s no default. However, that means the C variable will be
- initialized to <code class="docutils literal notranslate"><span class="pre">Py_None</span></code>. For convenience’s sakes, there’s a special
- value called <code class="docutils literal notranslate"><span class="pre">NULL</span></code> for just this reason: from Python’s perspective it
- behaves like a default value of <code class="docutils literal notranslate"><span class="pre">None</span></code>, but the C variable is initialized
- with <code class="docutils literal notranslate"><span class="pre">NULL</span></code>.</p>
- </section>
- <section id="symbolic-default-values">
- <h4>Symbolic default values<a class="headerlink" href="#symbolic-default-values" title="Permalink to this headline">¶</a></h4>
- <p>The default value you provide for a parameter can’t be any arbitrary
- expression. Currently the following are explicitly supported:</p>
- <ul class="simple">
- <li><p>Numeric constants (integer and float)</p></li>
- <li><p>String constants</p></li>
- <li><p><code class="docutils literal notranslate"><span class="pre">True</span></code>, <code class="docutils literal notranslate"><span class="pre">False</span></code>, and <code class="docutils literal notranslate"><span class="pre">None</span></code></p></li>
- <li><p>Simple symbolic constants like <a class="reference internal" href="../library/sys.html#sys.maxsize" title="sys.maxsize"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.maxsize</span></code></a>, which must
- start with the name of the module</p></li>
- </ul>
- <p>(In the future, this may need to get even more elaborate,
- to allow full expressions like <code class="docutils literal notranslate"><span class="pre">CONSTANT</span> <span class="pre">-</span> <span class="pre">1</span></code>.)</p>
- </section>
- <section id="expressions-as-default-values">
- <h4>Expressions as default values<a class="headerlink" href="#expressions-as-default-values" title="Permalink to this headline">¶</a></h4>
- <p>The default value for a parameter can be more than just a literal value.
- It can be an entire expression, using math operators and looking up attributes
- on objects. However, this support isn’t exactly simple, because of some
- non-obvious semantics.</p>
- <p>Consider the following example:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>foo: Py_ssize_t = sys.maxsize - 1
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/sys.html#sys.maxsize" title="sys.maxsize"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.maxsize</span></code></a> can have different values on different platforms. Therefore
- Argument Clinic can’t simply evaluate that expression locally and hard-code it
- in C. So it stores the default in such a way that it will get evaluated at
- runtime, when the user asks for the function’s signature.</p>
- <p>What namespace is available when the expression is evaluated? It’s evaluated
- in the context of the module the builtin came from. So, if your module has an
- attribute called <code class="xref py py-attr docutils literal notranslate"><span class="pre">max_widgets</span></code>, you may simply use it:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>foo: Py_ssize_t = max_widgets
- </pre></div>
- </div>
- <p>If the symbol isn’t found in the current module, it fails over to looking in
- <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a>. That’s how it can find <a class="reference internal" href="../library/sys.html#sys.maxsize" title="sys.maxsize"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.maxsize</span></code></a> for example.
- (Since you don’t know in advance what modules the user will load into their interpreter,
- it’s best to restrict yourself to modules that are preloaded by Python itself.)</p>
- <p>Evaluating default values only at runtime means Argument Clinic can’t compute
- the correct equivalent C default value. So you need to tell it explicitly.
- When you use an expression, you must also specify the equivalent expression
- in C, using the <em>c_default</em> parameter to the converter:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1
- </pre></div>
- </div>
- <p>Another complication: Argument Clinic can’t know in advance whether or not the
- expression you supply is valid. It parses it to make sure it looks legal, but
- it can’t <em>actually</em> know. You must be very careful when using expressions to
- specify values that are guaranteed to be valid at runtime!</p>
- <p>Finally, because expressions must be representable as static C values, there
- are many restrictions on legal expressions. Here’s a list of Python features
- you’re not permitted to use:</p>
- <ul class="simple">
- <li><p>Function calls.</p></li>
- <li><p>Inline if statements (<code class="docutils literal notranslate"><span class="pre">3</span> <span class="pre">if</span> <span class="pre">foo</span> <span class="pre">else</span> <span class="pre">5</span></code>).</p></li>
- <li><p>Automatic sequence unpacking (<code class="docutils literal notranslate"><span class="pre">*[1,</span> <span class="pre">2,</span> <span class="pre">3]</span></code>).</p></li>
- <li><p>List/set/dict comprehensions and generator expressions.</p></li>
- <li><p>Tuple/list/set/dict literals.</p></li>
- </ul>
- </section>
- </section>
- <section id="how-to-use-return-converters">
- <span id="clinic-howto-return-converters"></span><h3>How to use return converters<a class="headerlink" href="#how-to-use-return-converters" title="Permalink to this headline">¶</a></h3>
- <p>By default, the impl function Argument Clinic generates for you returns
- <a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">*</span></code></a>.
- But your C function often computes some C type,
- then converts it into the <code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">*</span></code>
- at the last moment. Argument Clinic handles converting your inputs from Python types
- into native C types—why not have it convert your return value from a native C type
- into a Python type too?</p>
- <p>That’s what a “return converter” does. It changes your impl function to return
- some C type, then adds code to the generated (non-impl) function to handle converting
- that value into the appropriate <code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">*</span></code>.</p>
- <p>The syntax for return converters is similar to that of parameter converters.
- You specify the return converter like it was a return annotation on the
- function itself, using <code class="docutils literal notranslate"><span class="pre">-></span></code> notation.</p>
- <p>For example:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">add -> int</span>
- <span class="cm"> a: int</span>
- <span class="cm"> b: int</span>
- <span class="cm"> /</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>Return converters behave much the same as parameter converters;
- they take arguments, the arguments are all keyword-only, and if you’re not changing
- any of the default arguments you can omit the parentheses.</p>
- <p>(If you use both <code class="docutils literal notranslate"><span class="pre">"as"</span></code> <em>and</em> a return converter for your function,
- the <code class="docutils literal notranslate"><span class="pre">"as"</span></code> should come before the return converter.)</p>
- <p>There’s one additional complication when using return converters: how do you
- indicate an error has occurred? Normally, a function returns a valid (non-<code class="docutils literal notranslate"><span class="pre">NULL</span></code>)
- pointer for success, and <code class="docutils literal notranslate"><span class="pre">NULL</span></code> for failure. But if you use an integer return converter,
- all integers are valid. How can Argument Clinic detect an error? Its solution: each return
- converter implicitly looks for a special value that indicates an error. If you return
- that value, and an error has been set (c:func:<cite>PyErr_Occurred</cite> returns a true
- value), then the generated code will propagate the error. Otherwise it will
- encode the value you return like normal.</p>
- <p>Currently Argument Clinic supports only a few return converters:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>bool
- double
- float
- int
- long
- Py_ssize_t
- size_t
- unsigned int
- unsigned long
- </pre></div>
- </div>
- <p>None of these take parameters.
- For all of these, return <code class="docutils literal notranslate"><span class="pre">-1</span></code> to indicate error.</p>
- <p>To see all the return converters Argument Clinic supports, along with
- their parameters (if any),
- just run <code class="docutils literal notranslate"><span class="pre">Tools/clinic/clinic.py</span> <span class="pre">--converters</span></code> for the full list.</p>
- </section>
- <section id="how-to-clone-existing-functions">
- <h3>How to clone existing functions<a class="headerlink" href="#how-to-clone-existing-functions" title="Permalink to this headline">¶</a></h3>
- <p>If you have a number of functions that look similar, you may be able to
- use Clinic’s “clone” feature. When you clone an existing function,
- you reuse:</p>
- <ul class="simple">
- <li><p>its parameters, including</p>
- <ul>
- <li><p>their names,</p></li>
- <li><p>their converters, with all parameters,</p></li>
- <li><p>their default values,</p></li>
- <li><p>their per-parameter docstrings,</p></li>
- <li><p>their <em>kind</em> (whether they’re positional only,
- positional or keyword, or keyword only), and</p></li>
- </ul>
- </li>
- <li><p>its return converter.</p></li>
- </ul>
- <p>The only thing not copied from the original function is its docstring;
- the syntax allows you to specify a new docstring.</p>
- <p>Here’s the syntax for cloning a function:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">module.class.new_function [as c_basename] = module.class.existing_function</span>
- <span class="cm">Docstring for new_function goes here.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>(The functions can be in different modules or classes. I wrote
- <code class="docutils literal notranslate"><span class="pre">module.class</span></code> in the sample just to illustrate that you must
- use the full path to <em>both</em> functions.)</p>
- <p>Sorry, there’s no syntax for partially cloning a function, or cloning a function
- then modifying it. Cloning is an all-or nothing proposition.</p>
- <p>Also, the function you are cloning from must have been previously defined
- in the current file.</p>
- </section>
- <section id="how-to-call-python-code">
- <h3>How to call Python code<a class="headerlink" href="#how-to-call-python-code" title="Permalink to this headline">¶</a></h3>
- <p>The rest of the advanced topics require you to write Python code
- which lives inside your C file and modifies Argument Clinic’s
- runtime state. This is simple: you simply define a Python block.</p>
- <p>A Python block uses different delimiter lines than an Argument
- Clinic function block. It looks like this:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[python input]</span>
- <span class="cm"># python code goes here</span>
- <span class="cm">[python start generated code]*/</span>
- </pre></div>
- </div>
- <p>All the code inside the Python block is executed at the
- time it’s parsed. All text written to stdout inside the block
- is redirected into the “output” after the block.</p>
- <p>As an example, here’s a Python block that adds a static integer
- variable to the C code:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[python input]</span>
- <span class="cm">print('static int __ignored_unused_variable__ = 0;')</span>
- <span class="cm">[python start generated code]*/</span>
- <span class="k">static</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">__ignored_unused_variable__</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
- <span class="cm">/*[python checksum:...]*/</span>
- </pre></div>
- </div>
- </section>
- <section id="how-to-use-the-self-converter">
- <span id="clinic-howto-self-converter"></span><h3>How to use the “self converter”<a class="headerlink" href="#how-to-use-the-self-converter" title="Permalink to this headline">¶</a></h3>
- <p>Argument Clinic automatically adds a “self” parameter for you
- using a default converter. It automatically sets the <code class="docutils literal notranslate"><span class="pre">type</span></code>
- of this parameter to the “pointer to an instance” you specified
- when you declared the type. However, you can override
- Argument Clinic’s converter and specify one yourself.
- Just add your own <em>self</em> parameter as the first parameter in a
- block, and ensure that its converter is an instance of
- <code class="xref py py-class docutils literal notranslate"><span class="pre">self_converter</span></code> or a subclass thereof.</p>
- <p>What’s the point? This lets you override the type of <code class="docutils literal notranslate"><span class="pre">self</span></code>,
- or give it a different default name.</p>
- <p>How do you specify the custom type you want to cast <code class="docutils literal notranslate"><span class="pre">self</span></code> to?
- If you only have one or two functions with the same type for <code class="docutils literal notranslate"><span class="pre">self</span></code>,
- you can directly use Argument Clinic’s existing <code class="docutils literal notranslate"><span class="pre">self</span></code> converter,
- passing in the type you want to use as the <em>type</em> parameter:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm"> self: self(type="PicklerObject *")</span>
- <span class="cm"> obj: object</span>
- <span class="cm"> /</span>
- <span class="cm">Write a pickled representation of the given object to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>On the other hand, if you have a lot of functions that will use the same
- type for <code class="docutils literal notranslate"><span class="pre">self</span></code>, it’s best to create your own converter, subclassing
- <code class="xref py py-class docutils literal notranslate"><span class="pre">self_converter</span></code> but overwriting the <code class="xref py py-attr docutils literal notranslate"><span class="pre">type</span></code> member:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[python input]</span>
- <span class="cm">class PicklerObject_converter(self_converter):</span>
- <span class="cm"> type = "PicklerObject *"</span>
- <span class="cm">[python start generated code]*/</span>
- <span class="cm">/*[clinic input]</span>
- <span class="cm">_pickle.Pickler.dump</span>
- <span class="cm"> self: PicklerObject</span>
- <span class="cm"> obj: object</span>
- <span class="cm"> /</span>
- <span class="cm">Write a pickled representation of the given object to the open file.</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- </section>
- <section id="how-to-use-the-defining-class-converter">
- <h3>How to use the “defining class” converter<a class="headerlink" href="#how-to-use-the-defining-class-converter" title="Permalink to this headline">¶</a></h3>
- <p>Argument Clinic facilitates gaining access to the defining class of a method.
- This is useful for <a class="reference internal" href="../c-api/typeobj.html#heap-types"><span class="std std-ref">heap type</span></a> methods that need to fetch
- module level state. Use <a class="reference internal" href="../c-api/type.html#c.PyType_FromModuleAndSpec" title="PyType_FromModuleAndSpec"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyType_FromModuleAndSpec()</span></code></a> to associate a new
- heap type with a module. You can now use <a class="reference internal" href="../c-api/type.html#c.PyType_GetModuleState" title="PyType_GetModuleState"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyType_GetModuleState()</span></code></a> on
- the defining class to fetch the module state, for example from a module method.</p>
- <p>Example from <a class="reference external" href="https://github.com/python/cpython/tree/3.12/Modules/zlibmodule.c">Modules/zlibmodule.c</a>.
- First, <code class="docutils literal notranslate"><span class="pre">defining_class</span></code> is added to the clinic input:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">zlib.Compress.compress</span>
- <span class="cm"> cls: defining_class</span>
- <span class="cm"> data: Py_buffer</span>
- <span class="cm"> Binary data to be compressed.</span>
- <span class="cm"> /</span>
- </pre></div>
- </div>
- <p>After running the Argument Clinic tool, the following function signature is
- generated:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic start generated code]*/</span>
- <span class="k">static</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
- <span class="n">zlib_Compress_compress_impl</span><span class="p">(</span><span class="n">compobject</span><span class="w"> </span><span class="o">*</span><span class="n">self</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">cls</span><span class="p">,</span>
- <span class="w"> </span><span class="n">Py_buffer</span><span class="w"> </span><span class="o">*</span><span class="n">data</span><span class="p">)</span>
- <span class="cm">/*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/</span>
- </pre></div>
- </div>
- <p>The following code can now use <code class="docutils literal notranslate"><span class="pre">PyType_GetModuleState(cls)</span></code> to fetch the
- module state:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">zlibstate</span><span class="w"> </span><span class="o">*</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyType_GetModuleState</span><span class="p">(</span><span class="n">cls</span><span class="p">);</span>
- </pre></div>
- </div>
- <p>Each method may only have one argument using this converter, and it must appear
- after <code class="docutils literal notranslate"><span class="pre">self</span></code>, or, if <code class="docutils literal notranslate"><span class="pre">self</span></code> is not used, as the first argument. The argument
- will be of type <code class="docutils literal notranslate"><span class="pre">PyTypeObject</span> <span class="pre">*</span></code>. The argument will not appear in the
- <code class="xref py py-attr docutils literal notranslate"><span class="pre">__text_signature__</span></code>.</p>
- <p>The <code class="docutils literal notranslate"><span class="pre">defining_class</span></code> converter is not compatible with <code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code>
- and <code class="xref py py-meth docutils literal notranslate"><span class="pre">__new__()</span></code> methods, which cannot use the <a class="reference internal" href="../c-api/structures.html#c.METH_METHOD" title="METH_METHOD"><code class="xref c c-macro docutils literal notranslate"><span class="pre">METH_METHOD</span></code></a>
- convention.</p>
- <p>It is not possible to use <code class="docutils literal notranslate"><span class="pre">defining_class</span></code> with slot methods. In order to
- fetch the module state from such methods, use <a class="reference internal" href="../c-api/type.html#c.PyType_GetModuleByDef" title="PyType_GetModuleByDef"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyType_GetModuleByDef()</span></code></a>
- to look up the module and then <a class="reference internal" href="../c-api/module.html#c.PyModule_GetState" title="PyModule_GetState"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyModule_GetState()</span></code></a> to fetch the module
- state. Example from the <code class="docutils literal notranslate"><span class="pre">setattro</span></code> slot method in
- <a class="reference external" href="https://github.com/python/cpython/tree/3.12/Modules/_threadmodule.c">Modules/_threadmodule.c</a>:</p>
- <div class="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">local_setattro</span><span class="p">(</span><span class="n">localobject</span><span class="w"> </span><span class="o">*</span><span class="n">self</span><span class="p">,</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">v</span><span class="p">)</span>
- <span class="p">{</span>
- <span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">module</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyType_GetModuleByDef</span><span class="p">(</span><span class="n">Py_TYPE</span><span class="p">(</span><span class="n">self</span><span class="p">),</span><span class="w"> </span><span class="o">&</span><span class="n">thread_module</span><span class="p">);</span>
- <span class="w"> </span><span class="n">thread_module_state</span><span class="w"> </span><span class="o">*</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">get_thread_state</span><span class="p">(</span><span class="n">module</span><span class="p">);</span>
- <span class="w"> </span><span class="p">...</span>
- <span class="p">}</span>
- </pre></div>
- </div>
- <p>See also <span class="target" id="index-3"></span><a class="pep reference external" href="https://peps.python.org/pep-0573/"><strong>PEP 573</strong></a>.</p>
- </section>
- <section id="how-to-write-a-custom-converter">
- <span id="clinic-howto-custom-converter"></span><h3>How to write a custom converter<a class="headerlink" href="#how-to-write-a-custom-converter" title="Permalink to this headline">¶</a></h3>
- <p>A converter is a Python class that inherits from <a class="reference internal" href="#clinic.CConverter" title="clinic.CConverter"><code class="xref py py-class docutils literal notranslate"><span class="pre">CConverter</span></code></a>.
- The main purpose of a custom converter, is for parameters parsed with
- the <code class="docutils literal notranslate"><span class="pre">O&</span></code> format unit — parsing such a parameter means calling
- a <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a> “converter function”.</p>
- <p>Your converter class should be named <code class="samp docutils literal notranslate"><em><span class="pre">ConverterName</span></em><span class="pre">_converter</span></code>.
- By following this convention, your converter class will be automatically
- registered with Argument Clinic, with its <em>converter name</em> being the name of
- your converter class with the <code class="docutils literal notranslate"><span class="pre">_converter</span></code> suffix stripped off.</p>
- <p>Instead of subclassing <code class="xref py py-meth docutils literal notranslate"><span class="pre">CConverter.__init__()</span></code>,
- write a <code class="xref py py-meth docutils literal notranslate"><span class="pre">converter_init()</span></code> method.
- <code class="xref py py-meth docutils literal notranslate"><span class="pre">converter_init()</span></code> always accepts a <em>self</em> parameter.
- After <em>self</em>, all additional parameters <strong>must</strong> be keyword-only.
- Any arguments passed to the converter in Argument Clinic
- will be passed along to your <code class="xref py py-meth docutils literal notranslate"><span class="pre">converter_init()</span></code> method.
- See <a class="reference internal" href="#clinic.CConverter" title="clinic.CConverter"><code class="xref py py-class docutils literal notranslate"><span class="pre">CConverter</span></code></a> for a list of members you may wish to specify in
- your subclass.</p>
- <p>Here’s the simplest example of a custom converter, from <a class="reference external" href="https://github.com/python/cpython/tree/3.12/Modules/zlibmodule.c">Modules/zlibmodule.c</a>:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[python input]</span>
- <span class="cm">class ssize_t_converter(CConverter):</span>
- <span class="cm"> type = 'Py_ssize_t'</span>
- <span class="cm"> converter = 'ssize_t_converter'</span>
- <span class="cm">[python start generated code]*/</span>
- <span class="cm">/*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/</span>
- </pre></div>
- </div>
- <p>This block adds a converter named <code class="docutils literal notranslate"><span class="pre">ssize_t</span></code> to Argument Clinic.
- Parameters declared as <code class="docutils literal notranslate"><span class="pre">ssize_t</span></code> will be declared with type <a class="reference internal" href="../c-api/intro.html#c.Py_ssize_t" title="Py_ssize_t"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_ssize_t</span></code></a>,
- and will be parsed by the <code class="docutils literal notranslate"><span class="pre">'O&'</span></code> format unit,
- which will call the <code class="xref c c-func docutils literal notranslate"><span class="pre">ssize_t_converter()</span></code> converter C function.
- <code class="docutils literal notranslate"><span class="pre">ssize_t</span></code> variables automatically support default values.</p>
- <p>More sophisticated custom converters can insert custom C code to
- handle initialization and cleanup.
- You can see more examples of custom converters in the CPython
- source tree; grep the C files for the string <code class="docutils literal notranslate"><span class="pre">CConverter</span></code>.</p>
- </section>
- <section id="how-to-write-a-custom-return-converter">
- <h3>How to write a custom return converter<a class="headerlink" href="#how-to-write-a-custom-return-converter" title="Permalink to this headline">¶</a></h3>
- <p>Writing a custom return converter is much like writing
- a custom converter. Except it’s somewhat simpler, because return
- converters are themselves much simpler.</p>
- <p>Return converters must subclass <code class="xref py py-class docutils literal notranslate"><span class="pre">CReturnConverter</span></code>.
- There are no examples yet of custom return converters,
- because they are not widely used yet. If you wish to
- write your own return converter, please read <a class="reference external" href="https://github.com/python/cpython/tree/3.12/Tools/clinic/clinic.py">Tools/clinic/clinic.py</a>,
- specifically the implementation of <code class="xref py py-class docutils literal notranslate"><span class="pre">CReturnConverter</span></code> and
- all its subclasses.</p>
- </section>
- <section id="how-to-convert-meth-o-and-meth-noargs-functions">
- <h3>How to convert <code class="docutils literal notranslate"><span class="pre">METH_O</span></code> and <code class="docutils literal notranslate"><span class="pre">METH_NOARGS</span></code> functions<a class="headerlink" href="#how-to-convert-meth-o-and-meth-noargs-functions" title="Permalink to this headline">¶</a></h3>
- <p>To convert a function using <a class="reference internal" href="../c-api/structures.html#c.METH_O" title="METH_O"><code class="xref c c-macro docutils literal notranslate"><span class="pre">METH_O</span></code></a>, make sure the function’s
- single argument is using the <code class="docutils literal notranslate"><span class="pre">object</span></code> converter, and mark the
- arguments as positional-only:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/*[clinic input]</span>
- <span class="cm">meth_o_sample</span>
- <span class="cm"> argument: object</span>
- <span class="cm"> /</span>
- <span class="cm">[clinic start generated code]*/</span>
- </pre></div>
- </div>
- <p>To convert a function using <a class="reference internal" href="../c-api/structures.html#c.METH_NOARGS" title="METH_NOARGS"><code class="xref c c-macro docutils literal notranslate"><span class="pre">METH_NOARGS</span></code></a>, just don’t specify
- any arguments.</p>
- <p>You can still use a self converter, a return converter, and specify
- a <em>type</em> argument to the object converter for <a class="reference internal" href="../c-api/structures.html#c.METH_O" title="METH_O"><code class="xref c c-macro docutils literal notranslate"><span class="pre">METH_O</span></code></a>.</p>
- </section>
- <section id="how-to-convert-tp-new-and-tp-init-functions">
- <h3>How to convert <code class="docutils literal notranslate"><span class="pre">tp_new</span></code> and <code class="docutils literal notranslate"><span class="pre">tp_init</span></code> functions<a class="headerlink" href="#how-to-convert-tp-new-and-tp-init-functions" title="Permalink to this headline">¶</a></h3>
- <p>You can convert <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_new" title="PyTypeObject.tp_new"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_new</span></code></a> and
- <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_init" title="PyTypeObject.tp_init"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_init</span></code></a> functions.
- Just name them <code class="docutils literal notranslate"><span class="pre">__new__</span></code> or <code class="docutils literal notranslate"><span class="pre">__init__</span></code> as appropriate. Notes:</p>
- <ul class="simple">
- <li><p>The function name generated for <code class="docutils literal notranslate"><span class="pre">__new__</span></code> doesn’t end in <code class="docutils literal notranslate"><span class="pre">__new__</span></code>
- like it would by default. It’s just the name of the class, converted
- into a valid C identifier.</p></li>
- <li><p>No <a class="reference internal" href="../c-api/structures.html#c.PyMethodDef" title="PyMethodDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code></a> <code class="docutils literal notranslate"><span class="pre">#define</span></code> is generated for these functions.</p></li>
- <li><p><code class="docutils literal notranslate"><span class="pre">__init__</span></code> functions return <code class="docutils literal notranslate"><span class="pre">int</span></code>, not <code class="docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">*</span></code>.</p></li>
- <li><p>Use the docstring as the class docstring.</p></li>
- <li><p>Although <code class="docutils literal notranslate"><span class="pre">__new__</span></code> and <code class="docutils literal notranslate"><span class="pre">__init__</span></code> functions must always
- accept both the <code class="docutils literal notranslate"><span class="pre">args</span></code> and <code class="docutils literal notranslate"><span class="pre">kwargs</span></code> objects, when converting
- you may specify any signature for these functions that you like.
- (If your function doesn’t support keywords, the parsing function
- generated will throw an exception if it receives any.)</p></li>
- </ul>
- </section>
- <section id="how-to-change-and-redirect-clinic-s-output">
- <h3>How to change and redirect Clinic’s output<a class="headerlink" href="#how-to-change-and-redirect-clinic-s-output" title="Permalink to this headline">¶</a></h3>
- <p>It can be inconvenient to have Clinic’s output interspersed with
- your conventional hand-edited C code. Luckily, Clinic is configurable:
- you can buffer up its output for printing later (or earlier!), or write
- its output to a separate file. You can also add a prefix or suffix to
- every line of Clinic’s generated output.</p>
- <p>While changing Clinic’s output in this manner can be a boon to readability,
- it may result in Clinic code using types before they are defined, or
- your code attempting to use Clinic-generated code before it is defined.
- These problems can be easily solved by rearranging the declarations in your file,
- or moving where Clinic’s generated code goes. (This is why the default behavior
- of Clinic is to output everything into the current block; while many people
- consider this hampers readability, it will never require rearranging your
- code to fix definition-before-use problems.)</p>
- <p>Let’s start with defining some terminology:</p>
- <dl>
- <dt><em>field</em></dt><dd><p>A field, in this context, is a subsection of Clinic’s output.
- For example, the <code class="docutils literal notranslate"><span class="pre">#define</span></code> for the <a class="reference internal" href="../c-api/structures.html#c.PyMethodDef" title="PyMethodDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code></a> structure
- is a field, called <code class="docutils literal notranslate"><span class="pre">methoddef_define</span></code>. Clinic has seven
- different fields it can output per function definition:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>docstring_prototype
- docstring_definition
- methoddef_define
- impl_prototype
- parser_prototype
- parser_definition
- impl_definition
- </pre></div>
- </div>
- <p>All the names are of the form <code class="docutils literal notranslate"><span class="pre">"<a>_<b>"</span></code>,
- where <code class="docutils literal notranslate"><span class="pre">"<a>"</span></code> is the semantic object represented (the parsing function,
- the impl function, the docstring, or the methoddef structure) and <code class="docutils literal notranslate"><span class="pre">"<b>"</span></code>
- represents what kind of statement the field is. Field names that end in
- <code class="docutils literal notranslate"><span class="pre">"_prototype"</span></code>
- represent forward declarations of that thing, without the actual body/data
- of the thing; field names that end in <code class="docutils literal notranslate"><span class="pre">"_definition"</span></code> represent the actual
- definition of the thing, with the body/data of the thing. (<code class="docutils literal notranslate"><span class="pre">"methoddef"</span></code>
- is special, it’s the only one that ends with <code class="docutils literal notranslate"><span class="pre">"_define"</span></code>, representing that
- it’s a preprocessor #define.)</p>
- </dd>
- <dt><em>destination</em></dt><dd><p>A destination is a place Clinic can write output to. There are
- five built-in destinations:</p>
- <dl>
- <dt><code class="docutils literal notranslate"><span class="pre">block</span></code></dt><dd><p>The default destination: printed in the output section of
- the current Clinic block.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">buffer</span></code></dt><dd><p>A text buffer where you can save text for later. Text sent
- here is appended to the end of any existing text. It’s an
- error to have any text left in the buffer when Clinic finishes
- processing a file.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">file</span></code></dt><dd><p>A separate “clinic file” that will be created automatically by Clinic.
- The filename chosen for the file is <code class="docutils literal notranslate"><span class="pre">{basename}.clinic{extension}</span></code>,
- where <code class="docutils literal notranslate"><span class="pre">basename</span></code> and <code class="docutils literal notranslate"><span class="pre">extension</span></code> were assigned the output
- from <code class="docutils literal notranslate"><span class="pre">os.path.splitext()</span></code> run on the current file. (Example:
- the <code class="docutils literal notranslate"><span class="pre">file</span></code> destination for <code class="file docutils literal notranslate"><span class="pre">_pickle.c</span></code> would be written to
- <code class="file docutils literal notranslate"><span class="pre">_pickle.clinic.c</span></code>.)</p>
- <p><strong>Important: When using a</strong> <code class="docutils literal notranslate"><span class="pre">file</span></code> <strong>destination, you</strong>
- <em>must check in</em> <strong>the generated file!</strong></p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">two-pass</span></code></dt><dd><p>A buffer like <code class="docutils literal notranslate"><span class="pre">buffer</span></code>. However, a two-pass buffer can only
- be dumped once, and it prints out all text sent to it during
- all processing, even from Clinic blocks <em>after</em> the dumping point.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">suppress</span></code></dt><dd><p>The text is suppressed—thrown away.</p>
- </dd>
- </dl>
- </dd>
- </dl>
- <p>Clinic defines five new directives that let you reconfigure its output.</p>
- <p>The first new directive is <code class="docutils literal notranslate"><span class="pre">dump</span></code>:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>dump <destination>
- </pre></div>
- </div>
- <p>This dumps the current contents of the named destination into the output of
- the current block, and empties it. This only works with <code class="docutils literal notranslate"><span class="pre">buffer</span></code> and
- <code class="docutils literal notranslate"><span class="pre">two-pass</span></code> destinations.</p>
- <p>The second new directive is <code class="docutils literal notranslate"><span class="pre">output</span></code>. The most basic form of <code class="docutils literal notranslate"><span class="pre">output</span></code>
- is like this:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>output <field> <destination>
- </pre></div>
- </div>
- <p>This tells Clinic to output <em>field</em> to <em>destination</em>. <code class="docutils literal notranslate"><span class="pre">output</span></code> also
- supports a special meta-destination, called <code class="docutils literal notranslate"><span class="pre">everything</span></code>, which tells
- Clinic to output <em>all</em> fields to that <em>destination</em>.</p>
- <p><code class="docutils literal notranslate"><span class="pre">output</span></code> has a number of other functions:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>output push
- output pop
- output preset <preset>
- </pre></div>
- </div>
- <p><code class="docutils literal notranslate"><span class="pre">output</span> <span class="pre">push</span></code> and <code class="docutils literal notranslate"><span class="pre">output</span> <span class="pre">pop</span></code> allow you to push and pop
- configurations on an internal configuration stack, so that you
- can temporarily modify the output configuration, then easily restore
- the previous configuration. Simply push before your change to save
- the current configuration, then pop when you wish to restore the
- previous configuration.</p>
- <p><code class="docutils literal notranslate"><span class="pre">output</span> <span class="pre">preset</span></code> sets Clinic’s output to one of several built-in
- preset configurations, as follows:</p>
- <blockquote>
- <div><dl>
- <dt><code class="docutils literal notranslate"><span class="pre">block</span></code></dt><dd><p>Clinic’s original starting configuration. Writes everything
- immediately after the input block.</p>
- <p>Suppress the <code class="docutils literal notranslate"><span class="pre">parser_prototype</span></code>
- and <code class="docutils literal notranslate"><span class="pre">docstring_prototype</span></code>, write everything else to <code class="docutils literal notranslate"><span class="pre">block</span></code>.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">file</span></code></dt><dd><p>Designed to write everything to the “clinic file” that it can.
- You then <code class="docutils literal notranslate"><span class="pre">#include</span></code> this file near the top of your file.
- You may need to rearrange your file to make this work, though
- usually this just means creating forward declarations for various
- <code class="docutils literal notranslate"><span class="pre">typedef</span></code> and <code class="docutils literal notranslate"><span class="pre">PyTypeObject</span></code> definitions.</p>
- <p>Suppress the <code class="docutils literal notranslate"><span class="pre">parser_prototype</span></code>
- and <code class="docutils literal notranslate"><span class="pre">docstring_prototype</span></code>, write the <code class="docutils literal notranslate"><span class="pre">impl_definition</span></code> to
- <code class="docutils literal notranslate"><span class="pre">block</span></code>, and write everything else to <code class="docutils literal notranslate"><span class="pre">file</span></code>.</p>
- <p>The default filename is <code class="docutils literal notranslate"><span class="pre">"{dirname}/clinic/{basename}.h"</span></code>.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">buffer</span></code></dt><dd><p>Save up most of the output from Clinic, to be written into
- your file near the end. For Python files implementing modules
- or builtin types, it’s recommended that you dump the buffer
- just above the static structures for your module or
- builtin type; these are normally very near the end. Using
- <code class="docutils literal notranslate"><span class="pre">buffer</span></code> may require even more editing than <code class="docutils literal notranslate"><span class="pre">file</span></code>, if
- your file has static <code class="docutils literal notranslate"><span class="pre">PyMethodDef</span></code> arrays defined in the
- middle of the file.</p>
- <p>Suppress the <code class="docutils literal notranslate"><span class="pre">parser_prototype</span></code>, <code class="docutils literal notranslate"><span class="pre">impl_prototype</span></code>,
- and <code class="docutils literal notranslate"><span class="pre">docstring_prototype</span></code>, write the <code class="docutils literal notranslate"><span class="pre">impl_definition</span></code> to
- <code class="docutils literal notranslate"><span class="pre">block</span></code>, and write everything else to <code class="docutils literal notranslate"><span class="pre">file</span></code>.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">two-pass</span></code></dt><dd><p>Similar to the <code class="docutils literal notranslate"><span class="pre">buffer</span></code> preset, but writes forward declarations to
- the <code class="docutils literal notranslate"><span class="pre">two-pass</span></code> buffer, and definitions to the <code class="docutils literal notranslate"><span class="pre">buffer</span></code>.
- This is similar to the <code class="docutils literal notranslate"><span class="pre">buffer</span></code> preset, but may require
- less editing than <code class="docutils literal notranslate"><span class="pre">buffer</span></code>. Dump the <code class="docutils literal notranslate"><span class="pre">two-pass</span></code> buffer
- near the top of your file, and dump the <code class="docutils literal notranslate"><span class="pre">buffer</span></code> near
- the end just like you would when using the <code class="docutils literal notranslate"><span class="pre">buffer</span></code> preset.</p>
- <p>Suppresses the <code class="docutils literal notranslate"><span class="pre">impl_prototype</span></code>, write the <code class="docutils literal notranslate"><span class="pre">impl_definition</span></code>
- to <code class="docutils literal notranslate"><span class="pre">block</span></code>, write <code class="docutils literal notranslate"><span class="pre">docstring_prototype</span></code>, <code class="docutils literal notranslate"><span class="pre">methoddef_define</span></code>,
- and <code class="docutils literal notranslate"><span class="pre">parser_prototype</span></code> to <code class="docutils literal notranslate"><span class="pre">two-pass</span></code>, write everything else
- to <code class="docutils literal notranslate"><span class="pre">buffer</span></code>.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">partial-buffer</span></code></dt><dd><p>Similar to the <code class="docutils literal notranslate"><span class="pre">buffer</span></code> preset, but writes more things to <code class="docutils literal notranslate"><span class="pre">block</span></code>,
- only writing the really big chunks of generated code to <code class="docutils literal notranslate"><span class="pre">buffer</span></code>.
- This avoids the definition-before-use problem of <code class="docutils literal notranslate"><span class="pre">buffer</span></code> completely,
- at the small cost of having slightly more stuff in the block’s output.
- Dump the <code class="docutils literal notranslate"><span class="pre">buffer</span></code> near the end, just like you would when using
- the <code class="docutils literal notranslate"><span class="pre">buffer</span></code> preset.</p>
- <p>Suppresses the <code class="docutils literal notranslate"><span class="pre">impl_prototype</span></code>, write the <code class="docutils literal notranslate"><span class="pre">docstring_definition</span></code>
- and <code class="docutils literal notranslate"><span class="pre">parser_definition</span></code> to <code class="docutils literal notranslate"><span class="pre">buffer</span></code>, write everything else to <code class="docutils literal notranslate"><span class="pre">block</span></code>.</p>
- </dd>
- </dl>
- </div></blockquote>
- <p>The third new directive is <code class="docutils literal notranslate"><span class="pre">destination</span></code>:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>destination <name> <command> [...]
- </pre></div>
- </div>
- <p>This performs an operation on the destination named <code class="docutils literal notranslate"><span class="pre">name</span></code>.</p>
- <p>There are two defined subcommands: <code class="docutils literal notranslate"><span class="pre">new</span></code> and <code class="docutils literal notranslate"><span class="pre">clear</span></code>.</p>
- <p>The <code class="docutils literal notranslate"><span class="pre">new</span></code> subcommand works like this:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>destination <name> new <type>
- </pre></div>
- </div>
- <p>This creates a new destination with name <code class="docutils literal notranslate"><span class="pre"><name></span></code> and type <code class="docutils literal notranslate"><span class="pre"><type></span></code>.</p>
- <p>There are five destination types:</p>
- <blockquote>
- <div><dl>
- <dt><code class="docutils literal notranslate"><span class="pre">suppress</span></code></dt><dd><p>Throws the text away.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">block</span></code></dt><dd><p>Writes the text to the current block. This is what Clinic
- originally did.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">buffer</span></code></dt><dd><p>A simple text buffer, like the “buffer” builtin destination above.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">file</span></code></dt><dd><p>A text file. The file destination takes an extra argument,
- a template to use for building the filename, like so:</p>
- <blockquote>
- <div><p>destination <name> new <type> <file_template></p>
- </div></blockquote>
- <p>The template can use three strings internally that will be replaced
- by bits of the filename:</p>
- <blockquote>
- <div><dl class="simple">
- <dt>{path}</dt><dd><p>The full path to the file, including directory and full filename.</p>
- </dd>
- <dt>{dirname}</dt><dd><p>The name of the directory the file is in.</p>
- </dd>
- <dt>{basename}</dt><dd><p>Just the name of the file, not including the directory.</p>
- </dd>
- <dt>{basename_root}</dt><dd><p>Basename with the extension clipped off
- (everything up to but not including the last ‘.’).</p>
- </dd>
- <dt>{basename_extension}</dt><dd><p>The last ‘.’ and everything after it. If the basename
- does not contain a period, this will be the empty string.</p>
- </dd>
- </dl>
- </div></blockquote>
- <p>If there are no periods in the filename, {basename} and {filename}
- are the same, and {extension} is empty. “{basename}{extension}”
- is always exactly the same as “{filename}”.”</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">two-pass</span></code></dt><dd><p>A two-pass buffer, like the “two-pass” builtin destination above.</p>
- </dd>
- </dl>
- </div></blockquote>
- <p>The <code class="docutils literal notranslate"><span class="pre">clear</span></code> subcommand works like this:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>destination <name> clear
- </pre></div>
- </div>
- <p>It removes all the accumulated text up to this point in the destination.
- (I don’t know what you’d need this for, but I thought maybe it’d be
- useful while someone’s experimenting.)</p>
- <p>The fourth new directive is <code class="docutils literal notranslate"><span class="pre">set</span></code>:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>set line_prefix "string"
- set line_suffix "string"
- </pre></div>
- </div>
- <p><code class="docutils literal notranslate"><span class="pre">set</span></code> lets you set two internal variables in Clinic.
- <code class="docutils literal notranslate"><span class="pre">line_prefix</span></code> is a string that will be prepended to every line of Clinic’s output;
- <code class="docutils literal notranslate"><span class="pre">line_suffix</span></code> is a string that will be appended to every line of Clinic’s output.</p>
- <p>Both of these support two format strings:</p>
- <blockquote>
- <div><dl class="simple">
- <dt><code class="docutils literal notranslate"><span class="pre">{block</span> <span class="pre">comment</span> <span class="pre">start}</span></code></dt><dd><p>Turns into the string <code class="docutils literal notranslate"><span class="pre">/*</span></code>, the start-comment text sequence for C files.</p>
- </dd>
- <dt><code class="docutils literal notranslate"><span class="pre">{block</span> <span class="pre">comment</span> <span class="pre">end}</span></code></dt><dd><p>Turns into the string <code class="docutils literal notranslate"><span class="pre">*/</span></code>, the end-comment text sequence for C files.</p>
- </dd>
- </dl>
- </div></blockquote>
- <p>The final new directive is one you shouldn’t need to use directly,
- called <code class="docutils literal notranslate"><span class="pre">preserve</span></code>:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>preserve
- </pre></div>
- </div>
- <p>This tells Clinic that the current contents of the output should be kept, unmodified.
- This is used internally by Clinic when dumping output into <code class="docutils literal notranslate"><span class="pre">file</span></code> files; wrapping
- it in a Clinic block lets Clinic use its existing checksum functionality to ensure
- the file was not modified by hand before it gets overwritten.</p>
- </section>
- <section id="how-to-use-the-ifdef-trick">
- <h3>How to use the <code class="docutils literal notranslate"><span class="pre">#ifdef</span></code> trick<a class="headerlink" href="#how-to-use-the-ifdef-trick" title="Permalink to this headline">¶</a></h3>
- <p>If you’re converting a function that isn’t available on all platforms,
- there’s a trick you can use to make life a little easier. The existing
- code probably looks like this:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef HAVE_FUNCTIONNAME</span>
- <span class="k">static</span><span class="w"> </span><span class="n">module_functionname</span><span class="p">(...)</span>
- <span class="p">{</span>
- <span class="p">...</span>
- <span class="p">}</span>
- <span class="cp">#endif </span><span class="cm">/* HAVE_FUNCTIONNAME */</span>
- </pre></div>
- </div>
- <p>And then in the <code class="docutils literal notranslate"><span class="pre">PyMethodDef</span></code> structure at the bottom the existing code
- will have:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#ifdef HAVE_FUNCTIONNAME
- {'functionname', ... },
- #endif /* HAVE_FUNCTIONNAME */
- </pre></div>
- </div>
- <p>In this scenario, you should enclose the body of your impl function inside the <code class="docutils literal notranslate"><span class="pre">#ifdef</span></code>,
- like so:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef HAVE_FUNCTIONNAME</span>
- <span class="cm">/*[clinic input]</span>
- <span class="cm">module.functionname</span>
- <span class="cm">...</span>
- <span class="cm">[clinic start generated code]*/</span>
- <span class="k">static</span><span class="w"> </span><span class="n">module_functionname</span><span class="p">(...)</span>
- <span class="p">{</span>
- <span class="p">...</span>
- <span class="p">}</span>
- <span class="cp">#endif </span><span class="cm">/* HAVE_FUNCTIONNAME */</span>
- </pre></div>
- </div>
- <p>Then, remove those three lines from the <a class="reference internal" href="../c-api/structures.html#c.PyMethodDef" title="PyMethodDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code></a> structure,
- replacing them with the macro Argument Clinic generated:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>MODULE_FUNCTIONNAME_METHODDEF
- </pre></div>
- </div>
- <p>(You can find the real name for this macro inside the generated code.
- Or you can calculate it yourself: it’s the name of your function as defined
- on the first line of your block, but with periods changed to underscores,
- uppercased, and <code class="docutils literal notranslate"><span class="pre">"_METHODDEF"</span></code> added to the end.)</p>
- <p>Perhaps you’re wondering: what if <code class="docutils literal notranslate"><span class="pre">HAVE_FUNCTIONNAME</span></code> isn’t defined?
- The <code class="docutils literal notranslate"><span class="pre">MODULE_FUNCTIONNAME_METHODDEF</span></code> macro won’t be defined either!</p>
- <p>Here’s where Argument Clinic gets very clever. It actually detects that the
- Argument Clinic block might be deactivated by the <code class="docutils literal notranslate"><span class="pre">#ifdef</span></code>. When that
- happens, it generates a little extra code that looks like this:</p>
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifndef MODULE_FUNCTIONNAME_METHODDEF</span>
- <span class="w"> </span><span class="cp">#define MODULE_FUNCTIONNAME_METHODDEF</span>
- <span class="cp">#endif </span><span class="cm">/* !defined(MODULE_FUNCTIONNAME_METHODDEF) */</span>
- </pre></div>
- </div>
- <p>That means the macro always works. If the function is defined, this turns
- into the correct structure, including the trailing comma. If the function is
- undefined, this turns into nothing.</p>
- <p>However, this causes one ticklish problem: where should Argument Clinic put this
- extra code when using the “block” output preset? It can’t go in the output block,
- because that could be deactivated by the <code class="docutils literal notranslate"><span class="pre">#ifdef</span></code>. (That’s the whole point!)</p>
- <p>In this situation, Argument Clinic writes the extra code to the “buffer” destination.
- This may mean that you get a complaint from Argument Clinic:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Warning in file "Modules/posixmodule.c" on line 12357:
- Destination buffer 'buffer' not empty at end of file, emptying.
- </pre></div>
- </div>
- <p>When this happens, just open your file, find the <code class="docutils literal notranslate"><span class="pre">dump</span> <span class="pre">buffer</span></code> block that
- Argument Clinic added to your file (it’ll be at the very bottom), then
- move it above the <a class="reference internal" href="../c-api/structures.html#c.PyMethodDef" title="PyMethodDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code></a> structure where that macro is used.</p>
- </section>
- <section id="how-to-use-argument-clinic-in-python-files">
- <h3>How to use Argument Clinic in Python files<a class="headerlink" href="#how-to-use-argument-clinic-in-python-files" title="Permalink to this headline">¶</a></h3>
- <p>It’s actually possible to use Argument Clinic to preprocess Python files.
- There’s no point to using Argument Clinic blocks, of course, as the output
- wouldn’t make any sense to the Python interpreter. But using Argument Clinic
- to run Python blocks lets you use Python as a Python preprocessor!</p>
- <p>Since Python comments are different from C comments, Argument Clinic
- blocks embedded in Python files look slightly different. They look like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1">#/*[python input]</span>
- <span class="c1">#print("def foo(): pass")</span>
- <span class="c1">#[python start generated code]*/</span>
- <span class="k">def</span> <span class="nf">foo</span><span class="p">():</span> <span class="k">pass</span>
- <span class="c1">#/*[python checksum:...]*/</span>
- </pre></div>
- </div>
- </section>
- </section>
- </section>
- <div class="clearer"></div>
- </div>
- </div>
- </div>
- <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
- <div>
- <h3><a href="../contents.html">Table of Contents</a></h3>
- <ul>
- <li><a class="reference internal" href="#">Argument Clinic How-To</a><ul>
- <li><a class="reference internal" href="#background">Background</a><ul>
- <li><a class="reference internal" href="#basic-concepts">Basic concepts</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#reference">Reference</a><ul>
- <li><a class="reference internal" href="#terminology">Terminology</a></li>
- <li><a class="reference internal" href="#command-line-interface">Command-line interface</a></li>
- <li><a class="reference internal" href="#module-clinic">Classes for extending Argument Clinic</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#tutorial">Tutorial</a></li>
- <li><a class="reference internal" href="#how-to-guides">How-to guides</a><ul>
- <li><a class="reference internal" href="#how-to-rename-c-functions-and-variables-generated-by-argument-clinic">How to rename C functions and variables generated by Argument Clinic</a></li>
- <li><a class="reference internal" href="#how-to-convert-functions-using-pyarg-unpacktuple">How to convert functions using <code class="docutils literal notranslate"><span class="pre">PyArg_UnpackTuple</span></code></a></li>
- <li><a class="reference internal" href="#how-to-use-optional-groups">How to use optional groups</a></li>
- <li><a class="reference internal" href="#how-to-use-real-argument-clinic-converters-instead-of-legacy-converters">How to use real Argument Clinic converters, instead of “legacy converters”</a></li>
- <li><a class="reference internal" href="#how-to-use-the-py-buffer-converter">How to use the <code class="docutils literal notranslate"><span class="pre">Py_buffer</span></code> converter</a></li>
- <li><a class="reference internal" href="#how-to-use-advanced-converters">How to use advanced converters</a></li>
- <li><a class="reference internal" href="#how-to-assign-default-values-to-parameter">How to assign default values to parameter</a><ul>
- <li><a class="reference internal" href="#the-null-default-value">The <code class="docutils literal notranslate"><span class="pre">NULL</span></code> default value</a></li>
- <li><a class="reference internal" href="#symbolic-default-values">Symbolic default values</a></li>
- <li><a class="reference internal" href="#expressions-as-default-values">Expressions as default values</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#how-to-use-return-converters">How to use return converters</a></li>
- <li><a class="reference internal" href="#how-to-clone-existing-functions">How to clone existing functions</a></li>
- <li><a class="reference internal" href="#how-to-call-python-code">How to call Python code</a></li>
- <li><a class="reference internal" href="#how-to-use-the-self-converter">How to use the “self converter”</a></li>
- <li><a class="reference internal" href="#how-to-use-the-defining-class-converter">How to use the “defining class” converter</a></li>
- <li><a class="reference internal" href="#how-to-write-a-custom-converter">How to write a custom converter</a></li>
- <li><a class="reference internal" href="#how-to-write-a-custom-return-converter">How to write a custom return converter</a></li>
- <li><a class="reference internal" href="#how-to-convert-meth-o-and-meth-noargs-functions">How to convert <code class="docutils literal notranslate"><span class="pre">METH_O</span></code> and <code class="docutils literal notranslate"><span class="pre">METH_NOARGS</span></code> functions</a></li>
- <li><a class="reference internal" href="#how-to-convert-tp-new-and-tp-init-functions">How to convert <code class="docutils literal notranslate"><span class="pre">tp_new</span></code> and <code class="docutils literal notranslate"><span class="pre">tp_init</span></code> functions</a></li>
- <li><a class="reference internal" href="#how-to-change-and-redirect-clinic-s-output">How to change and redirect Clinic’s output</a></li>
- <li><a class="reference internal" href="#how-to-use-the-ifdef-trick">How to use the <code class="docutils literal notranslate"><span class="pre">#ifdef</span></code> trick</a></li>
- <li><a class="reference internal" href="#how-to-use-argument-clinic-in-python-files">How to use Argument Clinic in Python files</a></li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- </div>
- <div>
- <h4>Previous topic</h4>
- <p class="topless"><a href="ipaddress.html"
- title="previous chapter">An introduction to the ipaddress module</a></p>
- </div>
- <div>
- <h4>Next topic</h4>
- <p class="topless"><a href="instrumentation.html"
- title="next chapter">Instrumenting CPython with DTrace and SystemTap</a></p>
- </div>
- <div role="note" aria-label="source link">
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../bugs.html">Report a Bug</a></li>
- <li>
- <a href="https://github.com/python/cpython/blob/main/Doc/howto/clinic.rst"
- rel="nofollow">Show Source
- </a>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="clearer"></div>
- </div>
- <div class="related" role="navigation" aria-label="related navigation">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- >index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="instrumentation.html" title="Instrumenting CPython with DTrace and SystemTap"
- >next</a> |</li>
- <li class="right" >
- <a href="ipaddress.html" title="An introduction to the ipaddress module"
- >previous</a> |</li>
- <li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
- <li><a href="https://www.python.org/">Python</a> »</li>
- <li class="switchers">
- <div class="language_switcher_placeholder"></div>
- <div class="version_switcher_placeholder"></div>
- </li>
- <li>
-
- </li>
- <li id="cpython-language-and-version">
- <a href="../index.html">3.12.0 Documentation</a> »
- </li>
- <li class="nav-item nav-item-1"><a href="index.html" >Python HOWTOs</a> »</li>
- <li class="nav-item nav-item-this"><a href="">Argument Clinic How-To</a></li>
- <li class="right">
-
- <div class="inline-search" role="search">
- <form class="inline-search" action="../search.html" method="get">
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
- <input type="submit" value="Go" />
- </form>
- </div>
- |
- </li>
- <li class="right">
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label> |</li>
-
- </ul>
- </div>
- <div class="footer">
- © <a href="../copyright.html">Copyright</a> 2001-2023, Python Software Foundation.
- <br />
- This page is licensed under the Python Software Foundation License Version 2.
- <br />
- Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
- <br />
- See <a href="/license.html">History and License</a> for more information.<br />
- <br />
- The Python Software Foundation is a non-profit corporation.
- <a href="https://www.python.org/psf/donations/">Please donate.</a>
- <br />
- <br />
- Last updated on Oct 02, 2023.
- <a href="/bugs.html">Found a bug</a>?
- <br />
- Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 4.5.0.
- </div>
- </body>
- </html>
|