Repository: home-assistant/core
File: homeassistant/util/file.py (Python)

Code before:

_LOGGER = logging.getLogger(__name__)


class WriteError(HomeAssistantError):
    """Error writing the data."""


def write_utf8_file_atomic(
    filename: str, utf8_data: bytes | str, private: bool = False, mode: str = "w"
) -> None:
    """Write a file and rename it into place using atomicwrites.

    Writes all or nothing.

    This function uses fsync under the hood. It should
    only be used to write mission critical files as
    fsync can block for a few seconds or longer is the
    disk is busy.

    Using this function frequently will significantly
    negatively impact performance.
    """
    encoding = "utf-8" if "b" not in mode else None
    try:
        with AtomicWriter(
            filename, mode=mode, overwrite=True, encoding=encoding
        ).open() as fdesc:
            if not private:
                os.fchmod(fdesc.fileno(), 0o644)
            fdesc.write(utf8_data)
    except OSError as error:
        _LOGGER.exception("Saving file failed: %s", filename)
        raise WriteError(error) from error


def write_utf8_file(
    filename: str, utf8_data: bytes | str, private: bool = False, mode: str = "w"
) -> None:
    """Write a file and rename it into place.

    Writes all or nothing.
    """
    tmp_filename = ""
    encoding = "utf-8" if "b" not in mode else None
    try:
        # Modern versions of Python tempfile create this file with mode 0o600
        with tempfile.NamedTemporaryFile(
            mode=mode, encoding=encoding, dir=os.path.dirname(filename), delete=False
        ) as fdesc:
            fdesc.write(utf8_data)

Review comment (bug):
I think mypy is incorrect:
https://github.com/home-assistant-libs/python-atomicwrites-homeassistant/blob/c8a921e0d50f9a733b88532aeb3e1ef0e0257fde/atomicwrites/__init__.py#L114-L136

I suggest we disable the type error for this line. Also add a code comment why we disable the type error.

Code after:

_LOGGER = logging.getLogger(__name__)


class WriteError(HomeAssistantError):
    """Error writing the data."""


def write_utf8_file_atomic(
    filename: str, utf8_data: bytes | str, private: bool = False, mode: str = "w"
) -> None:
    """Write a file and rename it into place using atomicwrites.

    Writes all or nothing.

    This function uses fsync under the hood. It should
    only be used to write mission critical files as
    fsync can block for a few seconds or longer is the
    disk is busy.

    Using this function frequently will significantly
    negatively impact performance.
    """
    encoding = "utf-8" if "b" not in mode else None
    try:
        with AtomicWriter(  # type: ignore[call-arg]  # atomicwrites-stubs is outdated, encoding is a valid kwarg
            filename, mode=mode, overwrite=True, encoding=encoding
        ).open() as fdesc:
            if not private:
                os.fchmod(fdesc.fileno(), 0o644)
            fdesc.write(utf8_data)
    except OSError as error:
        _LOGGER.exception("Saving file failed: %s", filename)
        raise WriteError(error) from error


def write_utf8_file(
    filename: str, utf8_data: bytes | str, private: bool = False, mode: str = "w"
) -> None:
    """Write a file and rename it into place.

    Writes all or nothing.
    """
    tmp_filename = ""
    encoding = "utf-8" if "b" not in mode else None
    try:
        # Modern versions of Python tempfile create this file with mode 0o600
        with tempfile.NamedTemporaryFile(
            mode=mode, encoding=encoding, dir=os.path.dirname(filename), delete=False
        ) as fdesc:
            fdesc.write(utf8_data)