import json
import re
import types
from _typeshed import Incomplete
from collections.abc import Iterable
from typing import ClassVar

from pony.utils import localbase

class DBException(Exception):
    def __init__(exc, original_exc, *args) -> None: ...

class Warning(DBException): ...
class Error(DBException): ...
class InterfaceError(Error): ...
class DatabaseError(Error): ...
class DataError(DatabaseError): ...
class OperationalError(DatabaseError): ...
class IntegrityError(DatabaseError): ...
class InternalError(DatabaseError): ...
class ProgrammingError(DatabaseError): ...
class NotSupportedError(DatabaseError): ...

def wrap_dbapi_exceptions(func, provider, *args, **kwargs): ...
def unexpected_args(attr, args) -> None: ...

version_re: re.Pattern[str]

def get_version_tuple(s: str): ...

class DBAPIProvider:
    paramstyle: ClassVar[str]
    quote_char: ClassVar[str]
    max_params_count: ClassVar[int]
    max_name_len: ClassVar[int]
    table_if_not_exists_syntax: ClassVar[bool]
    index_if_not_exists_syntax: ClassVar[bool]
    max_time_precision: ClassVar[int]
    default_time_precision: ClassVar[int]
    uint64_support: ClassVar[bool]
    varchar_default_max_len: ClassVar[int | None]
    dialect: ClassVar[str | None]
    dbapi_module: ClassVar[types.ModuleType | None]
    dbschema_cls: ClassVar[type | None]
    translator_cls: ClassVar[type | None]
    sqlbuilder_cls: ClassVar[type | None]
    array_converter_cls: ClassVar[type | None]
    name_before_table: ClassVar[str]
    default_schema_name: ClassVar[str | None]
    fk_types: ClassVar[dict[str, str]]
    converter_classes: Incomplete
    def __init__(provider, _database, *args, **kwargs) -> None: ...
    def inspect_connection(provider, connection) -> None: ...
    def normalize_name(provider, name): ...
    def get_default_entity_table_name(provider, entity): ...
    def get_default_m2m_table_name(provider, attr, reverse): ...
    def get_default_column_names(provider, attr, reverse_pk_columns=None): ...
    def get_default_m2m_column_names(provider, entity): ...
    def get_default_index_name(
        provider, table_name, column_names, is_pk: bool = False, is_unique: bool = False, m2m: bool = False
    ): ...
    def get_default_fk_name(provider, child_table_name, parent_table_name, child_column_names): ...
    def split_table_name(provider, table_name): ...
    def base_name(provider, name): ...
    def quote_name(provider, name: str | Iterable[str]) -> str: ...
    def format_table_name(provider, name): ...
    def normalize_vars(provider, vars, vartypes) -> None: ...
    def ast2sql(provider, ast): ...
    def should_reconnect(provider, exc): ...
    def connect(provider): ...
    def set_transaction_mode(provider, connection, cache) -> None: ...
    def commit(provider, connection, cache=None) -> None: ...
    def rollback(provider, connection, cache=None) -> None: ...
    def release(provider, connection, cache=None) -> None: ...
    def drop(provider, connection, cache=None) -> None: ...
    def disconnect(provider) -> None: ...
    def execute(provider, cursor, sql, arguments=None, returning_id: bool = False): ...
    def get_converter_by_py_type(provider, py_type): ...
    def get_converter_by_attr(provider, attr): ...
    def get_pool(provider, *args, **kwargs): ...
    def table_exists(provider, connection, table_name, case_sensitive: bool = True) -> None: ...
    def index_exists(provider, connection, table_name, index_name, case_sensitive: bool = True) -> None: ...
    def fk_exists(provider, connection, table_name, fk_name, case_sensitive: bool = True) -> None: ...
    def table_has_data(provider, connection, table_name): ...
    def disable_fk_checks(provider, connection) -> None: ...
    def enable_fk_checks(provider, connection, prev_state) -> None: ...
    def drop_table(provider, connection, table_name) -> None: ...

class Pool(localbase):
    forked_connections: list[tuple[Incomplete, int | None]]
    dbapi_module: types.ModuleType
    args: tuple[Incomplete, ...]
    kwargs: dict[str, Incomplete]
    con: Incomplete
    pid: int | None
    def __init__(pool, dbapi_module: types.ModuleType, *args, **kwargs) -> None: ...
    def connect(pool) -> tuple[Incomplete, bool]: ...
    def release(pool, con) -> None: ...
    def drop(pool, con) -> None: ...
    def disconnect(pool) -> None: ...

