|
| 1 | +"""Types for the compiled module. |
| 2 | +
|
| 3 | +The extension is a shared object, so nothing can read a signature out of |
| 4 | +it: mypy, pyright and an editor's completion all read this file |
| 5 | +instead. It ships inside the wheel next to `py.typed`, and CI checks it |
| 6 | +against the module it describes with griffe, which loads this file |
| 7 | +statically and the compiled module by inspection and compares them. A |
| 8 | +stub that promises a method the engine does not have is a lie a checker |
| 9 | +would believe, so it is worth a gate. |
| 10 | +
|
| 11 | +The docstrings here are the first line of each one in the Rust source, |
| 12 | +because a stub is what an editor shows and an editor showing nothing is |
| 13 | +what a stub is for. |
| 14 | +""" |
| 15 | + |
| 16 | +from __future__ import annotations |
| 17 | + |
| 18 | +import datetime |
| 19 | +import os |
| 20 | +import pathlib |
| 21 | +from collections.abc import Iterable, Iterator, Mapping, Sequence |
| 22 | +from typing import Any |
| 23 | + |
| 24 | +from .types import Value |
| 25 | + |
| 26 | +#: The revision of the C ABI this client answers to. |
| 27 | +__abi_version__: str |
| 28 | +#: The version of the engine compiled into the wheel. |
| 29 | +__engine_version__: str |
| 30 | + |
| 31 | +def connect( |
| 32 | + path: str | os.PathLike[str], |
| 33 | + *, |
| 34 | + read_only: bool = False, |
| 35 | + memory_limit: int | None = None, |
| 36 | + threads: int | None = None, |
| 37 | +) -> Connection: |
| 38 | + """Opens the database at `path` and connects to it.""" |
| 39 | + |
| 40 | +def load( |
| 41 | + path: str | os.PathLike[str], |
| 42 | + *, |
| 43 | + nodes: str, |
| 44 | + rels: str = "rel", |
| 45 | + columns: Mapping[str, Iterable[Value]] | None = None, |
| 46 | + edges: Iterable[Sequence[int]] | None = None, |
| 47 | + rows: int | None = None, |
| 48 | +) -> dict[str, int]: |
| 49 | + """Writes a new database at `path` and answers what went into it.""" |
| 50 | + |
| 51 | +class Connection: |
| 52 | + """One connection to one database.""" |
| 53 | + |
| 54 | + @property |
| 55 | + def path(self) -> pathlib.Path: |
| 56 | + """The file this connection was opened on.""" |
| 57 | + |
| 58 | + @property |
| 59 | + def read_only(self) -> bool: |
| 60 | + """Whether it was opened read-only.""" |
| 61 | + |
| 62 | + @property |
| 63 | + def closed(self) -> bool: |
| 64 | + """Whether this connection is still open.""" |
| 65 | + |
| 66 | + def execute(self, statement: str, params: Mapping[str, Value] | None = None) -> Result: |
| 67 | + """Runs one statement and gives back its rows.""" |
| 68 | + |
| 69 | + def sql(self, statement: str, params: Mapping[str, Value] | None = None) -> Result: |
| 70 | + """The same call, named for the way it reads in a notebook.""" |
| 71 | + |
| 72 | + def close(self) -> None: |
| 73 | + """Closes the connection and frees what it held.""" |
| 74 | + |
| 75 | + def __enter__(self) -> Connection: ... |
| 76 | + def __exit__(self, *_exception: object) -> bool: ... |
| 77 | + def __repr__(self) -> str: ... |
| 78 | + |
| 79 | +class Result: |
| 80 | + """The rows a statement gave back.""" |
| 81 | + |
| 82 | + @property |
| 83 | + def columns(self) -> list[str]: |
| 84 | + """The column names, in the order the statement projected them.""" |
| 85 | + |
| 86 | + @property |
| 87 | + def notices(self) -> list[dict[str, str]]: |
| 88 | + """The warnings the statement raised, if it raised any.""" |
| 89 | + |
| 90 | + def fetchall(self) -> list[tuple[Value, ...]]: |
| 91 | + """Every row, as a list of tuples.""" |
| 92 | + |
| 93 | + def fetchone(self) -> tuple[Value, ...] | None: |
| 94 | + """The next row, or `None` when there are no more.""" |
| 95 | + |
| 96 | + # `Any` and not `pyarrow.Table`, because the wheel does not depend |
| 97 | + # on pyarrow and a stub that imported it would fail to resolve for |
| 98 | + # every caller who does not have it either. |
| 99 | + def to_arrow(self) -> Any: |
| 100 | + """The rows as a `pyarrow.Table`.""" |
| 101 | + |
| 102 | + def to_pandas(self) -> Any: |
| 103 | + """The rows as a `pandas.DataFrame`, with Arrow-backed dtypes.""" |
| 104 | + |
| 105 | + def to_polars(self) -> Any: |
| 106 | + """The rows as a `polars.DataFrame`.""" |
| 107 | + |
| 108 | + def record_batches(self) -> Any: |
| 109 | + """The rows as a `pyarrow.RecordBatchReader`, a batch at a time.""" |
| 110 | + |
| 111 | + def __arrow_c_stream__(self, requested_schema: object | None = None) -> Any: |
| 112 | + """The rows as an Arrow stream, for anything that speaks Arrow.""" |
| 113 | + |
| 114 | + def __len__(self) -> int: ... |
| 115 | + def __iter__(self) -> Iterator[tuple[Value, ...]]: ... |
| 116 | + def __repr__(self) -> str: ... |
| 117 | + |
| 118 | +class Node: |
| 119 | + """One node of the graph.""" |
| 120 | + |
| 121 | + def __init__(self, table: str, offset: int) -> None: ... |
| 122 | + @property |
| 123 | + def table(self) -> str: |
| 124 | + """The name the table was given in the schema.""" |
| 125 | + |
| 126 | + @property |
| 127 | + def offset(self) -> int: |
| 128 | + """The row this node sits at in that table, counting from zero.""" |
| 129 | + |
| 130 | + def __hash__(self) -> int: ... |
| 131 | + def __repr__(self) -> str: ... |
| 132 | + |
| 133 | +class Rel: |
| 134 | + """One edge of the graph.""" |
| 135 | + |
| 136 | + def __init__(self, table: str, src: int, dst: int, ord: int) -> None: ... |
| 137 | + @property |
| 138 | + def table(self) -> str: |
| 139 | + """The name the rel table was given in the schema.""" |
| 140 | + |
| 141 | + @property |
| 142 | + def src(self) -> int: |
| 143 | + """The row the edge leaves, in the node table it joins.""" |
| 144 | + |
| 145 | + @property |
| 146 | + def dst(self) -> int: |
| 147 | + """The row the edge arrives at.""" |
| 148 | + |
| 149 | + @property |
| 150 | + def ord(self) -> int: |
| 151 | + """Where the edge's properties sit, which is its place in |
| 152 | + the order the table was loaded in.""" |
| 153 | + |
| 154 | + def __hash__(self) -> int: ... |
| 155 | + def __repr__(self) -> str: ... |
| 156 | + |
| 157 | +class Path: |
| 158 | + """A walk: nodes and edges alternating, a node at each end.""" |
| 159 | + |
| 160 | + def __init__(self, elements: list[Node | Rel]) -> None: ... |
| 161 | + @property |
| 162 | + def elements(self) -> list[Node | Rel]: |
| 163 | + """The walk as it is stored, a node and an edge at a time.""" |
| 164 | + |
| 165 | + @property |
| 166 | + def nodes(self) -> list[Node]: |
| 167 | + """The nodes of the walk, in the order it visits them.""" |
| 168 | + |
| 169 | + @property |
| 170 | + def rels(self) -> list[Rel]: |
| 171 | + """The edges of the walk, in the order it crosses them.""" |
| 172 | + |
| 173 | + def __len__(self) -> int: ... |
| 174 | + def __repr__(self) -> str: ... |
| 175 | + |
| 176 | +class Duration: |
| 177 | + """A duration, which Python has no type for.""" |
| 178 | + |
| 179 | + def __init__(self, months: int = 0, nanoseconds: int = 0) -> None: ... |
| 180 | + @property |
| 181 | + def months(self) -> int: |
| 182 | + """Months, for a year-month duration. Zero for a day-time one.""" |
| 183 | + |
| 184 | + @property |
| 185 | + def nanoseconds(self) -> int: |
| 186 | + """Nanoseconds, for a day-time duration. Zero for a year-month one.""" |
| 187 | + |
| 188 | + @property |
| 189 | + def kind(self) -> str: |
| 190 | + """`"year_month"` or `"day_time"`.""" |
| 191 | + |
| 192 | + def to_timedelta(self) -> datetime.timedelta: |
| 193 | + """The same duration as a `datetime.timedelta`, rounded towards zero.""" |
| 194 | + |
| 195 | + def __hash__(self) -> int: ... |
| 196 | + def __repr__(self) -> str: ... |
0 commit comments