@@ -561,8 +561,8 @@ in ``Lib/inspect.py``.
561561to allow full expressions like ``CONSTANT - 1 ``.)
562562
563563
564- Renaming the C functions generated by Argument Clinic
565- -----------------------------------------------------
564+ Renaming the C functions and variables generated by Argument Clinic
565+ -------------------------------------------------------------------
566566
567567Argument Clinic automatically names the functions it generates for you.
568568Occasionally this may cause a problem, if the generated name collides with
@@ -584,6 +584,25 @@ The base function would now be named ``pickler_dumper()``,
584584and the impl function would now be named ``pickler_dumper_impl() ``.
585585
586586
587+ Similarly, you may have a problem where you want to give a parameter
588+ a specific Python name, but that name may be inconvenient in C. Argument
589+ Clinic allows you to give a parameter different names in Python and in C,
590+ using the same ``"as" `` syntax::
591+
592+ /*[clinic input]
593+ pickle.Pickler.dump
594+
595+ obj: object
596+ file as file_obj: object
597+ protocol: object = NULL
598+ *
599+ fix_imports: bool = True
600+
601+ Here, the name used in Python (in the signature and the ``keywords ``
602+ array) would be ``file ``, but the C variable would be named ``file_obj ``.
603+
604+ You can use this to rename the ``self `` parameter too!
605+
587606
588607Converting functions using PyArg_UnpackTuple
589608--------------------------------------------
@@ -1308,74 +1327,6 @@ them ``__new__`` or ``__init__`` as appropriate. Notes:
13081327 (If your function doesn't support keywords, the parsing function
13091328 generated will throw an exception if it receives any.)
13101329
1311- The #ifdef trick
1312- ----------------------------------------------
1313-
1314- If you're converting a function that isn't available on all platforms,
1315- there's a trick you can use to make life a little easier. The existing
1316- code probably looks like this::
1317-
1318- #ifdef HAVE_FUNCTIONNAME
1319- static module_functionname(...)
1320- {
1321- ...
1322- }
1323- #endif /* HAVE_FUNCTIONNAME */
1324-
1325- And then in the ``PyMethodDef `` structure at the bottom you'll have::
1326-
1327- #ifdef HAVE_FUNCTIONNAME
1328- {'functionname', ... },
1329- #endif /* HAVE_FUNCTIONNAME */
1330-
1331- In this scenario, you should change the code to look like the following::
1332-
1333- #ifdef HAVE_FUNCTIONNAME
1334- /*[clinic input]
1335- module.functionname
1336- ...
1337- [clinic start generated code]*/
1338- static module_functionname(...)
1339- {
1340- ...
1341- }
1342- #endif /* HAVE_FUNCTIONNAME */
1343-
1344- Run Argument Clinic on the code in this state, then refresh the file in
1345- your editor. Now you'll have the generated code, including the #define
1346- for the ``PyMethodDef ``, like so::
1347-
1348- #ifdef HAVE_FUNCTIONNAME
1349- /*[clinic input]
1350- ...
1351- [clinic start generated code]*/
1352- ...
1353- #define MODULE_FUNCTIONNAME \
1354- {'functionname', ... },
1355- ...
1356- /*[clinic end generated code: checksum=...]*/
1357- static module_functionname(...)
1358- {
1359- ...
1360- }
1361- #endif /* HAVE_FUNCTIONNAME */
1362-
1363- Change the #endif at the bottom as follows::
1364-
1365- #else
1366- #define MODULE_FUNCTIONNAME
1367- #endif /* HAVE_FUNCTIONNAME */
1368-
1369- Now you can remove the #ifdefs around the ``PyMethodDef `` structure
1370- at the end, and replace those three lines with ``MODULE_FUNCTIONNAME ``.
1371- If the function is available, the macro turns into the ``PyMethodDef ``
1372- static value, including the trailing comma; if the function isn't
1373- available, the macro turns into nothing. Perfect!
1374-
1375- (This is the preferred approach for optional functions; in the future,
1376- Argument Clinic may generate the entire ``PyMethodDef `` structure.)
1377-
1378-
13791330Changing and redirecting Clinic's output
13801331----------------------------------------
13811332
@@ -1491,8 +1442,9 @@ previous configuration.
14911442``output preset `` sets Clinic's output to one of several built-in
14921443preset configurations, as follows:
14931444
1494- ``original ``
1495- Clinic's starting configuration.
1445+ ``block ``
1446+ Clinic's original starting configuration. Writes everything
1447+ immediately after the input block.
14961448
14971449 Suppress the ``parser_prototype ``
14981450 and ``docstring_prototype ``, write everything else to ``block ``.
@@ -1640,6 +1592,82 @@ it in a Clinic block lets Clinic use its existing checksum functionality to ensu
16401592the file was not modified by hand before it gets overwritten.
16411593
16421594
1595+ The #ifdef trick
1596+ ----------------------------------------------
1597+
1598+ If you're converting a function that isn't available on all platforms,
1599+ there's a trick you can use to make life a little easier. The existing
1600+ code probably looks like this::
1601+
1602+ #ifdef HAVE_FUNCTIONNAME
1603+ static module_functionname(...)
1604+ {
1605+ ...
1606+ }
1607+ #endif /* HAVE_FUNCTIONNAME */
1608+
1609+ And then in the ``PyMethodDef `` structure at the bottom the existing code
1610+ will have::
1611+
1612+ #ifdef HAVE_FUNCTIONNAME
1613+ {'functionname', ... },
1614+ #endif /* HAVE_FUNCTIONNAME */
1615+
1616+ In this scenario, you should enclose the body of your impl function inside the ``#ifdef ``,
1617+ like so::
1618+
1619+ #ifdef HAVE_FUNCTIONNAME
1620+ /*[clinic input]
1621+ module.functionname
1622+ ...
1623+ [clinic start generated code]*/
1624+ static module_functionname(...)
1625+ {
1626+ ...
1627+ }
1628+ #endif /* HAVE_FUNCTIONNAME */
1629+
1630+ Then, remove those three lines from the ``PyMethodDef `` structure,
1631+ replacing them with the macro Argument Clinic generated::
1632+
1633+ MODULE_FUNCTIONNAME_METHODDEF
1634+
1635+ (You can find the real name for this macro inside the generated code.
1636+ Or you can calculate it yourself: it's the name of your function as defined
1637+ on the first line of your block, but with periods changed to underscores,
1638+ uppercased, and ``"_METHODDEF" `` added to the end.)
1639+
1640+ Perhaps you're wondering: what if ``HAVE_FUNCTIONNAME `` isn't defined?
1641+ The ``MODULE_FUNCTIONNAME_METHODDEF `` macro won't be defined either!
1642+
1643+ Here's where Argument Clinic gets very clever. It actually detects that the
1644+ Argument Clinic block might be deactivated by the ``#ifdef ``. When that
1645+ happens, it generates a little extra code that looks like this::
1646+
1647+ #ifndef MODULE_FUNCTIONNAME_METHODDEF
1648+ #define MODULE_FUNCTIONNAME_METHODDEF
1649+ #endif /* !defined(MODULE_FUNCTIONNAME_METHODDEF) */
1650+
1651+ That means the macro always works. If the function is defined, this turns
1652+ into the correct structure, including the trailing comma. If the function is
1653+ undefined, this turns into nothing.
1654+
1655+ However, this causes one ticklish problem: where should Argument Clinic put this
1656+ extra code when using the "block" output preset? It can't go in the output block,
1657+ because that could be decativated by the ``#ifdef ``. (That's the whole point!)
1658+
1659+ In this situation, Argument Clinic writes the extra code to the "buffer" destination.
1660+ This may mean that you get a complaint from Argument Clinic::
1661+
1662+ Warning in file "Modules/posixmodule.c" on line 12357:
1663+ Destination buffer 'buffer' not empty at end of file, emptying.
1664+
1665+ When this happens, just open your file, find the ``dump buffer `` block that
1666+ Argument Clinic added to your file (it'll be at the very bottom), then
1667+ move it above the ``PyMethodDef `` structure where that macro is used.
1668+
1669+
1670+
16431671Using Argument Clinic in Python files
16441672-------------------------------------
16451673
0 commit comments