-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make optional parameters of sqlite3.connect() keyword-only #93057
Comments
Can we enhance AC with such functionality first? |
It would be not easy. 😫 |
That I assumed 🙂 Do you have a coarse outline in mind of how such a change could be implemented? |
Continuing the AC digression :) I introduced a new special symbol, Example AC code: /*[clinic input]
_sqlite3.connect as pysqlite_connect
database: object
timeout: double = 5.0
detect_types: int = 0
isolation_level: object = NULL
check_same_thread: bool(accept={int}) = True
factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType
x
cached_statements: int = 128
uri: bool = False
Opens a connection to the SQLite database file database.
You can use ":memory:" to open a database connection to a database that resides
in RAM instead of on disk.
[clinic start generated code]*/ |
I suggest we make all but the database argument keyword-only. If my AC hack is a possible way forward1, we can do this in 3.12. Also, the database argument should be positional-only. Footnotes
|
Argument Clinic now has support for deprecating positional use of positional-or-keyword parameters. However, there are still some prerequisites that must be in place before we can continue with this issue:
This is roughly what the relevant parts of Modules/_sqlite/connection.c will look like: /*[clinic input]
sqlite3.Connection.__init__ as pysqlite_connection_init
database: object
* [from 3.15]
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]*/
static int
pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database,
double timeout, int detect_types,
const char *isolation_level,
int check_same_thread, PyObject *factory,
int cache_size, int uri,
enum autocommit_mode autocommit)
/*[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 suppress
output docstring_definition connect
output 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]*/ Then, in Modules/_sqlite/module.c: #include "clinic/_sqlite3.connect.c.h"
static PyObject *
pysqlite_connect(PyObject *module, PyObject *const *args, Py_ssize_t nargsf,
PyObject *kwnames)
{
// ...
}
// ... and then:
static PyMethodDef module_methods[] = {
PYSQLITE_ADAPT_METHODDEF
PYSQLITE_COMPLETE_STATEMENT_METHODDEF
PYSQLITE_CONNECT_METHODDEF // <= this now comes from clinic/_sqlite3.connect.c.h
PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF
PYSQLITE_REGISTER_ADAPTER_METHODDEF
PYSQLITE_REGISTER_CONVERTER_METHODDEF
{NULL, NULL}
}; |
…les/_sqlite/connection.c This change has no impact on behaviour. It is needed only for Argument Clinic to produce nicer deprecation messages when we get to deprecate positional use of optional parameters to sqlite3.connect().
Thanks for suggesting this feature and helping land it (and all its implications in Argument Clinic), @serhiy-storchaka. Very helpful, and a good learning experience. |
For the record, it was the Argument Clinic implications of this feature that spawned the desire to add typing to clinic.py (#104050), which in turn got both @AlexWaygood and me highly involved with Argument Clinic. We've now ended up in a position where more core devs have better knowledge of the inner workings of clinic.py; this is a good thing. Thanks, again! |
If this is desired, we should create a new issue for it. cc. @serhiy-storchaka |
sqlite3.connect()
has a large number of parameters: 1 required and 7 optional. It is much more convenient to pass optional arguments by keyword, because you can pass only values which differs from default. And if you pass positional arguments, it is easy to make an error and pass value as wrong argument.It is recommended to make optional rarely used arguments keyword-only. I do not think it will break much code, but we need a deprecation period for this.
The problem is that
sqlite3.connect()
was converted to Argument Clinic, and it was much easier to add deprecation warning in the old code.Linked PRs
The text was updated successfully, but these errors were encountered: