"""
This type stub file was generated by pyright.
"""

import sys
from types import TracebackType
from typing import (
    TYPE_CHECKING,
    Any,
    AnyStr,
    Callable,
    Dict,
    Iterator,
    List,
    Optional,
    TextIO,
    Type,
    Union,
)

from pyfakefs.fake_filesystem import FakeFilesystem
from pyfakefs.helpers import AnyPath, AnyString

"""Fake implementations for different file objects.
"""
if TYPE_CHECKING: ...
AnyFileWrapper = Union[
    "FakeFileWrapper",
    "FakeDirWrapper",
    "StandardStreamWrapper",
    "FakePipeWrapper",
]
AnyFile = Union["FakeFile", "FakeDirectory"]

class FakeLargeFileIoException(Exception):
    """Exception thrown on unsupported operations for fake large files.
    Fake large files have a size with no real content.
    """

    def __init__(self, file_path: str) -> None: ...

class FakeFile:
    """Provides the appearance of a real file.

    Attributes currently faked out:
      * `st_mode`: user-specified, otherwise S_IFREG
      * `st_ctime`: the time.time() timestamp of the file change time (updated
        each time a file's attributes is modified).
      * `st_atime`: the time.time() timestamp when the file was last accessed.
      * `st_mtime`: the time.time() timestamp when the file was last modified.
      * `st_size`: the size of the file
      * `st_nlink`: the number of hard links to the file
      * `st_ino`: the inode number - a unique number identifying the file
      * `st_dev`: a unique number identifying the (fake) file system device
        the file belongs to
      * `st_uid`: always set to USER_ID, which can be changed globally using
            `set_uid`
      * `st_gid`: always set to GROUP_ID, which can be changed globally using
            `set_gid`

    .. note:: The resolution for `st_ctime`, `st_mtime` and `st_atime` in the
        real file system depends on the used file system (for example it is
        only 1s for HFS+ and older Linux file systems, but much higher for
        ext4 and NTFS). This is currently ignored by pyfakefs, which uses
        the resolution of `time.time()`.

        Under Windows, `st_atime` is not updated for performance reasons by
        default. pyfakefs never updates `st_atime` under Windows, assuming
        the default setting.
    """

    stat_types = ...
    def __init__(
        self,
        name: AnyStr,
        st_mode: int = ...,
        contents: Optional[AnyStr] = ...,
        filesystem: Optional[FakeFilesystem] = ...,
        encoding: Optional[str] = ...,
        errors: Optional[str] = ...,
        side_effect: Optional[Callable[[FakeFile], None]] = ...,
    ) -> None:
        """
        Args:
            name: Name of the file/directory, without parent path information
            st_mode: The stat.S_IF* constant representing the file type (i.e.
                stat.S_IFREG, stat.S_IFDIR), and the file permissions.
                If no file type is set (e.g. permission flags only), a
                regular file type is assumed.
            contents: The contents of the filesystem object; should be a string
                or byte object for regular files, and a dict of other
                FakeFile or FakeDirectory objects wih the file names as
                keys for FakeDirectory objects
            filesystem: The fake filesystem where the file is created.
            encoding: If contents is a unicode string, the encoding used
                for serialization.
            errors: The error mode used for encoding/decoding errors.
            side_effect: function handle that is executed when file is written,
                must accept the file object as an argument.
        """
        ...
    @property
    def byte_contents(self) -> Optional[bytes]:
        """Return the contents as raw byte array."""
        ...
    @property
    def contents(self) -> Optional[str]:
        """Return the contents as string with the original encoding."""
        ...
    @property
    def st_ctime(self) -> float:
        """Return the creation time of the fake file."""
        ...
    @st_ctime.setter
    def st_ctime(self, val: float) -> None:
        """Set the creation time of the fake file."""
        ...
    @property
    def st_atime(self) -> float:
        """Return the access time of the fake file."""
        ...
    @st_atime.setter
    def st_atime(self, val: float) -> None:
        """Set the access time of the fake file."""
        ...
    @property
    def st_mtime(self) -> float:
        """Return the modification time of the fake file."""
        ...
    @st_mtime.setter
    def st_mtime(self, val: float) -> None:
        """Set the modification time of the fake file."""
        ...
    def set_large_file_size(self, st_size: int) -> None:
        """Sets the self.st_size attribute and replaces self.content with None.

        Provided specifically to simulate very large files without regards
        to their content (which wouldn't fit in memory).
        Note that read/write operations with such a file raise
            :py:class:`FakeLargeFileIoException`.

        Args:
          st_size: (int) The desired file size

        Raises:
          OSError: if the st_size is not a non-negative integer,
                   or if st_size exceeds the available file system space
        """
        ...
    def is_large_file(self) -> bool:
        """Return `True` if this file was initialized with size
        but no contents.
        """
        ...
    def set_initial_contents(self, contents: AnyStr) -> bool:
        """Sets the file contents and size.
           Called internally after initial file creation.

        Args:
            contents: string, new content of file.

        Returns:
            True if the contents have been changed.

        Raises:
              OSError: if the st_size is not a non-negative integer,
                   or if st_size exceeds the available file system space
        """
        ...
    def set_contents(self, contents: AnyStr, encoding: Optional[str] = ...) -> bool:
        """Sets the file contents and size and increases the modification time.
        Also executes the side_effects if available.

        Args:
          contents: (str, bytes) new content of file.
          encoding: (str) the encoding to be used for writing the contents
                    if they are a unicode string.
                    If not given, the locale preferred encoding is used.

        Returns:
            True if the contents have been changed.

        Raises:
          OSError: if `st_size` is not a non-negative integer,
                   or if it exceeds the available file system space.
        """
        ...
    @property
    def size(self) -> int:
        """Return the size in bytes of the file contents."""
        ...
    @size.setter
    def size(self, st_size: int) -> None:
        """Resizes file content, padding with nulls if new size exceeds the
        old size.

        Args:
          st_size: The desired size for the file.

        Raises:
          OSError: if the st_size arg is not a non-negative integer
                   or if st_size exceeds the available file system space
        """
        ...
    @property
    def path(self) -> AnyStr:
        """Return the full path of the current object."""
        ...
    if sys.version_info >= (3, 12): ...
    def __getattr__(self, item: str) -> Any:
        """Forward some properties to stat_result."""
        ...
    def __setattr__(self, key: str, value: Any) -> None:
        """Forward some properties to stat_result."""
        ...
    def __str__(self) -> str: ...

class FakeNullFile(FakeFile):
    def __init__(self, filesystem: FakeFilesystem) -> None: ...
    @property
    def byte_contents(self) -> bytes: ...
    def set_initial_contents(self, contents: AnyStr) -> bool: ...

class FakeFileFromRealFile(FakeFile):
    """Represents a fake file copied from the real file system.

    The contents of the file are read on demand only.
    """

    def __init__(
        self,
        file_path: str,
        filesystem: FakeFilesystem,
        side_effect: Optional[Callable] = ...,
    ) -> None:
        """
        Args:
            file_path: Path to the existing file.
            filesystem: The fake filesystem where the file is created.

        Raises:
            OSError: if the file does not exist in the real file system.
            OSError: if the file already exists in the fake file system.
        """
        ...
    @property
    def byte_contents(self) -> Optional[bytes]: ...
    def set_contents(self, contents, encoding=...): ...
    def is_large_file(self):  # -> Literal[False]:
        """The contents are never faked."""
        ...

class FakeDirectory(FakeFile):
    """Provides the appearance of a real directory."""

    def __init__(
        self,
        name: str,
        perm_bits: int = ...,
        filesystem: Optional[FakeFilesystem] = ...,
    ) -> None:
        """
        Args:
            name:  name of the file/directory, without parent path information
            perm_bits: permission bits. defaults to 0o777.
            filesystem: if set, the fake filesystem where the directory
                is created
        """
        ...
    def set_contents(self, contents: AnyStr, encoding: Optional[str] = ...) -> bool: ...
    @property
    def entries(self) -> Dict[str, FakeFile]:
        """Return the list of contained directory entries."""
        ...
    @property
    def ordered_dirs(self) -> List[str]:
        """Return the list of contained directory entry names ordered by
        creation order.
        """
        ...
    def add_entry(self, path_object: FakeFile) -> None:
        """Adds a child FakeFile to this directory.

        Args:
            path_object: FakeFile instance to add as a child of this directory.

        Raises:
            OSError: if the directory has no write permission (Posix only)
            OSError: if the file or directory to be added already exists
        """
        ...
    def get_entry(self, pathname_name: str) -> AnyFile:
        """Retrieves the specified child file or directory entry.

        Args:
            pathname_name: The basename of the child object to retrieve.

        Returns:
            The fake file or directory object.

        Raises:
            KeyError: if no child exists by the specified name.
        """
        ...
    def remove_entry(self, pathname_name: str, recursive: bool = ...) -> None:
        """Removes the specified child file or directory.

        Args:
            pathname_name: Basename of the child object to remove.
            recursive: If True (default), the entries in contained directories
                are deleted first. Used to propagate removal errors
                (e.g. permission problems) from contained entries.

        Raises:
            KeyError: if no child exists by the specified name.
            OSError: if user lacks permission to delete the file,
                or (Windows only) the file is open.
        """
        ...
    @property
    def size(self) -> int:
        """Return the total size of all files contained
        in this directory tree.
        """
        ...
    @size.setter
    def size(self, st_size: int) -> None:
        """Setting the size is an error for a directory."""
        ...
    def has_parent_object(self, dir_object: FakeDirectory) -> bool:
        """Return `True` if dir_object is a direct or indirect parent
        directory, or if both are the same object."""
        ...
    def __str__(self) -> str: ...

