Skip to content

Commit d27b020

Browse files
committed
Change errorhandling once again
1 parent b41a4fd commit d27b020

File tree

3 files changed

+30
-30
lines changed

3 files changed

+30
-30
lines changed

atomicwrites/__init__.py

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,18 @@
99

1010
PY2 = sys.version_info[0] == 2
1111

12-
if PY2:
13-
class FileExistsError(OSError):
14-
errno = errno.EEXIST
1512

16-
class FileNotFoundError(OSError):
17-
errno = errno.ENOENT
18-
else:
19-
# For some reason we have to redefine this, or users can't import it.
20-
FileExistsError = FileExistsError
21-
FileNotFoundError = FileNotFoundError
13+
class _FileExistsError(OSError if PY2 else FileExistsError):
14+
errno = errno.EEXIST
15+
16+
class _FileNotFoundError(OSError if PY2 else FileNotFoundError):
17+
errno = errno.ENOENT
2218

2319

2420
if sys.platform != 'win32':
2521
@contextlib.contextmanager
2622
def handle_errors():
27-
try:
28-
yield
29-
except FileExistsError:
30-
raise
31-
except OSError as e:
32-
if e.errno == errno.EEXIST:
33-
raise FileExistsError(str(e))
34-
else:
35-
raise
23+
yield
3624

3725
def _replace_atomic(src, dst):
3826
os.rename(src, dst)
@@ -47,20 +35,19 @@ def _move_atomic(src, dst):
4735

4836
_windows_default_flags = win32file.MOVEFILE_WRITE_THROUGH
4937
_windows_error_table = {
50-
183: FileExistsError,
51-
3: FileNotFoundError
38+
183: _FileExistsError,
39+
3: _FileNotFoundError
5240
}
5341

5442
@contextlib.contextmanager
5543
def handle_errors():
5644
try:
5745
yield
5846
except pywintypes.error as e:
59-
native_cls = _windows_error_table.get(e.winerror, None)
60-
if native_cls is not None:
61-
raise native_cls(str(e))
62-
else:
63-
raise
47+
native_cls = _windows_error_table.get(e.winerror, OSError)
48+
new_e = native_cls(e)
49+
new_e.windows_error = e
50+
raise new_e
6451

6552
def _replace_atomic(src, dst):
6653
win32api.MoveFileEx(

docs/index.rst

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@ API
88
.. autofunction:: atomic_write
99

1010

11-
Exceptions
12-
----------
11+
Errorhandling
12+
-------------
13+
14+
All filesystem errors are subclasses of :py:exc:`OSError`.
15+
16+
- On UNIX systems, errors from the Python stdlib calls are simply uncaught.
17+
- On Windows systems, some PyWin32 errors are intercepted such that they
18+
resemble the stdlib exceptions. The original PyWin32 exception object is
19+
available as ``windows_error`` at all times.
1320

1421
.. exception:: FileExistsError
1522

tests/test_atomicwrites.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from atomicwrites import atomic_write, FileExistsError
1+
import errno
2+
3+
from atomicwrites import atomic_write
24

35
import pytest
46

@@ -9,10 +11,12 @@ def test_atomic_write(tmpdir):
911
with atomic_write(str(fname), overwrite=True) as f:
1012
f.write('hoho')
1113

12-
with pytest.raises(FileExistsError):
14+
with pytest.raises(OSError) as excinfo:
1315
with atomic_write(str(fname), overwrite=False) as f:
1416
f.write('haha')
1517

18+
assert excinfo.value.errno == errno.EEXIST
19+
1620
assert fname.read() == 'hoho'
1721
assert len(tmpdir.listdir()) == 1
1822

@@ -38,10 +42,12 @@ def test_replace_simultaneously_created_file(tmpdir):
3842

3943
def test_dont_remove_simultaneously_created_file(tmpdir):
4044
fname = tmpdir.join('ha')
41-
with pytest.raises(FileExistsError):
45+
with pytest.raises(OSError) as excinfo:
4246
with atomic_write(str(fname), overwrite=False) as f:
4347
f.write('hoho')
4448
fname.write('harhar')
4549
assert fname.read() == 'harhar'
50+
51+
assert excinfo.value.errno == errno.EEXIST
4652
assert fname.read() == 'harhar'
4753
assert len(tmpdir.listdir()) == 1

0 commit comments

Comments
 (0)