Description
Feature or enhancement
Currently, AC will generate both the parser and the corresponding impl method with static scope. This is also what is desired most of the time, and it fits the general use-case in the CPython code base. Suggesting to add the possibility of generating extern
parsers with the following syntax:
[extern] modulename.fnname [as c_basename] [-> return annotation]
If the line starts with the optional extern
keyword, extern
is used instead of static
when generating the parser code.
Pitch
In the sqlite3 extension module, the code is split between several files. Module level functions are found in Modules/_sqlite/module.c
, the connection object and its method in Modules/_sqlite/connection.c
, etc. The sqlite3.connect()
function and the sqlite3.Connection.__init__()
method have identical signatures, and the former is implicitly relayed to the latter. Currently, this is very inconvenient:
- the signatures must be equal, and I cannot use the "clone" feature of AC:
- cloning can only be performed within a single file
- AC cannot clone a module level function to a class method, or the other way around
- I cannot reuse custom converters conveniently, since not everything is in one file
- it is not possible to move the connection method to module.c and vice versa:
- the generated code is file local (static)
- (until recently) is was impossible to redirect AC output to a custom file (fixed in gh-94538: Fix Argument Clinic output to custom file destinations #94539)
- relaying the call from
sqlite3.connect()
tosqlite3.Connection.__init__()
is currently very clumsy (take a look); having both in the same file, will make things a lot easier in a lot of ways, not to mention the call itself
If it was possible to generate extern
parsers, I could move sqlite3.connect()
from module.c to connection.c, redirect the methoddef, doc, and parser declarations to a header file for inclusion in module.c, and include the rest of the generated output in connection.c. I could then easily reuse the custom converter (that currently lives in connection.c), and the relay call would be a simple C function call (not a PyObject_Call*
).
If I were to add a keyword-only parameter to sqlite3.connect
, the relay call will be even more clumsy (and slow). I'm planning to add a keyword-only parameter in #93823. With this change, adding a keyword-only parameter will be trivial.
Other solutions
Another possibility is of course to remove AC from sqlite3.connect()
, manually copy the docstring, and just use PyObject_Call(factory, args, kwds)
to relay the call. I'd still have to parse the incoming args/kwds in order to fetch the factory function thought, so this option is also pretty clumsy.