class FakeDirectoryFromRealDirectory(FakeDirectory):
    """Represents a fake directory copied from the real file system.

    The contents of the directory are read on demand only.
    """

    def __init__(
        self,
        source_path: AnyPath,
        filesystem: FakeFilesystem,
        read_only: bool,
        target_path: Optional[AnyPath] = ...,
    ) -> None:
        """
        Args:
            source_path: Full directory path.
            filesystem: The fake filesystem where the directory is created.
            read_only: If set, all files under the directory are treated
                as read-only, e.g. a write access raises an exception;
                otherwise, writing to the files changes the fake files
                only as usually.
            target_path: If given, the target path of the directory,
                otherwise the target is the same as `source_path`.

        Raises:
            OSError: if the directory does not exist in the real file system
        """
        ...
    @property
    def entries(self) -> Dict[str, FakeFile]:
        """Return the list of contained directory entries, loading them
        if not already loaded."""
        ...
    @property
    def size(self) -> int: ...
    @size.setter
    def size(self, st_size: int) -> None: ...

class FakeFileWrapper:
    """Wrapper for a stream object for use by a FakeFile object.

    If the wrapper has any data written to it, it will propagate to
    the FakeFile object on close() or flush().
    """

    def __init__(
        self,
        file_object: FakeFile,
        file_path: AnyStr,
        update: bool,
        read: bool,
        append: bool,
        delete_on_close: bool,
        filesystem: FakeFilesystem,
        newline: Optional[str],
        binary: bool,
        closefd: bool,
        encoding: Optional[str],
        errors: Optional[str],
        buffering: int,
        raw_io: bool,
        is_stream: bool = ...,
    ) -> None: ...
    def __enter__(self) -> FakeFileWrapper:
        """To support usage of this fake file with the 'with' statement."""
        ...
    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> None:
        """To support usage of this fake file with the 'with' statement."""
        ...
    def get_object(self) -> FakeFile:
        """Return the FakeFile object that is wrapped
        by the current instance.
        """
        ...
    def fileno(self) -> int:
        """Return the file descriptor of the file object."""
        ...
    def close(self) -> None:
        """Close the file."""
        ...
    @property
    def closed(self) -> bool:
        """Simulate the `closed` attribute on file."""
        ...
    def flush(self) -> None:
        """Flush file contents to 'disk'."""
        ...
    def update_flush_pos(self) -> None: ...
    def seek(self, offset: int, whence: int = ...) -> None:
        """Move read/write pointer in 'file'."""
        ...
    def tell(self) -> int:
        """Return the file's current position.

        Returns:
          int, file's current position in bytes.
        """
        ...
    def size(self) -> int:
        """Return the content size in bytes of the wrapped file."""
        ...
    def __getattr__(self, name: str) -> Any: ...
    def __iter__(self) -> Union[Iterator[str], Iterator[bytes]]: ...
    def __next__(self): ...

class StandardStreamWrapper:
    """Wrapper for a system standard stream to be used in open files list."""

    def __init__(self, stream_object: TextIO) -> None: ...
    def get_object(self) -> TextIO: ...
    def fileno(self) -> int:
        """Return the file descriptor of the wrapped standard stream."""
        ...
    def read(self, n: int = ...) -> bytes: ...
    def close(self) -> None:
        """We do not support closing standard streams."""
        ...
    def is_stream(self) -> bool: ...

class FakeDirWrapper:
    """Wrapper for a FakeDirectory object to be used in open files list."""

    def __init__(
        self,
        file_object: FakeDirectory,
        file_path: AnyString,
        filesystem: FakeFilesystem,
    ) -> None: ...
    def get_object(self) -> FakeDirectory:
        """Return the FakeFile object that is wrapped by the current
        instance."""
        ...
    def fileno(self) -> int:
        """Return the file descriptor of the file object."""
        ...
    def close(self) -> None:
        """Close the directory."""
        ...

class FakePipeWrapper:
    """Wrapper for a read or write descriptor of a real pipe object to be
    used in open files list.
    """

    def __init__(
        self, filesystem: FakeFilesystem, fd: int, can_write: bool, mode: str = ...
    ) -> None: ...
    def __enter__(self) -> FakePipeWrapper:
        """To support usage of this fake pipe with the 'with' statement."""
        ...
    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> None:
        """To support usage of this fake pipe with the 'with' statement."""
        ...
    def get_object(self) -> None: ...
    def fileno(self) -> int:
        """Return the fake file descriptor of the pipe object."""
        ...
    def read(self, numBytes: int = ...) -> bytes:
        """Read from the real pipe."""
        ...
    def flush(self) -> None:
        """Flush the real pipe?"""
        ...
    def write(self, contents: bytes) -> int:
        """Write to the real pipe."""
        ...
    def close(self) -> None:
        """Close the pipe descriptor."""
        ...
    def readable(self) -> bool:
        """The pipe end can either be readable or writable."""
        ...
    def writable(self) -> bool:
        """The pipe end can either be readable or writable."""
        ...
    def seekable(self) -> bool:
        """A pipe is not seekable."""
        ...