class Converter:
    EQ: str
    NE: str
    optimistic: bool
    def __deepcopy__(converter, memo): ...
    def __init__(converter, provider, py_type, attr=None) -> None: ...
    def init(converter, kwargs) -> None: ...
    def validate(converter, val, obj=None): ...
    def py2sql(converter, val): ...
    def sql2py(converter, val): ...
    def val2dbval(self, val, obj=None): ...
    def dbval2val(self, dbval, obj=None): ...
    def dbvals_equal(self, x, y): ...
    def get_sql_type(converter, attr=None): ...
    def get_fk_type(converter, sql_type): ...

class NoneConverter(Converter):
    def __init__(converter, provider, py_type, attr=None) -> None: ...
    def get_sql_type(converter, attr=None) -> None: ...
    def get_fk_type(converter, sql_type) -> None: ...

class BoolConverter(Converter):
    def validate(converter, val, obj=None): ...
    def sql2py(converter, val): ...
    def sql_type(converter): ...

class StrConverter(Converter):
    def __init__(converter, provider, py_type, attr=None) -> None: ...
    def init(converter, kwargs) -> None: ...
    def validate(converter, val, obj=None): ...
    def sql_type(converter): ...

class IntConverter(Converter):
    signed_types: Incomplete
    unsigned_types: Incomplete
    def init(converter, kwargs) -> None: ...
    def validate(converter, val, obj=None): ...
    def sql2py(converter, val): ...
    def sql_type(converter): ...

class RealConverter(Converter):
    EQ: str
    NE: str
    default_tolerance: float
    optimistic: bool
    def init(converter, kwargs) -> None: ...
    def validate(converter, val, obj=None): ...
    def dbvals_equal(converter, x, y): ...
    def sql2py(converter, val): ...
    def sql_type(converter): ...

class DecimalConverter(Converter):
    def __init__(converter, provider, py_type, attr=None) -> None: ...
    def init(converter, kwargs) -> None: ...
    def validate(converter, val, obj=None): ...
    def sql2py(converter, val): ...
    def sql_type(converter): ...

class BlobConverter(Converter):
    def validate(converter, val, obj=None): ...
    def sql2py(converter, val): ...
    def sql_type(converter): ...

class DateConverter(Converter):
    def validate(converter, val, obj=None): ...
    def sql2py(converter, val): ...
    def sql_type(converter): ...

class ConverterWithMicroseconds(Converter):
    def __init__(converter, provider, py_type, attr=None) -> None: ...
    def init(converter, kwargs) -> None: ...
    def round_microseconds_to_precision(converter, microseconds, precision): ...
    def sql_type(converter): ...

class TimeConverter(ConverterWithMicroseconds):
    sql_type_name: ClassVar[str]
    def validate(converter, val, obj=None): ...
    def sql2py(converter, val): ...

class TimedeltaConverter(ConverterWithMicroseconds):
    sql_type_name: ClassVar[str]
    def validate(converter, val, obj=None): ...
    def sql2py(converter, val): ...

class DatetimeConverter(ConverterWithMicroseconds):
    sql_type_name: ClassVar[str]
    def validate(converter, val, obj=None): ...
    def sql2py(converter, val): ...

class UuidConverter(Converter):
    def __init__(converter, provider, py_type, attr=None) -> None: ...
    def validate(converter, val, obj=None): ...
    def py2sql(converter, val): ...
    sql2py = validate
    def sql_type(converter): ...

class JsonConverter(Converter):
    json_kwargs: Incomplete

    class JsonEncoder(json.JSONEncoder):
        def default(converter, obj): ...

    def validate(converter, val, obj=None): ...
    def val2dbval(converter, val, obj=None): ...
    def dbval2val(converter, dbval, obj=None): ...
    def dbvals_equal(converter, x, y): ...
    def sql_type(converter): ...

class ArrayConverter(Converter):
    array_types: Incomplete
    def __init__(converter, provider, py_type, attr=None) -> None: ...
    def validate(converter, val, obj=None): ...
    def dbval2val(converter, dbval, obj=None): ...
    def val2dbval(converter, val, obj=None): ...
    def sql_type(converter): ...
