Skip to content

Argument Clinic: make it possible to clone __init__ functions#107880

@erlend-aasland

Description

@erlend-aasland

See #93057 (comment)

In sqlite3, both sqlite3.connect and sqlite3.Connection.__init__ have the same param spec. This has led to the far-from-optimal status quo:

// NB: This needs to be in sync with the Connection.__init__ docstring.
PyDoc_STRVAR(module_connect_doc,
"connect($module, /, database, timeout=5.0, detect_types=0,\n"
" isolation_level='', check_same_thread=True,\n"
" factory=ConnectionType, cached_statements=128, uri=False, *,\n"
" autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL)\n"
"--\n"
"\n"
"Opens a connection to the SQLite database file database.\n"
"\n"
"You can use \":memory:\" to open a database connection to a database that resides\n"
"in RAM instead of on disk.");
#definePYSQLITE_CONNECT_METHODDEF \
{"connect", _PyCFunction_CAST(module_connect), METH_FASTCALL|METH_KEYWORDS, module_connect_doc},
staticPyObject*
module_connect(PyObject*module, PyObject*const*args, Py_ssize_tnargsf,
PyObject*kwnames)

// NB: This needs to be in sync with the sqlite3.connect docstring
/*[clinic input]
_sqlite3.Connection.__init__ as pysqlite_connection_init
database: object
timeout: double = 5.0
detect_types: int = 0
isolation_level: IsolationLevel = ""
check_same_thread: bool = True
factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType
cached_statements as cache_size: int = 128
uri: bool = False
*
autocommit: Autocommit(c_default='LEGACY_TRANSACTION_CONTROL') = sqlite3.LEGACY_TRANSACTION_CONTROL
[clinic start generated code]*/
staticint
pysqlite_connection_init_impl(pysqlite_Connection*self, PyObject*database,
doubletimeout, intdetect_types,
constchar*isolation_level,
intcheck_same_thread, PyObject*factory,
intcache_size, inturi,
enumautocommit_modeautocommit)
/*[clinic end generated code: output=cba057313ea7712f input=9b0ab6c12f674fa3]*/
{

Instead, we want to be able to do this in connection.c:

/*[clinic input]sqlite3.Connection.__init__ as pysqlite_connection_init database: object timeout: double = 5.0 detect_types: int = 0 isolation_level: IsolationLevel = "" check_same_thread: bool = True factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType cached_statements as cache_size: int = 128 uri: bool = False * autocommit: Autocommit(c_default='LEGACY_TRANSACTION_CONTROL') = sqlite3.LEGACY_TRANSACTION_CONTROL[clinic start generated code]*/staticintpysqlite_connection_init_impl(pysqlite_Connection*self, PyObject*database, doubletimeout, intdetect_types, constchar*isolation_level, intcheck_same_thread, PyObject*factory, intcache_size, inturi, enumautocommit_modeautocommit) /*[clinic end generated code: output=cba057313ea7712f input=a0949fb85339104d]*/{// __init__ function is here; fast forward ... } /*[clinic input]# Save the clinic output config.output push# Create a new destination 'connect' for the docstring and methoddef only.destination connect new file '{dirname}/clinic/_sqlite3.connect.c.h'output everything suppressoutput docstring_definition connectoutput methoddef_define connect# Now, define the connect function.sqlite3.connect as pysqlite_connect = sqlite3.Connection.__init__[clinic start generated code]*//*[clinic end generated code: output=da39a3ee5e6b4b0d input=7913cd0b3bfc1b4a]*//*[clinic input]# Restore the clinic output config.output pop[clinic start generated code]*/

The methoddef and docstring for sqlite3.connect could then be included in module.c.

However, to achieve this, we need to teach Argument Clinic how to clone __init__ functions.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions