import pathlib
from builtins import set as _set
from collections.abc import Iterable, Iterator
from typing import IO, Any, List, Optional, Tuple, Union, overload

from rdflib import query
from rdflib.collection import Collection
from rdflib.paths import Path
from rdflib.resource import Resource
from rdflib.term import BNode, Identifier, Node

class Graph(Node):
    base: Any = ...
    context_aware: bool = ...
    formula_aware: bool = ...
    default_union: bool = ...
    def __init__(
        self,
        store: str = ...,
        identifier: Any | None = ...,
        namespace_manager: Any | None = ...,
        base: Any | None = ...,
    ) -> None: ...
    store: Any = ...
    identifier: Any = ...
    namespace_manager: Any = ...
    def toPython(self) -> str: ...
    def destroy(self, configuration: Any) -> None: ...
    def commit(self) -> None: ...
    def rollback(self) -> None: ...
    def open(self, configuration: Any, create: bool = ...) -> Any: ...
    def close(self, commit_pending_transaction: bool = ...) -> None: ...
    def add(self, triple: Any) -> None: ...
    def addN(self, quads: Any) -> None: ...
    def remove(self, triple: Any) -> None: ...
    def triples(
        self,
        triple: tuple[
            str | Identifier | None,
            str | Identifier | None,
            Identifier | None,
        ],
    ) -> Iterator[tuple[Identifier, Identifier, Identifier]]: ...
    def __getitem__(
        self, item: slice | Path | Node
    ) -> Iterator[
        tuple[Identifier, Identifier, Identifier] | tuple[Identifier, identifier] | Node
    ]: ...
    def __contains__(self, triple: Any) -> bool: ...
    def __add__(self, other: Any) -> Graph: ...
    def set(self, triple: Any) -> None: ...
    def subjects(self, predicate: Any | None = ..., object: Any | None = ...) -> Iterable[Node]: ...
    def predicates(self, subject: Any | None = ..., object: Any | None = ...) -> Iterable[Node]: ...
    def objects(
        self, subject: Any | None = ..., predicate: Any | None = ...
    ) -> Iterable[Identifier]: ...
    def subject_predicates(self, object: Any | None = ...) -> None: ...
    def subject_objects(self, predicate: Any | None = ...) -> None: ...
    def predicate_objects(self, subject: Any | None = ...) -> None: ...
    def triples_choices(self, triple: Any, context: Any | None = ...) -> None: ...
    def value(
        self,
        subject: Any | None = ...,
        predicate: Any = ...,
        object: Any | None = ...,
        default: Any | None = ...,
        any: bool = ...,
    ) -> Any: ...
    def label(self, subject: Any, default: str = ...) -> Any: ...
    def preferredLabel(
        self,
        subject: Any,
        lang: Any | None = ...,
        default: Any | None = ...,
        labelProperties: Any = ...,
    ) -> list[tuple[Any, Any]]: ...
    def comment(self, subject: Any, default: str = ...) -> Any: ...
    def items(self, list: Any) -> Iterator[Any]: ...
    def transitiveClosure(self, func: Any, arg: Any, seen: Any | None = ...) -> Iterator[Any]: ...
    def transitive_objects(
        self, subject: Any, property: Any, remember: Any | None = ...
    ) -> Iterator[Any]: ...
    def transitive_subjects(
        self, predicate: Any, object: Any, remember: Any | None = ...
    ) -> Iterator[Any]: ...
    def seq(self, subject: Any) -> Seq | None: ...
    def qname(self, uri: Any) -> Any: ...
    def compute_qname(self, uri: Any, generate: bool = ...) -> Any: ...
    def bind(
        self, prefix: Any, namespace: Any, override: bool = ..., replace: bool = ...
    ) -> Any: ...
    def namespaces(self) -> Iterator[tuple[Any, Any]]: ...
    def absolutize(self, uri: Any, defrag: int = ...) -> Any: ...

    # no destination and non-None positional encoding
    @overload
    def serialize(
        self,
        destination: None,
        format: str,
        base: str | None,
        encoding: str,
        **args: Any,
    ) -> bytes: ...

    # no destination and non-None keyword encoding
    @overload
    def serialize(
        self,
        destination: None = ...,
        format: str = ...,
        base: str | None = ...,
        *,
        encoding: str,
        **args: Any,
    ) -> bytes: ...

    # no destination and None encoding
    @overload
    def serialize(
        self,
        destination: None = ...,
        format: str = ...,
        base: str | None = ...,
        encoding: None = ...,
        **args: Any,
    ) -> str: ...

    # non-None destination
    @overload
    def serialize(
        self,
        destination: str | pathlib.PurePath | IO[bytes],
        format: str = ...,
        base: str | None = ...,
        encoding: str | None = ...,
        **args: Any,
    ) -> "Graph": ...

    # fallback
    @overload
    def serialize(
        self,
        destination: str | pathlib.PurePath | IO[bytes] | None = ...,
        format: str = ...,
        base: str | None = ...,
        encoding: str | None = ...,
        **args: Any,
    ) -> Union[bytes, str, "Graph"]: ...
    def parse(
        self,
        source: Any | None = ...,
        publicID: Any | None = ...,
        format: str | None = ...,
        location: Any | None = ...,
        file: Any | None = ...,
        data: Any | None = ...,
        **args: Any,
    ) -> "Graph": ...
    def load(self, source: Any, publicID: Any | None = ..., format: str = ...) -> "Graph": ...
    def query(
        self,
        query_object: Any,
        processor: str = ...,
        result: str = ...,
        initNs: Any | None = ...,
        initBindings: Any | None = ...,
        use_store_provided: bool = ...,
        **kwargs: Any,
    ) -> query.Result: ...
    def update(
        self,
        update_object: Any,
        processor: str = ...,
        initNs: Any | None = ...,
        initBindings: Any | None = ...,
        use_store_provided: bool = ...,
        **kwargs: Any,
    ) -> Any: ...
    def n3(self) -> str: ...
    def isomorphic(self, other: Any) -> bool: ...
    def connected(self) -> bool: ...
    def all_nodes(self) -> _set[Node]: ...
    def collection(self, identifier: Any) -> Collection: ...
    def resource(self, identifier: Any) -> Resource: ...
    def skolemize(
        self,
        new_graph: Any | None = ...,
        bnode: Any | None = ...,
        authority: Any | None = ...,
        basepath: Any | None = ...,
    ) -> Graph: ...
    def de_skolemize(self, new_graph: Any | None = ..., uriref: Any | None = ...) -> Graph: ...

