Skip to content

Commit f634595

Browse files
committed
fix: r/w assertions
1 parent 6633afe commit f634595

File tree

2 files changed

+39
-34
lines changed

2 files changed

+39
-34
lines changed

fgpyo/io/__init__.py

+19-13
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,12 @@ def assert_path_is_readable(path: Path) -> None:
7272
Example:
7373
assert_file_exists(path = Path("some_file.csv"))
7474
"""
75+
# stdin is readable
76+
if path == Path("/dev/stdin"):
77+
return
78+
7579
assert path.exists(), f"Cannot read non-existent path: {path}"
76-
assert not path.is_dir(), f"Cannot read path becasue it is a directory: {path}"
80+
assert path.is_file(), f"Cannot read path becasue it is not a file: {path}"
7781
assert os.access(path, os.R_OK), f"Path exists but is not readable: {path}"
7882

7983

@@ -124,30 +128,32 @@ def assert_path_is_writable(path: Path, parent_must_exist: bool = True) -> None:
124128
Example:
125129
assert_path_is_writable(path = Path("example.txt"))
126130
"""
127-
# If file exists, it must be writable
131+
# stdout is writable
132+
if path == Path("/dev/stdout"):
133+
return
134+
135+
# If path exists, it must be a writable file
128136
if path.exists():
129-
assert path.is_file() and os.access(
130-
path, os.W_OK
131-
), f"File exists but is not writable: {path}"
137+
assert path.is_file(), f"Cannot read path becasue it is not a file: {path}"
138+
assert os.access(path, os.W_OK), f"File exists but is not writable: {path}"
132139

133140
# Else if file doesnt exist and parent_must_exist is True then check
134141
# that path.absolute().parent exists, is a directory and is writable
135142
elif parent_must_exist:
136143
parent = path.absolute().parent
137-
assert (
138-
parent.exists() & parent.is_dir() & os.access(parent, os.W_OK)
139-
), f"Path does not exist and parent isn't extant/writable: {path}"
144+
assert parent.exists(), f"Parent directory does not exist: {parent}"
145+
assert parent.is_dir(), f"Parent directory exists but is not a directory: {parent}"
146+
assert os.access(parent, os.W_OK), f"Parent directory exists but is not writable: {parent}"
140147

141148
# Else if file doesn't exist and parent_must_exist is False, test parent until
142149
# you find the first extant path, and check that it is a directory and is writable.
143150
else:
144151
for parent in path.parents:
145152
if parent.exists():
146-
assert os.access(
147-
parent, os.W_OK
148-
), f"File does not have a writable parent directory: {path}"
149-
return
150-
raise AssertionError(f"No parent directories exist for: {path}")
153+
assert os.access(parent, os.W_OK), f"Parent directory is not writable: {parent}"
154+
break
155+
else:
156+
raise AssertionError(f"No parent directories exist for: {path}")
151157

152158

153159
def to_reader(path: Path) -> Union[io.TextIOWrapper, TextIO, IO[Any]]:

fgpyo/io/tests/test_io.py

+20-21
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
import io
44
import os
5+
import stat
56
from pathlib import Path
6-
from tempfile import NamedTemporaryFile as NamedTemp
7+
from tempfile import NamedTemporaryFile
78
from typing import Any
89
from typing import List
910

1011
import pytest
11-
from pytest import raises
1212

1313
import fgpyo.io as fio
1414
from fgpyo.io import assert_path_is_writable
@@ -18,69 +18,68 @@
1818
def test_assert_path_is_readable_missing_file_error() -> None:
1919
"""Error when file does not exist"""
2020
path = Path("error.txt")
21-
with raises(AssertionError):
21+
22+
with pytest.raises(AssertionError):
2223
fio.assert_path_is_readable(path=path)
2324

2425

2526
def test_assert_path_is_readable_mode_error() -> None:
2627
"""Error when permissions are write only by owner"""
27-
with NamedTemp(suffix=".txt", mode="r", delete=True) as write_file:
28+
with NamedTemporaryFile(suffix=".txt", mode="r", delete=True) as write_file:
2829
path = Path(write_file.name)
29-
os.chmod(path, 0o00200) # Write only permissions
30-
with raises(AssertionError):
30+
os.chmod(path, stat.S_IWUSR) # Write only permissions
31+
32+
with pytest.raises(AssertionError):
3133
fio.assert_path_is_readable(path=path)
3234

3335

