Skip to content

Commit

Permalink
Remove atomic writing (#409)
Browse files Browse the repository at this point in the history
Remove atomic writes due to issues users are facing:
- #383 and #384
- #404
- #399
  • Loading branch information
hukkin committed Aug 25, 2023
1 parent 54431f5 commit feb6869
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 48 deletions.
12 changes: 4 additions & 8 deletions src/mdformat/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@
from typing import Any

from mdformat._conf import DEFAULT_OPTS
from mdformat._util import (
EMPTY_MAP,
NULL_CTX,
atomic_write,
build_mdit,
detect_newline_type,
)
from mdformat._util import EMPTY_MAP, NULL_CTX, build_mdit, detect_newline_type
from mdformat.renderer import MDRenderer


Expand Down Expand Up @@ -75,4 +69,6 @@ def file(
newline = detect_newline_type(
original_md, options.get("end_of_line", DEFAULT_OPTS["end_of_line"])
)
atomic_write(f, formatted_md, newline)
formatted_md = formatted_md.replace("\n", newline)
if formatted_md != original_md:
f.write_bytes(formatted_md.encode())
22 changes: 6 additions & 16 deletions src/mdformat/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,17 @@
import itertools
import logging
from pathlib import Path
import re
import shutil
import sys
import textwrap

import mdformat
from mdformat._compat import importlib_metadata
from mdformat._conf import DEFAULT_OPTS, InvalidConfError, read_toml_opts
from mdformat._util import atomic_write, detect_newline_type, is_md_equal
from mdformat._util import detect_newline_type, is_md_equal
import mdformat.plugins
import mdformat.renderer

# Match "\r" and "\n" characters that are not part of a "\r\n" sequence
RE_NON_CRLF_LINE_END = re.compile(r"(?:[^\r]|^)\n|\r(?:[^\n]|\Z)")


class RendererWarningPrinter(logging.Handler):
def emit(self, record: logging.LogRecord) -> None:
Expand Down Expand Up @@ -82,14 +78,10 @@ def run(cli_args: Sequence[str]) -> int: # noqa: C901
_filename=path_str,
)
newline = detect_newline_type(original_str, opts["end_of_line"])
formatted_str = formatted_str.replace("\n", newline)

if opts["check"]:
original_str_lf_eol = original_str.replace("\r\n", "\n").replace("\r", "\n")
if (
(formatted_str != original_str_lf_eol)
or (newline == "\n" and "\r" in original_str)
or (newline == "\r\n" and RE_NON_CRLF_LINE_END.search(original_str))
):
if formatted_str != original_str:
format_errors_found = True
print_error(f'File "{path_str}" is not formatted.')
else:
Expand All @@ -111,12 +103,10 @@ def run(cli_args: Sequence[str]) -> int: # noqa: C901
)
return 1
if path:
atomic_write(path, formatted_str, newline)
if formatted_str != original_str:
path.write_bytes(formatted_str.encode())
else:
with open(
sys.stdout.fileno(), "w", closefd=False, newline=newline
) as stdout:
stdout.write(formatted_str)
sys.stdout.buffer.write(formatted_str.encode())
if format_errors_found:
return 1
return 0
Expand Down
24 changes: 0 additions & 24 deletions src/mdformat/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

from collections.abc import Iterable, Mapping
from contextlib import nullcontext
import filecmp
import os
from pathlib import Path
import re
import tempfile
from types import MappingProxyType
from typing import Any, Literal

Expand Down Expand Up @@ -106,26 +102,6 @@ def is_md_equal(
return html_texts["md1"] == html_texts["md2"]


def atomic_write(path: Path, text: str, newline: str) -> None:
"""A function for atomic writes to a file.
Writes a temporary file first and then replaces the original file
with the temporary one. This is to avoid a moment where only empty
or partial content exists on disk.
"""
fd, tmp_path = tempfile.mkstemp(dir=path.parent)
try:
with open(fd, "w", encoding="utf-8", newline=newline) as f:
f.write(text)
if filecmp.cmp(tmp_path, path, shallow=False):
os.remove(tmp_path)
else:
os.replace(tmp_path, path)
except BaseException: # pragma: no cover
os.remove(tmp_path)
raise


def detect_newline_type(md: str, eol_setting: str) -> Literal["\n", "\r\n"]:
"""Returns the newline-character to be used for output.
Expand Down

0 comments on commit feb6869

Please sign in to comment.