class ConjunctiveGraph(Graph):
    context_aware: bool = ...
    default_union: bool = ...
    default_context: Any = ...
    def __init__(
        self,
        store: str = ...,
        identifier: Any | None = ...,
        default_graph_base: Any | None = ...,
    ) -> None: ...
    def add(self, triple_or_quad: Any) -> None: ...
    def addN(self, quads: Any) -> None: ...
    def remove(self, triple_or_quad: Any) -> None: ...
    # def triples(self, triple_or_quad: Tuple[Optional[Union[str, BNode]], Optional[Union[str, BNode]], Optional[BNode]], context: Tuple[Optional[Union[str, BNode]], Optional[Union[str, BNode]], Optional[BNode]]) -> Iterator[Tuple[Identifier, Identifier, Identifier]]: ...
    def quads(self, triple_or_quad: Any | None = ...) -> None: ...
    def triples_choices(self, triple: Any, context: Any | None = ...) -> None: ...
    def contexts(self, triple: Any | None = ...) -> None: ...
    def get_context(
        self,
        identifier: Node | str | None,
        quoted: bool = ...,
        base: str | None = ...,
    ) -> Graph: ...
    def remove_context(self, context: Any) -> None: ...
    def context_id(self, uri: Any, context_id: Any | None = ...) -> Any: ...
    def parse(
        self,
        source: Any | None = ...,
        publicID: Any | None = ...,
        format: str | None = ...,
        location: Any | None = ...,
        file: Any | None = ...,
        data: Any | None = ...,
        **args: Any,
    ) -> Graph: ...

class Seq:
    def __init__(self, graph: Graph, subject: Any) -> None: ...
    def toPython(self) -> Seq: ...