3436
def test_assert_path_is_readable_pass() -> None:
3537
"""Returns none when no assertions are violated"""
36-
with NamedTemp(suffix=".txt", mode="w", delete=True) as write_file:
38+
with NamedTemporaryFile(suffix=".txt", mode="w", delete=True) as write_file:
3739
path = Path(write_file.name)
3840
fio.assert_path_is_readable(path=path)
3941

4042

4143
def test_assert_directory_exists_error() -> None:
4244
"""Ensure OSError when directory does not exist"""
4345
path = Path("/non/existent/dir/")
44-
with raises(AssertionError):
46+
with pytest.raises(AssertionError):
4547
fio.assert_directory_exists(path)
4648

4749

4850
def test_assert_directory_exists_pass() -> None:
4951
"""Asserts fio._assert_directory_exists() returns True when directory exists"""
50-
with NamedTemp(suffix=".txt", mode="w", delete=True) as write_file:
52+
with NamedTemporaryFile(suffix=".txt", mode="w", delete=True) as write_file:
5153
path = Path(write_file.name)
5254
fio.assert_directory_exists(path=path.parent.absolute())
5355

5456

5557
def test_assert_path_is_writable_mode_error() -> None:
5658
"""Error when permissions are read only by owner"""
57-
with NamedTemp(suffix=".txt", mode="w", delete=True) as read_file:
59+
with NamedTemporaryFile(suffix=".txt", mode="w", delete=True) as read_file:
5860
path = Path(read_file.name)
59-
os.chmod(path, 0o00400) # Read only permissions
60-
with raises(AssertionError, match=f"File exists but is not writable: {path}"):
61+
os.chmod(path, stat.S_IRUSR) # Read only permissions
62+
with pytest.raises(AssertionError, match=f"File exists but is not writable: {path}"):
6163
assert_path_is_writable(path=path)
6264

6365

6466
def test_assert_path_is_writable_parent_not_writable() -> None:
6567
"""Error when parent_must_exist is false and no writable parent directory exists"""
6668
path = Path("/no/parent/exists/")
67-
with raises(AssertionError, match=f"File does not have a writable parent directory: {path}"):
69+
with pytest.raises(AssertionError, match="Parent directory is not writable: /"):
6870
assert_path_is_writable(path=path, parent_must_exist=False)
6971

7072

7173
def test_assert_path_is_writable_file_does_not_exist() -> None:
7274
"""Error when file does not exist"""
7375
path = Path("example/non_existent_file.txt")
74-
with raises(
75-
AssertionError,
76-
match="Path does not exist and parent isn't extant/writable: example/non_existent_file.txt",
77-
):
76+
with pytest.raises(AssertionError, match="Parent directory does not exist:"):
7877
assert_path_is_writable(path=path)
7978

8079

8180
def test_assert_path_is_writable_pass() -> None:
8281
"""Should return the correct writable path"""
83-
with NamedTemp(suffix=".txt", mode="w", delete=True) as read_file:
82+
with NamedTemporaryFile(suffix=".txt", mode="w", delete=True) as read_file:
8483
path = Path(read_file.name)
8584
assert_path_is_writable(path=path)
8685

@@ -106,7 +105,7 @@ def test_reader(
106105
expected: Any,
107106
) -> None:
108107
"""Tests fgpyo.io.to_reader"""
109-
with NamedTemp(suffix=suffix, mode="r", delete=True) as read_file:
108+
with NamedTemporaryFile(suffix=suffix, mode="r", delete=True) as read_file:
110109
with fio.to_reader(path=Path(read_file.name)) as reader:
111110
assert isinstance(reader, expected)
112111

@@ -123,7 +122,7 @@ def test_writer(
123122
expected: Any,
124123
) -> None:
125124
"""Tests fgpyo.io.to_writer()"""
126-
with NamedTemp(suffix=suffix, mode="w", delete=True) as write_file:
125+
with NamedTemporaryFile(suffix=suffix, mode="w", delete=True) as write_file:
127126
with fio.to_writer(path=Path(write_file.name)) as writer:
128127
assert isinstance(writer, expected)
129128

@@ -137,7 +136,7 @@ def test_read_and_write_lines(
137136
list_to_write: List[Any],
138137
) -> None:
139138
"""Test fgpyo.fio.read_lines and write_lines"""
140-
with NamedTemp(suffix=suffix, mode="w", delete=True) as read_file:
139+
with NamedTemporaryFile(suffix=suffix, mode="w", delete=True) as read_file:
141140
fio.write_lines(path=Path(read_file.name), lines_to_write=list_to_write)
142141
read_back = fio.read_lines(path=Path(read_file.name))
143142
assert next(read_back) == list_to_write[0]

0 commit comments

Comments
 (0)