From 0e0b8f0a3a940ef11a70de5e2b7c4361beb6dc6c Mon Sep 17 00:00:00 2001 From: laggykiller Date: Thu, 29 Feb 2024 15:18:22 +0800 Subject: [PATCH] Add typing stubs --- sqlcipher3/__init__.pyi | 2 + sqlcipher3/dbapi2.pyi | 334 ++++++++++++++++++++++++++++++++++++++++ sqlcipher3/py.typed | 0 3 files changed, 336 insertions(+) create mode 100644 sqlcipher3/__init__.pyi create mode 100644 sqlcipher3/dbapi2.pyi create mode 100644 sqlcipher3/py.typed diff --git a/sqlcipher3/__init__.pyi b/sqlcipher3/__init__.pyi new file mode 100644 index 0000000..da46a55 --- /dev/null +++ b/sqlcipher3/__init__.pyi @@ -0,0 +1,2 @@ +# Adopted from https://github.com/python/typeshed +from sqlcipher3.dbapi2 import * \ No newline at end of file diff --git a/sqlcipher3/dbapi2.pyi b/sqlcipher3/dbapi2.pyi new file mode 100644 index 0000000..dae5a4f --- /dev/null +++ b/sqlcipher3/dbapi2.pyi @@ -0,0 +1,334 @@ +# Adopted from https://github.com/python/typeshed +from _typeshed import ReadableBuffer, StrOrBytesPath, SupportsLenAndGetItem, Unused +from collections.abc import Callable, Iterable, Iterator, Mapping +from datetime import date, datetime, time +from types import TracebackType +from typing import Any, Literal, Protocol, SupportsIndex, TypeVar, final, overload +from typing_extensions import Self, TypeAlias + +_T = TypeVar("_T") +_CursorT = TypeVar("_CursorT", bound=Cursor) +_SqliteData: TypeAlias = str | ReadableBuffer | int | float | None +# Data that is passed through adapters can be of any type accepted by an adapter. +_AdaptedInputData: TypeAlias = _SqliteData | Any +# The Mapping must really be a dict, but making it invariant is too annoying. +_Parameters: TypeAlias = SupportsLenAndGetItem[_AdaptedInputData] | Mapping[str, _AdaptedInputData] +_Adapter: TypeAlias = Callable[[_T], _SqliteData] +_Converter: TypeAlias = Callable[[bytes], Any] + +paramstyle: str +threadsafety: int +apilevel: str +Date = date +Time = time +Timestamp = datetime + +def DateFromTicks(ticks: float) -> Date: ... +def TimeFromTicks(ticks: float) -> Time: ... +def TimestampFromTicks(ticks: float) -> Timestamp: ... + +version_info: tuple[int, int, int] +sqlite_version_info: tuple[int, int, int] +Binary = memoryview + +# The remaining definitions are imported from _sqlite3. + +PARSE_COLNAMES: int +PARSE_DECLTYPES: int +SQLITE_ABORT: int +SQLITE_ALTER_TABLE: int +SQLITE_ANALYZE: int +SQLITE_ATTACH: int +SQLITE_AUTH: int +SQLITE_BUSY: int +SQLITE_CANTOPEN: int +SQLITE_CONSTRAINT: int +SQLITE_CORRUPT: int +SQLITE_CREATE_INDEX: int +SQLITE_CREATE_TABLE: int +SQLITE_CREATE_TEMP_INDEX: int +SQLITE_CREATE_TEMP_TABLE: int +SQLITE_CREATE_TEMP_TRIGGER: int +SQLITE_CREATE_TEMP_VIEW: int +SQLITE_CREATE_TRIGGER: int +SQLITE_CREATE_VIEW: int +SQLITE_CREATE_VTABLE: int +SQLITE_DELETE: int +SQLITE_DENY: int +SQLITE_DETACH: int +SQLITE_DONE: int +SQLITE_DROP_INDEX: int +SQLITE_DROP_TABLE: int +SQLITE_DROP_TEMP_INDEX: int +SQLITE_DROP_TEMP_TABLE: int +SQLITE_DROP_TEMP_TRIGGER: int +SQLITE_DROP_TEMP_VIEW: int +SQLITE_DROP_TRIGGER: int +SQLITE_DROP_VIEW: int +SQLITE_DROP_VTABLE: int +SQLITE_EMPTY: int +SQLITE_ERROR: int +SQLITE_FORMAT: int +SQLITE_FULL: int +SQLITE_FUNCTION: int +SQLITE_IGNORE: int +SQLITE_INSERT: int +SQLITE_INTERNAL: int +SQLITE_INTERRUPT: int +SQLITE_IOERR: int +SQLITE_LOCKED: int +SQLITE_MISMATCH: int +SQLITE_MISUSE: int +SQLITE_NOLFS: int +SQLITE_NOMEM: int +SQLITE_NOTADB: int +SQLITE_NOTFOUND: int +SQLITE_OK: int +SQLITE_OPEN_CREATE: int +SQLITE_OPEN_FULLMUTEX: int +SQLITE_OPEN_MEMORY: int +SQLITE_OPEN_NOMUTEX: int +SQLITE_OPEN_PRIVATECACHE: int +SQLITE_OPEN_READONLY: int +SQLITE_OPEN_READWRITE: int +SQLITE_OPEN_SHAREDCACHE: int +SQLITE_OPEN_URI: int +SQLITE_PERM: int +SQLITE_PRAGMA: int +SQLITE_PROTOCOL: int +SQLITE_RANGE: int +SQLITE_READ: int +SQLITE_READONLY: int +SQLITE_RECURSIVE: int +SQLITE_REINDEX: int +SQLITE_ROW: int +SQLITE_SAVEPOINT: int +SQLITE_SCHEMA: int +SQLITE_SELECT: int +SQLITE_TOOBIG: int +SQLITE_TRANSACTION: int +SQLITE_UPDATE: int +adapters: dict[tuple[type[Any], type[Any]], _Adapter[Any]] +converters: dict[str, _Converter] +sqlite_version: str +version: str + +# Can take or return anything depending on what's in the registry. +@overload +def adapt(__obj: Any, __proto: Any) -> Any: ... +@overload +def adapt(__obj: Any, __proto: Any, __alt: _T) -> Any | _T: ... +def complete_statement(statement: str) -> bool: ... + +def connect( + database: StrOrBytesPath, + timeout: float = ..., + detect_types: int = ..., + isolation_level: str | None = ..., + check_same_thread: bool = ..., + factory: type[Connection] | None = ..., + cached_statements: int = ..., + uri: bool = ..., + flags: int = ..., + vfs: str | None = ..., +) -> Connection: ... + +def enable_callback_tracebacks(flag: bool) -> None: ... + +# takes a pos-or-keyword argument because there is a C wrapper +def enable_shared_cache(do_enable: int) -> None: ... + +def register_adapter(type: type[_T], callable: _Adapter[_T]) -> None: ... +def register_converter(typename: str, callable: _Converter) -> None: ... + +class _AggregateProtocol(Protocol): + def step(self, __value: int) -> object: ... + def finalize(self) -> int: ... + +class _SingleParamWindowAggregateClass(Protocol): + def step(self, __param: Any) -> object: ... + def inverse(self, __param: Any) -> object: ... + def value(self) -> _SqliteData: ... + def finalize(self) -> _SqliteData: ... + +class _AnyParamWindowAggregateClass(Protocol): + def step(self, *args: Any) -> object: ... + def inverse(self, *args: Any) -> object: ... + def value(self) -> _SqliteData: ... + def finalize(self) -> _SqliteData: ... + +class _WindowAggregateClass(Protocol): + step: Callable[..., object] + inverse: Callable[..., object] + def value(self) -> _SqliteData: ... + def finalize(self) -> _SqliteData: ... + +class Connection: + @property + def DataError(self) -> type[DataError]: ... + @property + def DatabaseError(self) -> type[DatabaseError]: ... + @property + def Error(self) -> type[Error]: ... + @property + def IntegrityError(self) -> type[IntegrityError]: ... + @property + def InterfaceError(self) -> type[InterfaceError]: ... + @property + def InternalError(self) -> type[InternalError]: ... + @property + def NotSupportedError(self) -> type[NotSupportedError]: ... + @property + def OperationalError(self) -> type[OperationalError]: ... + @property + def ProgrammingError(self) -> type[ProgrammingError]: ... + @property + def Warning(self) -> type[Warning]: ... + @property + def in_transaction(self) -> bool: ... + isolation_level: str | None # one of '', 'DEFERRED', 'IMMEDIATE' or 'EXCLUSIVE' + @property + def total_changes(self) -> int: ... + row_factory: Any + text_factory: Any + def __init__( + self, + database: StrOrBytesPath, + timeout: float = ..., + detect_types: int = ..., + isolation_level: str | None = ..., + check_same_thread: bool = ..., + factory: type[Connection] | None = ..., + cached_statements: int = ..., + uri: bool = ..., + flags: int = ..., + vfi: str | None = ..., + ) -> None: ... + + def close(self) -> None: ... + def commit(self) -> None: ... + def create_aggregate(self, name: str, n_arg: int, aggregate_class: Callable[[], _AggregateProtocol]) -> None: ... + + # num_params determines how many params will be passed to the aggregate class. We provide an overload + # for the case where num_params = 1, which is expected to be the common case. + @overload + def create_window_function( + self, name: str, n_arg: Literal[1], window_function_class: Callable[[], _SingleParamWindowAggregateClass] | None + ) -> None: ... + # And for num_params = -1, which means the aggregate must accept any number of parameters. + @overload + def create_window_function( + self, name: str, n_arg: Literal[-1], window_function_class: Callable[[], _AnyParamWindowAggregateClass] | None + ) -> None: ... + @overload + def create_window_function( + self, name: str, n_arg: int, window_function_class: Callable[[], _WindowAggregateClass] | None + ) -> None: ... + + def create_collation(self, name: str, callback: Callable[[str, str], int | SupportsIndex] | None) -> None: ... + def create_function( + self, name: str, narg: int, func: Callable[..., _SqliteData] | None, *, deterministic: bool = False + ) -> None: ... + @overload + def cursor(self, factory: None = None) -> Cursor: ... + @overload + def cursor(self, factory: Callable[[Connection], _CursorT]) -> _CursorT: ... + def execute(self, __sql: str, __parameters: _Parameters = ...) -> Cursor: ... + def executemany(self, __sql: str, __parameters: Iterable[_Parameters]) -> Cursor: ... + def executescript(self, __sql_script: str) -> Cursor: ... + def interrupt(self) -> None: ... + def open_blob(self, table: str, column: str, row: int, readonly: bool, dbname: str) -> object: ... + def rollback(self) -> None: ... + def set_authorizer( + self, authorizer_callback: Callable[[int, str | None, str | None, str | None, str | None], int] | None + ) -> None: ... + def set_key(self, key: str) -> None: ... + def reset_key(self, key: str) -> None: ... + def set_progress_handler(self, progress_handler: Callable[[], int | None] | None, n: int) -> None: ... + def set_trace_callback(self, trace_callback: Callable[[str], object] | None) -> None: ... + # enable_load_extension and load_extension is not available on python distributions compiled + # without sqlite3 loadable extension support. see footnotes https://docs.python.org/3/library/sqlite3.html#f1 + def enable_load_extension(self, __enable: bool) -> None: ... + def load_extension(self, __name: str) -> None: ... + def backup( + self, + target: Connection, + *, + pages: int = -1, + progress: Callable[[int, int, int], object] | None = None, + name: str = "main", + sleep: float = 0.25, + ) -> None: ... + + def __call__(self, __sql: str) -> _Statement: ... + def __enter__(self) -> Self: ... + def __exit__( + self, __type: type[BaseException] | None, __value: BaseException | None, __traceback: TracebackType | None + ) -> Literal[False]: ... + +class Cursor(Iterator[Any]): + arraysize: int + @property + def connection(self) -> Connection: ... + # May be None, but using | Any instead to avoid slightly annoying false positives. + @property + def description(self) -> tuple[tuple[str, None, None, None, None, None, None], ...] | Any: ... + @property + def lastrowid(self) -> int | None: ... + row_factory: Callable[[Cursor, Row], object] | None + @property + def rowcount(self) -> int: ... + def __init__(self, __cursor: Connection) -> None: ... + def close(self) -> None: ... + def execute(self, __sql: str, __parameters: _Parameters = ()) -> Self: ... + def executemany(self, __sql: str, __seq_of_parameters: Iterable[_Parameters]) -> Self: ... + def executescript(self, __sql_script: str) -> Cursor: ... + def fetchall(self) -> list[Any]: ... + def fetchmany(self, size: int | None = 1) -> list[Any]: ... + # Returns either a row (as created by the row_factory) or None, but + # putting None in the return annotation causes annoying false positives. + def fetchone(self) -> Any: ... + def setinputsizes(self, __sizes: Unused) -> None: ... # does nothing + def setoutputsize(self, __size: Unused, __column: Unused = None) -> None: ... # does nothing + def __iter__(self) -> Self: ... + def __next__(self) -> Any: ... + +class Error(Exception): ... +class DatabaseError(Error): ... +class DataError(DatabaseError): ... +class IntegrityError(DatabaseError): ... +class InterfaceError(Error): ... +class InternalError(DatabaseError): ... +class NotSupportedError(DatabaseError): ... +class OperationalError(DatabaseError): ... + +OptimizedUnicode = str + +@final +class PrepareProtocol: + def __init__(self, *args: object, **kwargs: object) -> None: ... + +class ProgrammingError(DatabaseError): ... + +class Row: + def __init__(self, __cursor: Cursor, __data: tuple[Any, ...]) -> None: ... + def keys(self) -> list[str]: ... + @overload + def __getitem__(self, __key: int | str) -> Any: ... + @overload + def __getitem__(self, __key: slice) -> tuple[Any, ...]: ... + def __hash__(self) -> int: ... + def __iter__(self) -> Iterator[Any]: ... + def __len__(self) -> int: ... + # These return NotImplemented for anything that is not a Row. + def __eq__(self, __value: object) -> bool: ... + def __ge__(self, __value: object) -> bool: ... + def __gt__(self, __value: object) -> bool: ... + def __le__(self, __value: object) -> bool: ... + def __lt__(self, __value: object) -> bool: ... + def __ne__(self, __value: object) -> bool: ... + +@final +class _Statement: ... + +class Warning(Exception): ... \ No newline at end of file diff --git a/sqlcipher3/py.typed b/sqlcipher3/py.typed new file mode 100644 index 0000000..e69de29