@@ -561,8 +561,8 @@ in ``Lib/inspect.py``.
561
561
to allow full expressions like ``CONSTANT - 1 ``.)
562
562
563
563
564
- Renaming the C functions generated by Argument Clinic
565
- -----------------------------------------------------
564
+ Renaming the C functions and variables generated by Argument Clinic
565
+ -------------------------------------------------------------------
566
566
567
567
Argument Clinic automatically names the functions it generates for you.
568
568
Occasionally this may cause a problem, if the generated name collides with
@@ -584,6 +584,25 @@ The base function would now be named ``pickler_dumper()``,
584
584
and the impl function would now be named ``pickler_dumper_impl() ``.
585
585
586
586
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
+
587
606
588
607
Converting functions using PyArg_UnpackTuple
589
608
--------------------------------------------
@@ -1308,74 +1327,6 @@ them ``__new__`` or ``__init__`` as appropriate. Notes:
1308
1327
(If your function doesn't support keywords, the parsing function
1309
1328
generated will throw an exception if it receives any.)
1310
1329
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
-
1379
1330
Changing and redirecting Clinic's output
1380
1331
----------------------------------------
1381
1332
@@ -1491,8 +1442,9 @@ previous configuration.
1491
1442
``output preset `` sets Clinic's output to one of several built-in
1492
1443
preset configurations, as follows:
1493
1444
1494
- ``original ``
1495
- Clinic's starting configuration.
1445
+ ``block ``
1446
+ Clinic's original starting configuration. Writes everything
1447
+ immediately after the input block.
1496
1448
1497
1449
Suppress the ``parser_prototype ``
1498
1450
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
1640
1592
the file was not modified by hand before it gets overwritten.
1641
1593
1642
1594
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
+
1643
1671
Using Argument Clinic in Python files
1644
1672
-------------------------------------
1645
1673
0 commit comments