A cursor exposed its description tuple before filling in all the columns, so an allocation failure or a reader on a free-threaded build could encounter an unset tuple entry. An allocation failure could also clear lastrowid and crash the next execute. Build new metadata before replacing the old values and synchronize reads and writes. Keep a strong reference to each row or text factory while it is called so replacing the factory during a fetch cannot destroy an active callable.
When a SQL parameter sequence is an exact list, sqlite3 retrieved an element as a borrowed reference before taking ownership. On free-threaded builds another thread can replace it in between, so binding can use a freed object and crash. Fetch a strong reference atomically. Backport to 3.15 and 3.14.
* gh-157407: Use _PyUnicode_AsUTF8NoNUL for AC 's' and 'z' converters
The code was doing the same as the helper added in GH-111957 but inline.
That resulted in significantly more `.text` for most functions. Refactor
the Arguemnt Clinic converters code to deduplicate a bit while keeping
generated code close to original.
On my Linux x64 box this reduces `.text` by ~6200 bytes in a clang
release build (no PGO or LTO). Performance is flat.
The helper was already exported for `_sqlite3`, update the comment that
it is used in AC generated code as well.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Update Include/internal/pycore_unicodeobject.h
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
* Remove NEWS, add period
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
Add constants sqlite3.SQLITE_VERSION and sqlite3.SQLITE_VERSION_INFO
which provide information about the version of the SQLite library that
was used for building the module.
Make sqlite3.sqlite_version_info a named tuple.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* gh-136681: Drop _PyArg_Parser for positional-only defining-class methods
A method that takes a defining class and whose other parameters are all
positional-only (e.g. decimal.Decimal.from_float) was routed through
Argument Clinic's generic keyword path: it emitted a static _PyArg_Parser,
an (empty) keyword tuple and an _PyArg_UnpackKeywords() call, even though
it accepts no keyword arguments.
Such methods now go through parse_pos_only(): the wrapper still uses the
mandatory METH_METHOD|METH_FASTCALL|METH_KEYWORDS convention (the only one
that delivers the defining class), but it rejects keywords with
_PyArg_NoKwnames() and reads positional arguments directly, with no
parser, keyword tuple or argsbuf.
This converts 135 methods across 19 clinic headers, removing the static
_PyArg_Parser, the keyword arrays/tuples and the per-call
_PyArg_UnpackKeywords() + parser_init() overhead for each.
_PyArg_NoKwnames() is now exported (PyAPI_FUNC) so generated code in
shared extension modules can use it, like _PyArg_NoKeywords().
Error messages for these methods now match ordinary positional-only
functions ("expected ... arguments" / "takes no keyword arguments"
instead of the _PyArg_UnpackKeywords phrasing); affected stdlib tests
are updated accordingly.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* gh-157407: Rename NEWS entry to the correct issue number
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The value of a @setter is now a parameter, which can use a converter,
and a @getter can define a return converter. Declaring the value is
optional.
The accessors of an attribute are now collected in a Property, so the
entry of PyGetSetDef is identified by the Python name instead of the C
basename, and is composed without the help of the preprocessor unless
some accessor is compiled conditionally.
Replace soft deprecated PyBytes_FromStringAndSize() with
PyBytesWriter.
Replace also PyBytes_FromStringAndSize(NULL, 0) with
Py_GetConstant(Py_CONSTANT_EMPTY_BYTES) in other functions.
Replace also PyBytes_FromStringAndSize(NULL, 0) with
PyBytes_FromStringAndSize("", 0) in _Py_GetConstant_Init().
Fix generating an accessor in a preprocessor conditional block.
Reject the accessors of the same attribute with different C basenames and
the same accessor defined twice.
Reject deletion of the attribute, which crashed the setter, unless the new
directive @deleter is applied to it.
Reading or writing a slice with a negative step computed a negative length
for sqlite3_blob_read() and sqlite3_blob_write(), so it failed instead of
returning or storing the selected bytes.
Compute the contiguous region which covers all selected bytes, and index it
with a size_t cursor, so that a step of any sign and magnitude works.
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
It patched the bytes object read from the blob, which for a single byte
is an immortal singleton, so that the value of that byte was changed in
the whole process.
Rename from _Py_INTERNAL_ABI_SLOT to _Py_ABI_SLOT
and define the macro using _PyABIInfo_DEFAULT.
Use the ABI slot in stdlib extension modules to enable running
a check of ABI version compatibility.
_tkinter, _tracemalloc and readline don't use the slots, hence they need
explicit handling.
Co-authored-by: Victor Stinner <vstinner@python.org>
Passing a negative or zero size to `cursor.fetchmany()` made it fetch all rows
instead of none.
While this could be considered a security vulnerability, it was decided to treat
this issue as a regular bug as passing a non-sanitized *size* value in the first
place is not recommended.
* All parameters of sqlite3.connect() except "database" are now keyword-only.
* The first three parameters of methods create_function() and
create_aggregate() are now positional-only.
* The first parameter of methods set_authorizer(), set_progress_handler()
and set_trace_callback() is now positional-only.
Add a helper for raising DB-API compatible exceptions based on the
result code of SQLite C APIs. Some APIs do not store the error indicator
on the database pointer, so we need to be able to deduce the DB-API
compatible exception directly from the error code.
- rename _pysqlite_seterror() as set_error_from_db()
- introduce set_error_from_code()