from _typeshed import Incomplete
from typing import Any, overload
from typing_extensions import Self

from psycopg2._psycopg import connection, cursor

class Range:
    def __init__(
        self, lower: Incomplete | None = None, upper: Incomplete | None = None, bounds: str = "[)", empty: bool = False
    ) -> None: ...
    @property
    def lower(self): ...
    @property
    def upper(self): ...
    @property
    def isempty(self) -> bool: ...
    @property
    def lower_inf(self) -> bool: ...
    @property
    def upper_inf(self) -> bool: ...
    @property
    def lower_inc(self) -> bool: ...
    @property
    def upper_inc(self) -> bool: ...
    def __contains__(self, x) -> bool: ...
    def __bool__(self) -> bool: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __hash__(self) -> int: ...
    def __lt__(self, other: Range) -> bool: ...
    def __le__(self, other: Range) -> bool: ...
    def __gt__(self, other: Range) -> bool: ...
    def __ge__(self, other: Range) -> bool: ...

def register_range(
    pgrange: str, pyrange: str | Range, conn_or_curs: connection | cursor, globally: bool = False
) -> RangeCaster: ...

class RangeAdapter:
    name: str  # this is None here but MUST be str in subclasses
    adapted: Range
    def __init__(self, adapted: Range) -> None: ...
    def __conform__(self, proto) -> Self | None: ...
    def prepare(self, conn: connection | None) -> None: ...
    def getquoted(self) -> bytes: ...

class RangeCaster:
    adapter: type[RangeAdapter]
    range: type[Range]
    subtype_oid: Any
    typecaster: Any
    array_typecaster: Any
    def __init__(
        self, pgrange: str | RangeAdapter, pyrange: str | Range, oid: int, subtype_oid: int, array_oid: int | None = None
    ) -> None: ...
    @overload
    def parse(self, s: None, cur: cursor | None = None) -> None: ...
    @overload
    def parse(self, s: str, cur: cursor | None = None) -> Range: ...

class NumericRange(Range): ...
class DateRange(Range): ...
class DateTimeRange(Range): ...
class DateTimeTZRange(Range): ...

class NumberRangeAdapter(RangeAdapter):
    def getquoted(self) -> bytes: ...

int4range_caster: RangeCaster
int8range_caster: RangeCaster
numrange_caster: RangeCaster
daterange_caster: RangeCaster
tsrange_caster: RangeCaster
tstzrange_caster: RangeCaster
