from _typeshed import Incomplete
from collections.abc import Callable as Callable
from types import TracebackType
from typing import Any, Protocol, TypeVar

ExitException = tuple[type[BaseException] | None, BaseException | None, TracebackType | None]
Self = TypeVar('Self', bound='DicomIO')

class ReadableBuffer(Protocol):
    def read(self, size: int = ..., /) -> bytes: ...
    def seek(self, offset: int, whence: int = ..., /) -> int: ...
    def tell(self) -> int: ...

class WriteableBuffer(Protocol):
    def seek(self, offset: int, whence: int = ..., /) -> int: ...
    def tell(self) -> int: ...
    def write(self, b: bytes | bytearray | memoryview, /) -> int: ...

class DicomIO:
    def __init__(self, buffer: ReadableBuffer | WriteableBuffer) -> None: ...
    def close(self, *args: Any, **kwargs: Any) -> Any: ...
    def __enter__(self) -> Self: ...
    def __exit__(self, *exc_info: ExitException) -> None: ...
    @property
    def is_little_endian(self) -> bool: ...
    @is_little_endian.setter
    def is_little_endian(self, value: bool) -> None: ...
    @property
    def is_implicit_VR(self) -> bool: ...
    @is_implicit_VR.setter
    def is_implicit_VR(self, value: bool) -> None: ...
    @property
    def name(self) -> str | None: ...
    @name.setter
    def name(self, name: str) -> None: ...
    @property
    def parent(self) -> ReadableBuffer | WriteableBuffer: ...
    def read(self, size: int = -1, /) -> bytes: ...
    def read_exact(self, length: int, nr_retries: int = 3) -> bytes: ...
    def read_tag(self) -> tuple[int, int]: ...
    def read_UL(self) -> int: ...
    def read_US(self) -> int: ...
    def seek(self, offset: int, whence: int = ..., /) -> int: ...
    def tell(self) -> int: ...
    def write(self, b: bytes | bytearray | memoryview, /) -> int: ...
    def write_tag(self, tag: int) -> None: ...
    def write_UL(self, val: int) -> None: ...
    def write_US(self, val: int) -> None: ...

class DicomFileLike(DicomIO): ...

def DicomFile(*args: Any, **kwargs: Any) -> DicomFileLike: ...

class DicomBytesIO(DicomIO):
    getvalue: Incomplete
    def __init__(self, initial_bytes: bytes | bytearray | memoryview = b'') -> None: ...
