

class Index:
    def collect() -> list[Indexable]: ...
    def add_object(obj: Indexable): ...
    def add_object_many(objects: list[Indexable]): ...
    def reduce(**kwargs): ...
    def reduced(**kwargs) -> FilteredIndex: ...
    def reduced_query(query: PyQueryExpr) -> FilteredIndex: ...
    def get_by_attribute(**kwargs): ...
    def union_with(other: Index): ...

class FilteredIndex:
    def reduced(**kwargs) -> FilteredIndex: ...
    def reduced_query(query: PyQueryExpr) -> FilteredIndex: ...
    def collect() -> list[Indexable]: ...
    def rebase() -> Index: ...

class PyQueryExpr:
    def and_(queries: list[PyQueryExpr]) -> PyQueryExpr: ...
    def or_(queries: list[PyQueryExpr]) -> PyQueryExpr: ...
    def not_(queries: PyQueryExpr) -> PyQueryExpr: ...

    def eq(attr: str, value: any) -> PyQueryExpr: ...
    def in_(attr: str, values: list[any]) -> PyQueryExpr: ...
    def ne(attr: str, value: any) -> PyQueryExpr: ...

    def gt(attr: str, value: int | float) -> PyQueryExpr: ...
    def ge(attr: str, value: int | float) -> PyQueryExpr: ...
    def lt(attr: str, value: int | float) -> PyQueryExpr: ...
    def le(attr: str, value: int | float) -> PyQueryExpr: ...
    def bt(attr: str, lower: int | float, upper: int | float) -> PyQueryExpr: ...

class Indexable: ...
