Skip to content

Commit

Permalink
Use intersphinx wherever possible
Browse files Browse the repository at this point in the history
  • Loading branch information
rogerbinns committed Dec 3, 2024
1 parent 5acd359 commit b913d32
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 117 deletions.
37 changes: 17 additions & 20 deletions apsw/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -244,26 +244,25 @@ def fork_checker() -> None:
other's work and interfere with each other's locks.)
One example of how you may end up using fork is if you use the
`multiprocessing module
<https://docs.python.org/3/library/multiprocessing.html>`__ which can use
:mod:`multiprocessing module <multiprocessing>` which can use
fork to make child processes.
If you do use fork or multiprocessing on a platform that supports
fork then you **must** ensure database connections and their objects
If you do use fork or multiprocessing on a platform that supports fork
then you **must** ensure database connections and their objects
(cursors, backup, blobs etc) are not used in the parent process, or
are all closed before calling fork or starting a `Process
<https://docs.python.org/3/library/multiprocessing.html#process-and-exceptions>`__.
(Note you must call close to ensure the underlying SQLite objects
are closed. It is also a good idea to call `gc.collect(2)
<https://docs.python.org/3/library/gc.html#gc.collect>`__ to ensure
anything you may have missed is also deallocated.)
(Note you must call close to ensure the underlying SQLite objects are
closed. It is also a good idea to call :func:`gc.collect(2)
<gc.collect>` to ensure anything you may have missed is also
deallocated.)
Once you run this method, extra checking code is inserted into
SQLite's mutex operations (at a very small performance penalty) that
verifies objects are not used across processes. You will get a
:exc:`ForkingViolationError` if you do so. Note that due to the way
Python's internals work, the exception will be delivered to
`sys.excepthook` in addition to the normal exception mechanisms and
:func:`sys.excepthook` in addition to the normal exception mechanisms and
may be reported by Python after the line where the issue actually
arose. (Destructors of objects you didn't close also run between
lines.)
Expand Down Expand Up @@ -483,8 +482,7 @@ def vfs_details() -> list[dict[str, int | str]]:
<https://sqlite.org/c3ref/vfs.html>`__ data structure, and their
corresponding values.
Pointers are converted using `PyLong_FromVoidPtr
<https://docs.python.org/3/c-api/long.html?highlight=voidptr#c.PyLong_FromVoidPtr>`__.
Pointers are converted using :c:func:`PyLong_FromVoidPtr`.
Calls: `sqlite3_vfs_find <https://sqlite.org/c3ref/vfs_find.html>`__"""
...
Expand Down Expand Up @@ -1283,8 +1281,7 @@ class Connection:
<https://sqlite.org/c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntldataversion>`__.
If you want data returned back then the *pointer* needs to point to
something mutable. Here is an example using `ctypes
<https://docs.python.org/3/library/ctypes.html>`_ of
something mutable. Here is an example using :mod:`ctypes` of
passing a Python dictionary to :meth:`~VFSFile.xFileControl` which
can then modify the dictionary to set return values::
Expand Down Expand Up @@ -2938,8 +2935,8 @@ class VTCursor(Protocol):
""".. note::
There is no actual *VTCursor* class - it is shown this way for
documentation convenience and is present as a `typing protocol
<https://docs.python.org/3/library/typing.html#typing.Protocol>`__.
documentation convenience and is present as a :class:`typing protocol
<typing.Protocol>`.
The :class:`VTCursor` object is used for iterating over a table.
Expand Down Expand Up @@ -3022,8 +3019,8 @@ class VTModule(Protocol):
""".. note::
There is no actual *VTModule* class - it is shown this way for
documentation convenience and is present as a `typing protocol
<https://docs.python.org/3/library/typing.html#typing.Protocol>`__.
documentation convenience and is present as a :class:`typing protocol
<typing.Protocol>`.
A module instance is used to create the virtual tables. Once you have
a module object, you register it with a connection by calling
Expand Down Expand Up @@ -3097,8 +3094,8 @@ class VTTable(Protocol):
""".. note::
There is no actual *VTTable* class - it is shown this way for
documentation convenience and is present as a `typing protocol
<https://docs.python.org/3/library/typing.html#typing.Protocol>`__.
documentation convenience and is present as a :class:`typing protocol
<typing.Protocol>`.
The :class:`VTTable` object contains knowledge of the indices, makes
cursors and can perform transactions.
Expand Down Expand Up @@ -4635,7 +4632,7 @@ class InternalError(Error):
longer used) Internal logic error in SQLite."""

class InterruptError(Error):
"""SQLITE_INTERRUPT <https://sqlite.org/rescode.html#interrupt>`__.
"""`SQLITE_INTERRUPT <https://sqlite.org/rescode.html#interrupt>`__.
Operation terminated by `sqlite3_interrupt
<https://sqlite.org/c3ref/interrupt.html>`_ - use
:meth:`Connection.interrupt`."""
Expand Down
2 changes: 1 addition & 1 deletion apsw/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def get_dataclass(self, description: tuple[tuple[str, str], ...]) -> tuple[Any,
return make_dataclass(f"{ self.__class__.__name__ }{ suffix }", zip(names, types), **kwargs), tuple(names)

def get_type(self, t: str | None) -> Any:
"""Returns the `type hint <https://docs.python.org/3/library/typing.html>`__ to use in the dataclass based on the type in the :meth:`description <apsw.Cursor.get_description>`
"""Returns the :mod:`type hint <typing>` to use in the dataclass based on the type in the :meth:`description <apsw.Cursor.get_description>`
`SQLite's affinity rules <https://www.sqlite.org/datatype3.html#affname>`__ are followed.
Expand Down
4 changes: 2 additions & 2 deletions apsw/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class Shell:
:param stderr: Where to send errors (default sys.stderr)
:param encoding: Default encoding for files opened/created by the
Shell. If you want stdin/out/err to use a particular encoding
then you need to provide them `already configured
<https://docs.python.org/3/library/codecs.html#codecs.open>`__ that way.
then you need to provide them :func:`already configured
<codecs.open>` that way.
:param args: This should be program arguments only (ie if
passing in sys.argv do not include sys.argv[0] which is the
program name. You can also pass in None and then call
Expand Down
10 changes: 6 additions & 4 deletions doc/about.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
About
=====

**APSW** |version| **released** |today|
**APSW** |version| **released** |today|.

Use with `SQLite <https://sqlite.org/>`__ 3.47.1 or later, `Python
<https://www.python.org/downloads/>`__ 3.9 and later.

APSW has been under continuous development since 2004.

What APSW does
--------------
Expand All @@ -28,8 +29,9 @@ APSW and sqlite3 <pysqlite>`.
Dependencies
------------

APSW has no dependencies other than Python itself, and SQLite which
you can provide or have APSW fetch and include statically in the
APSW has no dependencies other than Python itself, and SQLite which is
included in PyPI releases. When doing your own builds, you can
provide SQLite, or have APSW fetch it and include it statically in the
extension.

Hosting
Expand Down Expand Up @@ -80,7 +82,7 @@ compatibility with the `file format

APSW wraps the `SQLite C API
<https://www.sqlite.org/c3ref/intro.html>`__. That means when SQLite
adds new constant or API, then so does APSW. You can think of APSW as
adds new constants or APIs, then so does APSW. You can think of APSW as
the Python expression of SQLite's C API. You can `lookup
<genindex.html#S>`__ SQLite APIs to find which APSW functions and
attributes call them.
Expand Down
58 changes: 24 additions & 34 deletions doc/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,8 @@ passing and receiving positional and keyword arguments. (:issue:`477`,
:issue:`446`):

* Conversion of arguments from Python values to C values drops generic
`PyArg_ParseTupleAndKeywords
<https://docs.python.org/3/c-api/arg.html#c.PyArg_ParseTupleAndKeywords>`__
in favour of direct processing which is more efficient and allows
better exception messages.
:c:func:`PyArg_ParseTupleAndKeywords` in favour of direct processing
which is more efficient and allows better exception messages.

* Running :ref:`speedtest` with a VFS that inherits all methods went
from being 17% slower than pure SQLite to 2% slower.
Expand Down Expand Up @@ -338,9 +336,8 @@ Ensure that all applicable options are implemented for

Added :func:`apsw.sleep` (:issue:`419`)

Strings for :meth:`apsw.VFS.xNextSystemCall` are `interned
<https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_InternInPlace>`__
avoiding memory leaks. (:issue:`430`)
Strings for :meth:`apsw.VFS.xNextSystemCall` are :c:func:`interned
<PyUnicode_InternInPlace>` avoiding memory leaks. (:issue:`430`)

Detect unbound recursion not handled by CPython, and handle better.
(:issue:`425`)
Expand Down Expand Up @@ -440,13 +437,11 @@ Ensure all SQLite APIs are wrapped. :attr:`Connection.system_errno`,
:meth:`apsw.hard_heap_limit`. :meth:`Connection.drop_modules`
(:issue:`382`)

When an :ref:`unraisable exception <unraisable>` happens,
`sqlite3_log <https://www.sqlite.org/c3ref/log.html>`__ is now called
so you will have context within SQLite's actions. `sys.unraisablehook
<https://docs.python.org/3/library/sys.html#sys.unraisablehook>`__ is
now called first, and if it doesn't exist then `sys.excepthook
<https://docs.python.org/3/library/sys.html#sys.excepthook>`__ as
before. (:issue:`385`)
When an :ref:`unraisable exception <unraisable>` happens, `sqlite3_log
<https://www.sqlite.org/c3ref/log.html>`__ is now called so you will
have context within SQLite's actions. :func:`sys.unraisablehook` is
now called first, and if it doesn't exist then :func:`sys.excepthook`
as before. (:issue:`385`)

When the wrong type is given for a function argument, the error
message now includes the parameter name and function signature.
Expand All @@ -456,8 +451,7 @@ Let SQLite do size checking instead of APSW for strings and blobs.
(:issue:`387`)

Added :meth:`apsw.ext.log_sqlite` which installs a handler that
forwards SQLite messages to the `logging module
<https://docs.python.org/3/library/logging.html>`__.
forwards SQLite messages to the :mod:`logging module <logging>`.

Added :meth:`set_default_vfs` and :meth:`unregister_vfs` taking vfs
names. The test suite also unregisters `ZipVFS
Expand All @@ -481,9 +475,8 @@ setters, including :attr:`Connection.in_transaction`,

Completed: To the extent permitted by CPython APIs every item has the
same docstring as this documentation. Every API can use named
parameters. The `type stubs
<https://github.com/rogerbinns/apsw/blob/master/apsw/__init__.pyi>`__
cover everything including constants. The type stubs also include
parameters. The :source:`type stubs <apsw/__init__.pyi>` cover
everything including constants. The type stubs also include
documentation for everything, which for example Visual Studio Code
displays as you type or hover. There is a single source of
documentation in the source code, which is then automatically
Expand Down Expand Up @@ -1697,8 +1690,7 @@ it will be automatically included and *async_initialize* called.
A :meth:`fork_checker` is available which turns on detection when you
have used SQLite objects across a fork (a **very** bad thing). This
is possible on Unix like operating systems, especially if you use the
`multiprocessing module
<https://docs.python.org/3/library/multiprocessing.html>`__.
:mod:`multiprocessing module <multiprocessing>`.

Extension loading is now compiled in by default when using the
amalgamation and compiled out when using existing libraries. This is
Expand Down Expand Up @@ -1889,8 +1881,7 @@ compatible with XP. Thanks to Rudolf Gaertner for assistance in
detecting and diagnosing this issue.

:class:`Connections <Connection>`, :class:`cursors <Cursor>` and
:class:`blobs <Blob>` can be used by `weak references
<https://docs.python.org/3/library/weakref.html>`_.
:class:`blobs <Blob>` can be used by :mod:`weak references <weakref>`.

You can now install :class:`Connection` wide :meth:`execution
<Connection.set_exec_trace>` and :meth:`row <Connection.set_row_trace>`
Expand Down Expand Up @@ -2160,14 +2151,13 @@ necessary.

All strings are returned as unicode.

`PyErr_WriteUnraisable
<https://docs.python.org/3/c-api/exceptions.html?highlight=pyerr_writeunraisable#c.PyErr_WriteUnraisable>`__
was used for errors in destructors. Unfortunately it is almost
completely useless, merely printing *str* of the object and exception.
This doesn't help in finding where in your code the issue arose so you
could fix it. An internal APSW implementation generates a traceback
and calls :func:`sys.excepthook`, the default implementation of which
prints the exception and the traceback to sys.stderr.
:c:func:`PyErr_WriteUnraisable` was used for errors in destructors.
Unfortunately it is almost completely useless, merely printing ``str``
of the object and exception. This doesn't help in finding where in
your code the issue arose so you could fix it. An internal APSW
implementation generates a traceback and calls :func:`sys.excepthook`,
the default implementation of which prints the exception and the
traceback to sys.stderr.

.. Note:: The line number reported in the traceback is often off by
1. This is because the destructors run "between" lines of
Expand Down Expand Up @@ -2215,9 +2205,9 @@ APSW had the following changes:
You can use this release against any release of SQLite 3 from 3.3.5
onwards. A bug was also fixed when reporting an error during the
cleanup of an aggregate function if there had also been an error in
the step function. (`PyErr_WriteUnraisable(NULL)
<https://docs.python.org/3/c-api/exceptions.html?highlight=pyerr_writeunraisable#c.PyErr_WriteUnraisable>`__
crashed on some versions of Python but not others.)
the step function. (:c:func:`PyErr_WriteUnraisable(NULL)
<PyErr_WriteUnraisable>` crashed on some versions of Python but not
others.)

SQLite added several functions for returning metadata about result
column sets. You have to compile SQLite with
Expand Down
4 changes: 1 addition & 3 deletions doc/dbapi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ as an iterator to get the results (if any).
it as an iterator to get the results (if any).

fetchone is not available. Use the cursor as an iterator, or call
Python's `next function
<https://docs.python.org/3/library/functions.html?highlight=next#next>`__
to get the next row.
Python's :func:`next function <next>` to get the next row.

fetchmany is not available. Use :meth:`~Cursor.fetchall` to get all
remaining results.
Expand Down
6 changes: 2 additions & 4 deletions doc/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ Unraisable
There are a few places where it is not possible for a Python exception
to be reported to SQLite as an error, and Python C code does not allow
destructors to report exceptions. These exceptions are reported via
`sys.unraisablehook
<https://docs.python.org/3/library/sys.html#sys.unraisablehook>`__,
and if that is not present then `sys.excepthook
<https://docs.python.org/3/library/sys.html#sys.excepthook>`__.
:func:`sys.unraisablehook`, and if that is not present then
:func:`sys.excepthook`.

`sqlite3_log <https://www.sqlite.org/c3ref/log.html>`__ is also called
so that you will have the context of when the exception happened
Expand Down
8 changes: 3 additions & 5 deletions doc/execution.rst
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,16 @@ This is sample output with the following options: **--sql**,
Each row starts with the following fields:

id
This is the `id
<https://docs.python.org/3/library/functions.html#id>`_ of the
This is the :func:`id` of the
:class:`Cursor` or :class:`Connection`. You can easily `filter
<https://en.wikipedia.org/wiki/Grep>`_ the log if you just want to
<https://en.wikipedia.org/wiki/Grep>`__ the log if you just want to
find out what happened on a specific cursor or connection.

timestamp
This is time since the program started in seconds

threadid
The unique `thread identifier
<https://docs.python.org/library/thread.html#thread.get_ident>`_
The unique :func:`thread identifier <threading.get_ident>`


The remainder of the line has one of the following forms:
Expand Down
11 changes: 5 additions & 6 deletions doc/pysqlite.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ sqlite3 module differences

.. currentmodule:: apsw

The `sqlite3 <https://docs.python.org/3/library/sqlite3.html>`__
standard module and APSW approached the problem of providing access
to SQLite from Python from fundamentally different directions.
The :mod:`sqlite3` standard module and APSW approached the problem of
providing access to SQLite from Python from fundamentally different
directions.

APSW provides access in whatever way is normal for SQLite. It makes
no effort to hide how SQLite is different from other databases. It
Expand Down Expand Up @@ -127,9 +127,8 @@ module:
* sqlite3 swallows exceptions in your callbacks making it far harder
to debug problems. That also prevents you from raising exceptions in
your callbacks to be handled in your code that called SQLite.
sqlite3 does let you turn on `printing of tracebacks
<https://docs.python.org/3/library/sqlite3.html?highlight=sqlite#sqlite3.enable_callback_tracebacks>`__
but that is a poor substitute.
sqlite3 does let you turn on :func:`printing of tracebacks
<sqlite3.enable_callback_tracebacks>` but that is a poor substitute.

APSW does the right thing as demonstrated by this example. APSW
converts Python errors into SQLite errors, so SQLite is aware errors
Expand Down
Loading

0 comments on commit b913d32

Please sign in to comment.