Skip to content

Commit 6633afe

Browse files
committed
refactor: writeable -> writable
1 parent dd82a34 commit 6633afe

File tree

2 files changed

+62
-30
lines changed

2 files changed

+62
-30
lines changed

fgpyo/io/__init__.py

+37-16
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
55
The functions in this module make it easy to:
66
7-
* check if a file exists and is writeable
8-
* check if a file and its parent directories exist and are writeable
7+
* check if a file exists and is writable
8+
* check if a file and its parent directories exist and are writable
99
* check if a file exists and is readable
1010
* check if a path exists and is a directory
1111
* open an appropriate reader or writer based on the file extension
@@ -47,6 +47,7 @@
4747
import io
4848
import os
4949
import sys
50+
import warnings
5051
from contextlib import contextmanager
5152
from pathlib import Path
5253
from typing import IO
@@ -90,41 +91,61 @@ def assert_directory_exists(path: Path) -> None:
9091

9192

9293
def assert_path_is_writeable(path: Path, parent_must_exist: bool = True) -> None:
93-
"""Asserts the following:
94-
If the file exists then it must also be writeable. Else if the path is not a file and
95-
parent_must_exist is true then assert that the parent directory exists and is writeable.
96-
Else if the path is not a directory and parent_must_exist is false then look at each parent
97-
directory until one is found that exists and is writeable.
94+
"""
95+
A deprecated alias for `assert_path_is_writable()`.
96+
"""
97+
warnings.warn(
98+
"assert_path_is_writeable is deprecated, use assert_path_is_writable instead",
99+
DeprecationWarning,
100+
)
101+
102+
assert_path_is_writable(path=path, parent_must_exist=parent_must_exist)
103+
104+
105+
def assert_path_is_writable(path: Path, parent_must_exist: bool = True) -> None:
106+
"""
107+
Assert that a filepath is writable.
108+
109+
Specifically:
110+
- If the file exists then it must also be writable.
111+
- Else if the path is not a file and `parent_must_exist` is true, then assert that the parent
112+
directory exists and is writable.
113+
- Else if the path is not a directory and `parent_must_exist` is false, then look at each parent
114+
directory until one is found that exists and is writable.
98115
99116
Args:
100-
path: Path to check
101-
parent_must_exist: True/False the parent directory must exist, the default is True
117+
path: Path to check
118+
parent_must_exist: If True, the file's parent directory must exist. Otherwise, at least one
119+
directory in the path's components must exist.
120+
121+
Raises:
122+
AssertionError: If any of the above conditions are not met.
102123
103124
Example:
104-
assert_path_is_writeable(path = Path("example.txt"))
125+
assert_path_is_writable(path = Path("example.txt"))
105126
"""
106-
# If file exists, it must be writeable
127+
# If file exists, it must be writable
107128
if path.exists():
108129
assert path.is_file() and os.access(
109130
path, os.W_OK
110-
), f"File exists but is not writeable: {path}"
131+
), f"File exists but is not writable: {path}"
111132

112133
# Else if file doesnt exist and parent_must_exist is True then check
113-
# that path.absolute().parent exists, is a directory and is writeable
134+
# that path.absolute().parent exists, is a directory and is writable
114135
elif parent_must_exist:
115136
parent = path.absolute().parent
116137
assert (
117138
parent.exists() & parent.is_dir() & os.access(parent, os.W_OK)
118-
), f"Path does not exist and parent isn't extent/writable: {path}"
139+
), f"Path does not exist and parent isn't extant/writable: {path}"
119140

120141
# Else if file doesn't exist and parent_must_exist is False, test parent until
121-
# you find the first extent path, and check that it is a directory and is writeable.
142+
# you find the first extant path, and check that it is a directory and is writable.
122143
else:
123144
for parent in path.parents:
124145
if parent.exists():
125146
assert os.access(
126147
parent, os.W_OK
127-
), f"File does not have a writeable parent directory: {path}"
148+
), f"File does not have a writable parent directory: {path}"
128149
return
129150
raise AssertionError(f"No parent directories exist for: {path}")
130151

fgpyo/io/tests/test_io.py

+25-14
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from pytest import raises
1212

1313
import fgpyo.io as fio
14+
from fgpyo.io import assert_path_is_writable
15+
from fgpyo.io import assert_path_is_writeable
1416

1517

1618
def test_assert_path_is_readable_missing_file_error() -> None:
@@ -50,37 +52,46 @@ def test_assert_directory_exists_pass() -> None:
5052
fio.assert_directory_exists(path=path.parent.absolute())
5153

5254

53-
def test_assert_path_is_writeable_mode_error() -> None:
55+
def test_assert_path_is_writable_mode_error() -> None:
5456
"""Error when permissions are read only by owner"""
5557
with NamedTemp(suffix=".txt", mode="w", delete=True) as read_file:
5658
path = Path(read_file.name)
5759
os.chmod(path, 0o00400) # Read only permissions
58-
with raises(AssertionError, match=f"File exists but is not writeable: {path}"):
59-
fio.assert_path_is_writeable(path=path)
60+
with raises(AssertionError, match=f"File exists but is not writable: {path}"):
61+
assert_path_is_writable(path=path)
6062

6163

62-
def test_assert_path_is_writeable_parent_not_writeable() -> None:
63-
"""Error when parent_must_exist is false and no writeable parent directory exists"""
64+
def test_assert_path_is_writable_parent_not_writable() -> None:
65+
"""Error when parent_must_exist is false and no writable parent directory exists"""
6466
path = Path("/no/parent/exists/")
65-
with raises(AssertionError, match=f"File does not have a writeable parent directory: {path}"):
66-
fio.assert_path_is_writeable(path=path, parent_must_exist=False)
67+
with raises(AssertionError, match=f"File does not have a writable parent directory: {path}"):
68+
assert_path_is_writable(path=path, parent_must_exist=False)
6769

6870

69-
def test_assert_path_is_writeable_file_does_not_exist() -> None:
71+
def test_assert_path_is_writable_file_does_not_exist() -> None:
7072
"""Error when file does not exist"""
71-
path = Path("example/non_existant_file.txt")
73+
path = Path("example/non_existent_file.txt")
7274
with raises(
7375
AssertionError,
74-
match="Path does not exist and parent isn't extent/writable: example/non_existant_file.txt",
76+
match="Path does not exist and parent isn't extant/writable: example/non_existent_file.txt",
7577
):
76-
fio.assert_path_is_writeable(path=path)
78+
assert_path_is_writable(path=path)
7779

7880

79-
def test_assert_path_is_writeable_pass() -> None:
80-
"""Should return the correct writeable path"""
81+
def test_assert_path_is_writable_pass() -> None:
82+
"""Should return the correct writable path"""
8183
with NamedTemp(suffix=".txt", mode="w", delete=True) as read_file:
8284
path = Path(read_file.name)
83-
fio.assert_path_is_writeable(path=path)
85+
assert_path_is_writable(path=path)
86+
87+
88+
def test_assert_path_is_writeable_raises_deprecation_warning(tmp_path: Path) -> None:
89+
"""
90+
Test that we get a DeprecationWarning when the `assert_path_is_writeable` alias is called,
91+
but otherwise works as expected.
92+
"""
93+
with pytest.warns(DeprecationWarning):
94+
assert_path_is_writeable(path=tmp_path / "test.txt")
8495

8596

8697
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)