vendor aiosqlite

This commit is contained in:
arvidn
2026-08-20 14:14:28 +02:00
parent 29e386aec2
commit ef0e90fb3c
36 changed files with 767 additions and 42 deletions
+1 -1
View File
@@ -7,11 +7,11 @@ from dataclasses import dataclass
from pathlib import Path
from time import monotonic
import aiosqlite
import click
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint8, uint32
from chia._vendored import aiosqlite
from chia.consensus.block_height_map import BlockHeightMap
from chia.consensus.blockchain import Blockchain
from chia.consensus.default_constants import DEFAULT_CONSTANTS
@@ -4,7 +4,6 @@ import logging
from dataclasses import dataclass
from pathlib import Path
import aiosqlite
import pytest
from chia_rs import CoinRecord, CoinState, FullBlock, additions_and_removals, get_flags_for_height_and_constants
from chia_rs.sized_bytes import bytes32
@@ -14,6 +13,7 @@ from chia._tests.blockchain.blockchain_test_utils import _validate_and_add_block
from chia._tests.util.coin_store import add_coin_records_to_db
from chia._tests.util.db_connection import DBConnection
from chia._tests.util.misc import Marks, datacases
from chia._vendored import aiosqlite
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.block_generator_info import block_has_transactions_generator, get_transactions_generator_bytes
from chia.consensus.block_height_map import BlockHeightMap
+1 -1
View File
@@ -6,7 +6,6 @@ from collections.abc import Callable
from dataclasses import dataclass
from typing import TYPE_CHECKING
import aiosqlite
import pytest
# TODO: update after resolution in https://github.com/pytest-dev/pytest/issues/7469
@@ -14,6 +13,7 @@ from _pytest.fixtures import SubRequest
from chia._tests.util.db_connection import DBConnection, PathDBConnection
from chia._tests.util.misc import Marks, boolean_datacases, datacases
from chia._vendored import aiosqlite
from chia.util.db_wrapper import DBWrapper2, ForeignKeyError, InternalError, NestedForeignKeyDelayedRequestError
from chia.util.task_referencer import create_referenced_task
+1 -2
View File
@@ -5,8 +5,7 @@ from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from pathlib import Path
import aiosqlite
from chia._vendored import aiosqlite
from chia.util.db_wrapper import DBWrapper2, generate_in_memory_db_uri
+1 -1
View File
@@ -13,13 +13,13 @@ from contextlib import contextmanager
from pathlib import Path
from typing import cast
import aiosqlite
import zstd
from chia_rs import FullBlock
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint16
from chia._tests.util.constants import test_constants as TEST_CONSTANTS
from chia._vendored import aiosqlite
from chia.cmds.init_funcs import chia_init
from chia.consensus.augmented_chain import AugmentedBlockchain
from chia.consensus.block_body_validation import ForkInfo
+1 -1
View File
@@ -11,7 +11,6 @@ from types import SimpleNamespace
from typing import Any, cast
from unittest.mock import AsyncMock, MagicMock, patch
import aiosqlite
import pytest
from chia_rs import CoinRecord, CoinSpend, G1Element, G2Element
from chia_rs.sized_bytes import bytes32
@@ -49,6 +48,7 @@ from chia._tests.wallet.test_wallet_coin_store import (
)
from chia.cmds.cmd_classes import ChiaCliContext
from chia.cmds.cmd_helpers import NeedsWalletRPC, WalletClientInfo
from chia._vendored import aiosqlite
from chia.cmds.coins import CombineCMD, SplitCMD
from chia.cmds.param_types import CliAddress, CliAmount
from chia.cmds.wallet import (
+1 -1
View File
@@ -10,7 +10,6 @@ from dataclasses import dataclass
from unittest.mock import MagicMock
import pytest
from aiosqlite import Error as AIOSqliteError
from chia_rs import (
BlockRecord,
Coin,
@@ -40,6 +39,7 @@ from chia._tests.util.misc import patch_request_handler, wallet_height_at_least
from chia._tests.util.setup_nodes import OldSimulatorsAndWallets
from chia._tests.util.time_out_assert import time_out_assert, time_out_assert_not_none
from chia._tests.weight_proof.test_weight_proof import load_blocks_dont_validate
from chia._vendored.aiosqlite import Error as AIOSqliteError
from chia.consensus.augmented_chain import AugmentedBlockchain
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
+28
View File
@@ -0,0 +1,28 @@
# Vendored third-party packages
This directory contains third-party packages that are vendored (copied) into the
`chia` package instead of being declared as external dependencies. Code here is
imported as `chia._vendored.<package>`.
Do not edit the vendored sources by hand. To upgrade, replace the package
directory wholesale with a new release and update the version recorded below.
## aiosqlite
- Upstream: https://github.com/omnilib/aiosqlite
- Version: 0.22.1
- Source: https://files.pythonhosted.org/packages/4e/8a/64761f4005f17809769d23e518d915db74e6310474e733e3593cfc854ef1/aiosqlite-0.22.1.tar.gz
- sha256: 043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650
- License: MIT (see `aiosqlite/LICENSE`)
Only the `aiosqlite/` package directory and its `LICENSE` are vendored; the
upstream `tests/` directory is intentionally omitted. The package has no runtime
dependencies beyond the standard library.
### Upgrade steps
1. Download the new sdist from PyPI and verify its hash.
2. Replace `chia/_vendored/aiosqlite/` with the new `aiosqlite/` package dir plus
its `LICENSE` (delete the bundled `tests/` dir).
3. Update the version/source/hash recorded above.
4. Run the DB tests and `mypy`/`ruff`.
View File
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Amethyst Reese
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+44
View File
@@ -0,0 +1,44 @@
# Copyright Amethyst Reese
# Licensed under the MIT license
"""asyncio bridge to the standard sqlite3 module"""
from sqlite3 import ( # pylint: disable=redefined-builtin
DatabaseError,
Error,
IntegrityError,
NotSupportedError,
OperationalError,
paramstyle,
ProgrammingError,
register_adapter,
register_converter,
Row,
sqlite_version,
sqlite_version_info,
Warning,
)
__author__ = "Amethyst Reese"
from .__version__ import __version__
from .core import connect, Connection, Cursor
__all__ = [
"__version__",
"paramstyle",
"register_adapter",
"register_converter",
"sqlite_version",
"sqlite_version_info",
"connect",
"Connection",
"Cursor",
"Row",
"Warning",
"Error",
"DatabaseError",
"IntegrityError",
"ProgrammingError",
"OperationalError",
"NotSupportedError",
]
+7
View File
@@ -0,0 +1,7 @@
"""
This file is automatically generated by attribution.
Do not edit manually. Get more info at https://attribution.omnilib.dev
"""
__version__ = "0.22.1"
+56
View File
@@ -0,0 +1,56 @@
# Copyright Amethyst Reese
# Licensed under the MIT license
from collections.abc import Coroutine, Generator
from contextlib import AbstractAsyncContextManager
from functools import wraps
from typing import Any, Callable, TypeVar
from .cursor import Cursor
_T = TypeVar("_T")
class Result(AbstractAsyncContextManager[_T], Coroutine[Any, Any, _T]):
__slots__ = ("_coro", "_obj")
def __init__(self, coro: Coroutine[Any, Any, _T]):
self._coro = coro
self._obj: _T
def send(self, value) -> None:
return self._coro.send(value)
def throw(self, typ, val=None, tb=None) -> None:
if val is None:
return self._coro.throw(typ)
if tb is None:
return self._coro.throw(typ, val)
return self._coro.throw(typ, val, tb)
def close(self) -> None:
return self._coro.close()
def __await__(self) -> Generator[Any, None, _T]:
return self._coro.__await__()
async def __aenter__(self) -> _T:
self._obj = await self._coro
return self._obj
async def __aexit__(self, exc_type, exc, tb) -> None:
if isinstance(self._obj, Cursor):
await self._obj.close()
def contextmanager(
method: Callable[..., Coroutine[Any, Any, _T]],
) -> Callable[..., Result[_T]]:
@wraps(method)
def wrapper(self, *args, **kwargs) -> Result[_T]:
return Result(method(self, *args, **kwargs))
return wrapper
+468
View File
@@ -0,0 +1,468 @@
# Copyright Amethyst Reese
# Licensed under the MIT license
"""
Core implementation of aiosqlite proxies
"""
import asyncio
import logging
import sqlite3
from collections.abc import AsyncIterator, Generator, Iterable
from functools import partial
from pathlib import Path
from queue import Empty, Queue, SimpleQueue
from threading import Thread
from typing import Any, Callable, Literal, Optional, Union
from warnings import warn
from .context import contextmanager
from .cursor import Cursor
__all__ = ["connect", "Connection", "Cursor"]
AuthorizerCallback = Callable[[int, str, str, str, str], int]
LOG = logging.getLogger("aiosqlite")
IsolationLevel = Optional[Literal["DEFERRED", "IMMEDIATE", "EXCLUSIVE"]]
def set_result(fut: asyncio.Future, result: Any) -> None:
"""Set the result of a future if it hasn't been set already."""
if not fut.done():
fut.set_result(result)
def set_exception(fut: asyncio.Future, e: BaseException) -> None:
"""Set the exception of a future if it hasn't been set already."""
if not fut.done():
fut.set_exception(e)
_STOP_RUNNING_SENTINEL = object()
_TxQueue = SimpleQueue[tuple[Optional[asyncio.Future], Callable[[], Any]]]
def _connection_worker_thread(tx: _TxQueue):
"""
Execute function calls on a separate thread.
:meta private:
"""
while True:
# Continues running until all queue items are processed,
# even after connection is closed (so we can finalize all
# futures)
future, function = tx.get()
try:
LOG.debug("executing %s", function)
result = function()
if future:
future.get_loop().call_soon_threadsafe(set_result, future, result)
LOG.debug("operation %s completed", function)
if result is _STOP_RUNNING_SENTINEL:
break
except BaseException as e: # noqa B036
LOG.debug("returning exception %s", e)
if future:
future.get_loop().call_soon_threadsafe(set_exception, future, e)
class Connection:
def __init__(
self,
connector: Callable[[], sqlite3.Connection],
iter_chunk_size: int,
loop: Optional[asyncio.AbstractEventLoop] = None,
) -> None:
self._running = True
self._connection: Optional[sqlite3.Connection] = None
self._connector = connector
self._tx: _TxQueue = SimpleQueue()
self._iter_chunk_size = iter_chunk_size
self._thread = Thread(target=_connection_worker_thread, args=(self._tx,))
if loop is not None:
warn(
"aiosqlite.Connection no longer uses the `loop` parameter",
DeprecationWarning,
)
def __del__(self):
if self._connection is None:
return
warn(
(
f"{self!r} was deleted before being closed. "
"Please use 'async with' or '.close()' to close the connection properly."
),
ResourceWarning,
stacklevel=1,
)
# Don't try to be creative here, the event loop may have already been closed.
# Simply stop the worker thread, and let the underlying sqlite3 connection
# be finalized by its own __del__.
self.stop()
def stop(self) -> Optional[asyncio.Future]:
"""Stop the background thread. Prefer `async with` or `await close()`"""
self._running = False
def close_and_stop():
if self._connection is not None:
self._connection.close()
self._connection = None
return _STOP_RUNNING_SENTINEL
try:
future = asyncio.get_event_loop().create_future()
except Exception:
future = None
self._tx.put_nowait((future, close_and_stop))
return future
@property
def _conn(self) -> sqlite3.Connection:
if self._connection is None:
raise ValueError("no active connection")
return self._connection
def _execute_insert(self, sql: str, parameters: Any) -> Optional[sqlite3.Row]:
cursor = self._conn.execute(sql, parameters)
cursor.execute("SELECT last_insert_rowid()")
return cursor.fetchone()
def _execute_fetchall(self, sql: str, parameters: Any) -> Iterable[sqlite3.Row]:
cursor = self._conn.execute(sql, parameters)
return cursor.fetchall()
async def _execute(self, fn, *args, **kwargs):
"""Queue a function with the given arguments for execution."""
if not self._running or not self._connection:
raise ValueError("Connection closed")
function = partial(fn, *args, **kwargs)
future = asyncio.get_event_loop().create_future()
self._tx.put_nowait((future, function))
return await future
async def _connect(self) -> "Connection":
"""Connect to the actual sqlite database."""
if self._connection is None:
try:
future = asyncio.get_event_loop().create_future()
self._tx.put_nowait((future, self._connector))
self._connection = await future
except BaseException:
self.stop()
self._connection = None
raise
return self
def __await__(self) -> Generator[Any, None, "Connection"]:
self._thread.start()
return self._connect().__await__()
async def __aenter__(self) -> "Connection":
return await self
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
await self.close()
@contextmanager
async def cursor(self) -> Cursor:
"""Create an aiosqlite cursor wrapping a sqlite3 cursor object."""
return Cursor(self, await self._execute(self._conn.cursor))
async def commit(self) -> None:
"""Commit the current transaction."""
await self._execute(self._conn.commit)
async def rollback(self) -> None:
"""Roll back the current transaction."""
await self._execute(self._conn.rollback)
async def close(self) -> None:
"""Complete queued queries/cursors and close the connection."""
if self._connection is None:
return
try:
await self._execute(self._conn.close)
except Exception:
LOG.info("exception occurred while closing connection")
raise
finally:
self._connection = None
future = self.stop()
if future:
await future
@contextmanager
async def execute(
self, sql: str, parameters: Optional[Iterable[Any]] = None
) -> Cursor:
"""Helper to create a cursor and execute the given query."""
if parameters is None:
parameters = []
cursor = await self._execute(self._conn.execute, sql, parameters)
return Cursor(self, cursor)
@contextmanager
async def execute_insert(
self, sql: str, parameters: Optional[Iterable[Any]] = None
) -> Optional[sqlite3.Row]:
"""Helper to insert and get the last_insert_rowid."""
if parameters is None:
parameters = []
return await self._execute(self._execute_insert, sql, parameters)
@contextmanager
async def execute_fetchall(
self, sql: str, parameters: Optional[Iterable[Any]] = None
) -> Iterable[sqlite3.Row]:
"""Helper to execute a query and return all the data."""
if parameters is None:
parameters = []
return await self._execute(self._execute_fetchall, sql, parameters)
@contextmanager
async def executemany(
self, sql: str, parameters: Iterable[Iterable[Any]]
) -> Cursor:
"""Helper to create a cursor and execute the given multiquery."""
cursor = await self._execute(self._conn.executemany, sql, parameters)
return Cursor(self, cursor)
@contextmanager
async def executescript(self, sql_script: str) -> Cursor:
"""Helper to create a cursor and execute a user script."""
cursor = await self._execute(self._conn.executescript, sql_script)
return Cursor(self, cursor)
async def interrupt(self) -> None:
"""Interrupt pending queries."""
return self._conn.interrupt()
async def create_function(
self, name: str, num_params: int, func: Callable, deterministic: bool = False
) -> None:
"""
Create user-defined function that can be later used
within SQL statements. Must be run within the same thread
that query executions take place so instead of executing directly
against the connection, we defer this to `run` function.
If ``deterministic`` is true, the created function is marked as deterministic,
which allows SQLite to perform additional optimizations. This flag is supported
by SQLite 3.8.3 or higher, ``NotSupportedError`` will be raised if used with
older versions.
"""
await self._execute(
self._conn.create_function,
name,
num_params,
func,
deterministic=deterministic,
)
@property
def in_transaction(self) -> bool:
return self._conn.in_transaction
@property
def isolation_level(self) -> Optional[str]:
return self._conn.isolation_level
@isolation_level.setter
def isolation_level(self, value: IsolationLevel) -> None:
self._conn.isolation_level = value
@property
def row_factory(self) -> Optional[type]:
return self._conn.row_factory
@row_factory.setter
def row_factory(self, factory: Optional[type]) -> None:
self._conn.row_factory = factory
@property
def text_factory(self) -> Callable[[bytes], Any]:
return self._conn.text_factory
@text_factory.setter
def text_factory(self, factory: Callable[[bytes], Any]) -> None:
self._conn.text_factory = factory
@property
def total_changes(self) -> int:
return self._conn.total_changes
async def enable_load_extension(self, value: bool) -> None:
await self._execute(self._conn.enable_load_extension, value) # type: ignore
async def load_extension(self, path: str):
await self._execute(self._conn.load_extension, path) # type: ignore
async def set_progress_handler(
self, handler: Callable[[], Optional[int]], n: int
) -> None:
await self._execute(self._conn.set_progress_handler, handler, n)
async def set_trace_callback(self, handler: Callable) -> None:
await self._execute(self._conn.set_trace_callback, handler)
async def set_authorizer(
self, authorizer_callback: Optional[AuthorizerCallback]
) -> None:
"""
Set an authorizer callback to control database access.
The authorizer callback is invoked for each SQL statement that is prepared,
and controls whether specific operations are permitted.
Example::
import sqlite3
def restrict_drops(action_code, arg1, arg2, db_name, trigger_name):
# Deny all DROP operations
if action_code == sqlite3.SQLITE_DROP_TABLE:
return sqlite3.SQLITE_DENY
# Allow everything else
return sqlite3.SQLITE_OK
await conn.set_authorizer(restrict_drops)
See ``sqlite3`` documentation for details:
https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.set_authorizer
:param authorizer_callback: An optional callable that receives five arguments:
- ``action_code`` (int): The action to be authorized (e.g., ``SQLITE_READ``)
- ``arg1`` (str): First argument, meaning depends on ``action_code``
- ``arg2`` (str): Second argument, meaning depends on ``action_code``
- ``db_name`` (str): Database name (e.g., ``"main"``, ``"temp"``)
- ``trigger_name`` (str): Name of trigger or view that is doing the access,
or ``None``
The callback should return:
- ``SQLITE_OK`` (0): Allow the operation
- ``SQLITE_DENY`` (1): Deny the operation, raise ``sqlite3.DatabaseError``
- ``SQLITE_IGNORE`` (2): Treat operation as no-op
Pass ``None`` to remove the authorizer.
"""
await self._execute(self._conn.set_authorizer, authorizer_callback)
async def iterdump(self) -> AsyncIterator[str]:
"""
Return an async iterator to dump the database in SQL text format.
Example::
async for line in db.iterdump():
...
"""
dump_queue: Queue = Queue()
def dumper():
try:
for line in self._conn.iterdump():
dump_queue.put_nowait(line)
dump_queue.put_nowait(None)
except Exception:
LOG.exception("exception while dumping db")
dump_queue.put_nowait(None)
raise
fut = self._execute(dumper)
task = asyncio.ensure_future(fut)
while True:
try:
line: Optional[str] = dump_queue.get_nowait()
if line is None:
break
yield line
except Empty:
if task.done():
LOG.warning("iterdump completed unexpectedly")
break
await asyncio.sleep(0.01)
await task
async def backup(
self,
target: Union["Connection", sqlite3.Connection],
*,
pages: int = 0,
progress: Optional[Callable[[int, int, int], None]] = None,
name: str = "main",
sleep: float = 0.250,
) -> None:
"""
Make a backup of the current database to the target database.
Takes either a standard sqlite3 or aiosqlite Connection object as the target.
"""
if isinstance(target, Connection):
target = target._conn
await self._execute(
self._conn.backup,
target,
pages=pages,
progress=progress,
name=name,
sleep=sleep,
)
def connect(
database: Union[str, Path],
*,
iter_chunk_size=64,
loop: Optional[asyncio.AbstractEventLoop] = None,
**kwargs: Any,
) -> Connection:
"""Create and return a connection proxy to the sqlite database."""
if loop is not None:
warn(
"aiosqlite.connect() no longer uses the `loop` parameter",
DeprecationWarning,
)
def connector() -> sqlite3.Connection:
if isinstance(database, str):
loc = database
elif isinstance(database, bytes):
loc = database.decode("utf-8")
else:
loc = str(database)
return sqlite3.connect(loc, **kwargs)
return Connection(connector, iter_chunk_size)
+110
View File
@@ -0,0 +1,110 @@
# Copyright Amethyst Reese
# Licensed under the MIT license
import sqlite3
from collections.abc import AsyncIterator, Iterable
from typing import Any, Callable, Optional, TYPE_CHECKING
if TYPE_CHECKING:
from .core import Connection
class Cursor:
def __init__(self, conn: "Connection", cursor: sqlite3.Cursor) -> None:
self.iter_chunk_size = conn._iter_chunk_size
self._conn = conn
self._cursor = cursor
def __aiter__(self) -> AsyncIterator[sqlite3.Row]:
"""The cursor proxy is also an async iterator."""
return self._fetch_chunked()
async def _fetch_chunked(self):
while True:
rows = await self.fetchmany(self.iter_chunk_size)
if not rows:
return
for row in rows:
yield row
async def _execute(self, fn, *args, **kwargs):
"""Execute the given function on the shared connection's thread."""
return await self._conn._execute(fn, *args, **kwargs)
async def execute(
self, sql: str, parameters: Optional[Iterable[Any]] = None
) -> "Cursor":
"""Execute the given query."""
if parameters is None:
parameters = []
await self._execute(self._cursor.execute, sql, parameters)
return self
async def executemany(
self, sql: str, parameters: Iterable[Iterable[Any]]
) -> "Cursor":
"""Execute the given multiquery."""
await self._execute(self._cursor.executemany, sql, parameters)
return self
async def executescript(self, sql_script: str) -> "Cursor":
"""Execute a user script."""
await self._execute(self._cursor.executescript, sql_script)
return self
async def fetchone(self) -> Optional[sqlite3.Row]:
"""Fetch a single row."""
return await self._execute(self._cursor.fetchone)
async def fetchmany(self, size: Optional[int] = None) -> Iterable[sqlite3.Row]:
"""Fetch up to `cursor.arraysize` number of rows."""
args: tuple[int, ...] = ()
if size is not None:
args = (size,)
return await self._execute(self._cursor.fetchmany, *args)
async def fetchall(self) -> Iterable[sqlite3.Row]:
"""Fetch all remaining rows."""
return await self._execute(self._cursor.fetchall)
async def close(self) -> None:
"""Close the cursor."""
await self._execute(self._cursor.close)
@property
def rowcount(self) -> int:
return self._cursor.rowcount
@property
def lastrowid(self) -> Optional[int]:
return self._cursor.lastrowid
@property
def arraysize(self) -> int:
return self._cursor.arraysize
@arraysize.setter
def arraysize(self, value: int) -> None:
self._cursor.arraysize = value
@property
def description(self) -> tuple[tuple[str, None, None, None, None, None, None], ...]:
return self._cursor.description
@property
def row_factory(self) -> Optional[Callable[[sqlite3.Cursor, sqlite3.Row], object]]:
return self._cursor.row_factory
@row_factory.setter
def row_factory(self, factory: Optional[type]) -> None:
self._cursor.row_factory = factory
@property
def connection(self) -> sqlite3.Connection:
return self._cursor.connection
async def __aenter__(self):
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.close()
View File
+1 -1
View File
@@ -7,12 +7,12 @@ from hashlib import sha256
from pathlib import Path
from typing import TYPE_CHECKING, Any, Union
import aiosqlite
from chia_rs.datalayer import ProofOfInclusion, ProofOfInclusionLayer
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint8, uint64
from typing_extensions import final
from chia._vendored import aiosqlite
from chia.data_layer.data_layer_errors import ProofIntegrityError
from chia.server.ws_connection import WSChiaConnection
from chia.types.blockchain_format.program import Program
+1 -1
View File
@@ -14,7 +14,6 @@ from hashlib import sha256
from pathlib import Path
from typing import Any, BinaryIO
import aiosqlite
import anyio.to_thread
import chia_rs.datalayer
import zstd
@@ -31,6 +30,7 @@ from chia_rs.datalayer import (
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import int64
from chia._vendored import aiosqlite
from chia.data_layer.data_layer_errors import (
KeyNotFoundError,
MaxDeltaFileSizeExceededError,
+1 -1
View File
@@ -2,11 +2,11 @@ from __future__ import annotations
import dataclasses
from aiosqlite import Row
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint16, uint32, uint64
from typing_extensions import Self
from chia._vendored.aiosqlite import Row
from chia.data_layer.data_layer_wallet import Mirror
from chia.data_layer.singleton_record import SingletonRecord
from chia.types.blockchain_format.coin import Coin
+1 -1
View File
@@ -8,11 +8,11 @@ from collections.abc import Collection
from typing import Any, ClassVar
import typing_extensions
from aiosqlite import Cursor
from chia_rs import CoinRecord, CoinState
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint32, uint64
from chia._vendored.aiosqlite import Cursor
from chia.types.blockchain_format.coin import Coin
from chia.types.mempool_item import UnspentLineageInfo
from chia.util.batches import to_batches
+1 -1
View File
@@ -7,9 +7,9 @@ import time
from dataclasses import dataclass, field, replace
from datetime import datetime, timedelta
import aiosqlite
from chia_rs.sized_ints import uint32, uint64
from chia._vendored import aiosqlite
from chia.seeder.peer_record import PeerRecord, PeerReliability
log = logging.getLogger(__name__)
+1 -1
View File
@@ -12,10 +12,10 @@ from dataclasses import dataclass, field
from pathlib import Path
from typing import TYPE_CHECKING, Any, ClassVar, cast
import aiosqlite
from chia_rs import ConsensusConstants
from chia_rs.sized_ints import uint32, uint64
from chia._vendored import aiosqlite
from chia.full_node.full_node_api import FullNodeAPI
from chia.protocols import full_node_protocol
from chia.protocols.full_node_protocol import RespondPeers
+1 -1
View File
@@ -14,10 +14,10 @@ from pathlib import Path
from types import FrameType
from typing import Any
import aiosqlite
import dns.asyncresolver
from dnslib import AAAA, EDNS0, NS, QTYPE, RCODE, RD, RR, SOA, A, DNSError, DNSHeader, DNSQuestion, DNSRecord
from chia._vendored import aiosqlite
from chia.seeder.crawl_store import CrawlStore
from chia.server.signal_handlers import SignalHandlers
from chia.util.chia_logging import initialize_service_logging
+2
View File
@@ -5,6 +5,8 @@ import copy
from collections.abc import AsyncIterator, Awaitable, Callable
from dataclasses import dataclass, field
from typing import Generic, TypeVar
from chia._vendored import aiosqlite
from chia.util.db_wrapper import DBWrapper2, execute_fetchone
from typing_extensions import Self
+1 -1
View File
@@ -4,7 +4,7 @@ from __future__ import annotations
import sqlite3
import aiosqlite
from chia._vendored import aiosqlite
async def lookup_db_version(db: aiosqlite.Connection) -> int:
+2 -1
View File
@@ -14,10 +14,11 @@ from datetime import datetime
from pathlib import Path
from typing import Any, TextIO
import aiosqlite
import anyio
from typing_extensions import final
from chia._vendored import aiosqlite
if aiosqlite.sqlite_version_info < (3, 32, 0):
SQLITE_MAX_VARIABLE_NUMBER = 900
else:
+1 -1
View File
@@ -3,10 +3,10 @@ from __future__ import annotations
import logging
from time import perf_counter
import aiosqlite
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint8, uint32
from chia._vendored import aiosqlite
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
from chia.util.db_wrapper import DBWrapper2
from chia.util.errors import Err
+1 -1
View File
@@ -3,11 +3,11 @@ from __future__ import annotations
import dataclasses
from functools import cmp_to_key
from aiosqlite import Row
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint32, uint64
from typing_extensions import Self
from chia._vendored.aiosqlite import Row
from chia.types.blockchain_format.coin import Coin
from chia.types.blockchain_format.program import Program
from chia.util.db_wrapper import DBWrapper2
+1 -1
View File
@@ -13,12 +13,12 @@ from collections.abc import AsyncIterator
from pathlib import Path
from typing import TYPE_CHECKING, Any, ClassVar, Literal, cast, overload
import aiosqlite
from chia_rs import AugSchemeMPL, CoinState, ConsensusConstants, G1Element, G2Element, HeaderBlock, PrivateKey
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint16, uint32, uint64, uint128
from packaging.version import Version
from chia._vendored import aiosqlite
from chia.consensus.blockchain import AddBlockResult
from chia.daemon.keychain_proxy import KeychainProxy, connect_to_keychain_and_validate, wrap_local_keychain
from chia.full_node.full_node_api import FullNodeAPI
+1 -1
View File
@@ -15,11 +15,11 @@ from enum import IntEnum
from pathlib import Path
from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
import aiosqlite
from chia_rs import CoinRecord, CoinSpend, CoinState, ConsensusConstants, G1Element, G2Element, PrivateKey
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint8, uint16, uint32, uint64, uint128
from chia._vendored import aiosqlite
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
from chia.consensus.coinbase import farmer_parent_id, pool_parent_id
from chia.data_layer.data_layer_wallet import DataLayerWallet
+1 -1
View File
@@ -4,11 +4,11 @@ import dataclasses
import logging
import time
import aiosqlite
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint8, uint32
from typing_extensions import Any
from chia._vendored import aiosqlite
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
from chia.util.bech32m import encode_puzzle_hash
from chia.util.db_wrapper import DBWrapper2
+1 -17
View File
@@ -199,22 +199,6 @@ files = [
frozenlist = ">=1.1.0"
typing-extensions = {version = ">=4.2", markers = "python_version < \"3.13\""}
[[package]]
name = "aiosqlite"
version = "0.22.1"
description = "asyncio bridge to the standard sqlite3 module"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "aiosqlite-0.22.1-py3-none-any.whl", hash = "sha256:21c002eb13823fad740196c5a2e9d8e62f6243bd9e7e4a1f87fb5e44ecb4fceb"},
{file = "aiosqlite-0.22.1.tar.gz", hash = "sha256:043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650"},
]
[package.extras]
dev = ["attribution (==1.8.0)", "black (==25.11.0)", "build (>=1.2)", "coverage[toml] (==7.10.7)", "flake8 (==7.3.0)", "flake8-bugbear (==24.12.12)", "flit (==3.12.0)", "mypy (==1.19.0)", "ufmt (==2.8.0)", "usort (==1.0.8.post1)"]
docs = ["sphinx (==8.1.3)", "sphinx-mdinclude (==0.6.2)"]
[[package]]
name = "altgraph"
version = "0.17.5"
@@ -5244,4 +5228,4 @@ upnp = ["miniupnpc"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.10, <4"
content-hash = "0a699e35185bb71a490019eedf0b00326f181d8dbb28ee85f87a0a4824623c88"
content-hash = "259a85430057f1187e4ac9d76ee3eb74a9d83a8604aceb8f1ec2aae51c14f3f4"
-1
View File
@@ -46,7 +46,6 @@ changelog = "https://github.com/Chia-Network/chia-blockchain/blob/main/CHANGELOG
[tool.poetry.dependencies]
aiofiles = ">=24.1.0" # Async IO for files
aiohttp = ">=3.14.0" # HTTP server for full node rpc
aiosqlite = ">=0.20.0" # asyncio wrapper for sqlite, to store blocks
anyio = ">=4.6.2.post1"
bitstring = ">=4.1.4" # Binary data management library
boto3 = ">=1.43.8" # AWS S3 for Data Layer S3 plugin
+6
View File
@@ -1,5 +1,11 @@
line-length = 120
# Vendored third-party code is kept as-is and exempt from our lint rules.
# force-exclude ensures these paths are skipped even when passed explicitly
# (e.g. by pre-commit, which invokes ruff with a list of filenames).
extend-exclude = ["chia/_vendored"]
force-exclude = true
[lint]
preview = true
select = ["ALL"]
+1 -1
View File
@@ -1,5 +1,5 @@
interfaces = []
exclude = ["**/*__pycache__", "**/*egg-info", "**/docs", "**/tests", "**/venv"]
exclude = ["**/*__pycache__", "**/*egg-info", "**/docs", "**/tests", "**/venv", "chia/_vendored"]
source_roots = ["."]
[[modules]]
+1 -1
View File
@@ -6,12 +6,12 @@ import asyncio
import os
from pathlib import Path
import aiosqlite
import click
import zstd
from chia_rs import FullBlock
from chia._tests.util.full_sync import FakePeer, FakeServer, run_sync_test
from chia._vendored import aiosqlite
from chia.cmds.init_funcs import chia_init
from chia.consensus.augmented_chain import AugmentedBlockchain
from chia.consensus.block_body_validation import ForkInfo