from _typeshed import BytesPath, StrOrBytesPath, StrPath
from collections.abc import Callable, Generator, Iterable
from os import PathLike
from types import TracebackType
from typing import IO, Any, NoReturn, TypeVar, overload
from typing_extensions import Self

_StrPathT = TypeVar("_StrPathT", bound=StrPath)
_BytesPathT = TypeVar("_BytesPathT", bound=BytesPath)

def mkdir_p(path: StrOrBytesPath) -> None: ...
def rotate_file(filename: PathLike[str], *, keep: int = 5) -> None: ...

class FilePerms:
    user: str
    group: str
    other: str
    def __init__(self, user: str = "", group: str = "", other: str = "") -> None: ...
    @classmethod
    def from_int(cls, i: int) -> Self: ...
    @classmethod
    def from_path(cls, path: StrOrBytesPath) -> Self: ...
    def __int__(self) -> int: ...

def atomic_save(dest_path: str, **kwargs) -> AtomicSaver: ...

class AtomicSaver:
    dest_path: str
    overwrite: bool
    file_perms: int | None
    overwrite_part: bool
    part_filename: str | None
    rm_part_on_exc: bool
    text_mode: bool
    buffering: int
    dest_dir: str
    part_path: str
    mode: str
    open_flags: int
    part_file: str | None
    def __init__(self, dest_path: str, **kwargs) -> None: ...
    def setup(self) -> None: ...
    def __enter__(self) -> IO[Any] | None: ...
    def __exit__(
        self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
    ) -> None: ...

def iter_find_files(
    directory: str,
    patterns: str | Iterable[str],
    ignored: str | Iterable[str] | None = None,
    include_dirs: bool = False,
    max_depth: int | None = None,
) -> Generator[str]: ...

@overload
def copy_tree(
    src: _StrPathT, dst: _StrPathT, symlinks: bool = False, ignore: Callable[[_StrPathT, list[str]], Iterable[str]] | None = None
) -> None: ...
@overload
def copy_tree(
    src: _BytesPathT,
    dst: _BytesPathT,
    symlinks: bool = False,
    ignore: Callable[[_BytesPathT, list[bytes]], Iterable[bytes]] | None = None,
) -> None: ...

copytree = copy_tree

class DummyFile:
    name: StrOrBytesPath
    mode: str
    closed: bool
    errors: None
    isatty: bool
    encoding: None
    newlines: None
    softspace: int
    def __init__(self, path: StrOrBytesPath, mode: str = "r", buffering: int | None = None) -> None: ...
    def close(self) -> None: ...
    def fileno(self) -> int: ...
    def flush(self) -> None: ...
    def next(self) -> NoReturn: ...
    def read(self, size: int = 0) -> str: ...
    def readline(self, size: int = 0) -> str: ...
    def readlines(self, size: int = 0) -> list[str]: ...
    def seek(self) -> None: ...
    def tell(self) -> int: ...
    def truncate(self) -> None: ...
    def write(self, string: str) -> None: ...
    def writelines(self, list_of_strings: list[str]) -> None: ...
    def __next__(self) -> NoReturn: ...
    def __enter__(self) -> None: ...
    def __exit__(self, exc_type, exc_val, exc_tb) -> None: ...

__all__ = ["mkdir_p", "atomic_save", "AtomicSaver", "FilePerms", "iter_find_files", "copytree"]
