replace atomicwrites with os.replace

This commit is contained in:
Anthony Sottile 2022-07-08 16:01:14 -04:00
parent 966d4fb3e4
commit 4cd0322ca1
5 changed files with 26 additions and 70 deletions

View File

@ -67,7 +67,6 @@ repos:
- attrs>=19.2.0 - attrs>=19.2.0
- packaging - packaging
- tomli - tomli
- types-atomicwrites
- types-pkg_resources - types-pkg_resources
- repo: local - repo: local
hooks: hooks:

View File

@ -0,0 +1 @@
Replace `atomicwrites <https://github.com/untitaker/python-atomicwrites>`__ dependency on windows with `os.replace`.

View File

@ -46,7 +46,6 @@ install_requires =
packaging packaging
pluggy>=0.12,<2.0 pluggy>=0.12,<2.0
py>=1.8.2 py>=1.8.2
atomicwrites>=1.0;sys_platform=="win32"
colorama;sys_platform=="win32" colorama;sys_platform=="win32"
importlib-metadata>=0.12;python_version<"3.8" importlib-metadata>=0.12;python_version<"3.8"
tomli>=1.0.0;python_version<"3.11" tomli>=1.0.0;python_version<"3.11"

View File

@ -302,53 +302,29 @@ def _write_pyc_fp(
fp.write(marshal.dumps(co)) fp.write(marshal.dumps(co))
if sys.platform == "win32": def _write_pyc(
from atomicwrites import atomic_write state: "AssertionState",
co: types.CodeType,
def _write_pyc( source_stat: os.stat_result,
state: "AssertionState", pyc: Path,
co: types.CodeType, ) -> bool:
source_stat: os.stat_result, proc_pyc = f"{pyc}.{os.getpid()}"
pyc: Path, try:
) -> bool: with open(proc_pyc, "wb") as fp:
try:
with atomic_write(os.fspath(pyc), mode="wb", overwrite=True) as fp:
_write_pyc_fp(fp, source_stat, co)
except OSError as e:
state.trace(f"error writing pyc file at {pyc}: {e}")
# we ignore any failure to write the cache file
# there are many reasons, permission-denied, pycache dir being a
# file etc.
return False
return True
else:
def _write_pyc(
state: "AssertionState",
co: types.CodeType,
source_stat: os.stat_result,
pyc: Path,
) -> bool:
proc_pyc = f"{pyc}.{os.getpid()}"
try:
fp = open(proc_pyc, "wb")
except OSError as e:
state.trace(f"error writing pyc file at {proc_pyc}: errno={e.errno}")
return False
try:
_write_pyc_fp(fp, source_stat, co) _write_pyc_fp(fp, source_stat, co)
os.rename(proc_pyc, pyc) except OSError as e:
except OSError as e: state.trace(f"error writing pyc file at {proc_pyc}: errno={e.errno}")
state.trace(f"error writing pyc file at {pyc}: {e}") return False
# we ignore any failure to write the cache file
# there are many reasons, permission-denied, pycache dir being a try:
# file etc. os.replace(proc_pyc, pyc)
return False except OSError as e:
finally: state.trace(f"error writing pyc file at {pyc}: {e}")
fp.close() # we ignore any failure to write the cache file
return True # there are many reasons, permission-denied, pycache dir being a
# file etc.
return False
return True
def _rewrite_test(fn: Path, config: Config) -> Tuple[os.stat_result, types.CodeType]: def _rewrite_test(fn: Path, config: Config) -> Tuple[os.stat_result, types.CodeType]:

View File

@ -1009,7 +1009,7 @@ class TestAssertionRewriteHookDetails:
) )
assert pytester.runpytest().ret == 0 assert pytester.runpytest().ret == 0
def test_write_pyc(self, pytester: Pytester, tmp_path, monkeypatch) -> None: def test_write_pyc(self, pytester: Pytester, tmp_path) -> None:
from _pytest.assertion.rewrite import _write_pyc from _pytest.assertion.rewrite import _write_pyc
from _pytest.assertion import AssertionState from _pytest.assertion import AssertionState
@ -1021,27 +1021,8 @@ class TestAssertionRewriteHookDetails:
co = compile("1", "f.py", "single") co = compile("1", "f.py", "single")
assert _write_pyc(state, co, os.stat(source_path), pycpath) assert _write_pyc(state, co, os.stat(source_path), pycpath)
if sys.platform == "win32": with mock.patch.object(os, "replace", side_effect=OSError):
from contextlib import contextmanager assert not _write_pyc(state, co, os.stat(source_path), pycpath)
@contextmanager
def atomic_write_failed(fn, mode="r", overwrite=False):
e = OSError()
e.errno = 10
raise e
yield # type:ignore[unreachable]
monkeypatch.setattr(
_pytest.assertion.rewrite, "atomic_write", atomic_write_failed
)
else:
def raise_oserror(*args):
raise OSError()
monkeypatch.setattr("os.rename", raise_oserror)
assert not _write_pyc(state, co, os.stat(source_path), pycpath)
def test_resources_provider_for_loader(self, pytester: Pytester) -> None: def test_resources_provider_for_loader(self, pytester: Pytester) -> None:
""" """