Skip to content

Commit 5291650

Browse files
committed
Add in_directory function to paths and add new options to word_join
1 parent e65673b commit 5291650

File tree

4 files changed

+88
-32
lines changed

4 files changed

+88
-32
lines changed

domdf_python_tools/paths.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#
4141

4242
# stdlib
43+
import contextlib
4344
import json
4445
import os
4546
import pathlib
@@ -279,6 +280,23 @@ def make_executable(filename: PathLike) -> None:
279280
os.chmod(str(filename), st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
280281

281282

283+
@contextlib.contextmanager
284+
def in_directory(directory: PathLike):
285+
"""
286+
Context manager to change into the given directory for the
287+
duration of the ``with`` block.
288+
289+
:param directory:
290+
"""
291+
292+
oldwd = os.getcwd()
293+
try:
294+
os.chdir(str(directory))
295+
yield
296+
finally:
297+
os.chdir(oldwd)
298+
299+
282300
class PathPlus(pathlib.Path):
283301
"""
284302
Subclass of :mod:`pathlib.Path` with additional methods and a default encoding of UTF-8.

domdf_python_tools/words.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -493,16 +493,31 @@ def as_text(value: Any) -> str:
493493
return str(value)
494494

495495

496-
def word_join(iterable: Iterable[str], use_repr: bool = False, oxford: bool = False) -> str:
496+
def word_join(
497+
iterable: Iterable[str],
498+
use_repr: bool = False,
499+
oxford: bool = False,
500+
delimiter: str = ",",
501+
connective: str = "and",
502+
) -> str:
497503
"""
498504
Join the given list of strings in a natural manner, with 'and' to join the last two elements.
499505
500506
:param iterable:
501507
:param use_repr: Whether to join the ``repr`` of each object.
502508
:param oxford: Whether to use an oxford comma when joining the last two elements.
503509
Always :py:obj:`False` if there are fewer than three elements.
510+
:param delimiter: A single character to use between the words.
511+
:param connective: The connective to join the final two words with.
512+
513+
.. versionchanged:: 0.11.0
514+
515+
Added ``delimiter`` and ``connective`` arguments.
516+
504517
"""
505518

519+
delimiter = f"{delimiter} "
520+
506521
if use_repr:
507522
words = [repr(w) for w in iterable]
508523
else:
@@ -516,6 +531,6 @@ def word_join(iterable: Iterable[str], use_repr: bool = False, oxford: bool = Fa
516531
return " and ".join(words)
517532
else:
518533
if oxford:
519-
return ", ".join(words[:-1]) + f", and {words[-1]}"
534+
return delimiter.join(words[:-1]) + f"{delimiter}{connective} {words[-1]}"
520535
else:
521-
return ", ".join(words[:-1]) + f" and {words[-1]}"
536+
return delimiter.join(words[:-1]) + f" {connective} {words[-1]}"

tests/test_paths.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
# this package
2323
from domdf_python_tools import paths
24-
from domdf_python_tools.paths import PathPlus, clean_writer, copytree
24+
from domdf_python_tools.paths import PathPlus, clean_writer, copytree, in_directory
2525
from domdf_python_tools.testing import not_pypy, not_windows
2626

2727

@@ -594,3 +594,20 @@ def test_load_json(tmpdir):
594594
}"""))
595595

596596
assert tmp_file.load_json() == {"key": "value", "int": 1234, "float": 12.34}
597+
598+
599+
def test_in_directory(tmp_pathplus):
600+
cwd = os.getcwd()
601+
602+
with in_directory(tmp_pathplus):
603+
assert str(os.getcwd()) == str(tmp_pathplus)
604+
605+
assert os.getcwd() == cwd
606+
607+
tmpdir = tmp_pathplus / "tmp"
608+
tmpdir.maybe_make()
609+
610+
with in_directory(tmpdir):
611+
assert str(os.getcwd()) == str(tmpdir)
612+
613+
assert os.getcwd() == cwd

tests/test_words.py

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -111,31 +111,37 @@ def test_as_text(value, expects):
111111
assert words.as_text(value) == expects
112112

113113

114-
def test_word_join():
115-
assert words.word_join([]) == ''
116-
117-
assert words.word_join(["bob"]) == "bob"
118-
assert words.word_join(["bob", "alice"]) == "bob and alice"
119-
assert words.word_join(["bob", "alice", "fred"]) == "bob, alice and fred"
120-
121-
assert words.word_join(["bob"], use_repr=True) == "'bob'"
122-
assert words.word_join(["bob", "alice"], use_repr=True) == "'bob' and 'alice'"
123-
assert words.word_join(["bob", "alice", "fred"], use_repr=True) == "'bob', 'alice' and 'fred'"
124-
125-
assert words.word_join(["bob"], use_repr=True, oxford=True) == "'bob'"
126-
assert words.word_join(["bob", "alice"], use_repr=True, oxford=True) == "'bob' and 'alice'"
127-
assert words.word_join(["bob", "alice", "fred"], use_repr=True, oxford=True) == "'bob', 'alice', and 'fred'"
128-
129-
assert words.word_join(()) == ''
130-
131-
assert words.word_join(("bob", )) == "bob"
132-
assert words.word_join(("bob", "alice")) == "bob and alice"
133-
assert words.word_join(("bob", "alice", "fred")) == "bob, alice and fred"
134-
135-
assert words.word_join(("bob", ), use_repr=True) == "'bob'"
136-
assert words.word_join(("bob", "alice"), use_repr=True) == "'bob' and 'alice'"
137-
assert words.word_join(("bob", "alice", "fred"), use_repr=True) == "'bob', 'alice' and 'fred'"
138-
139-
assert words.word_join(("bob", ), use_repr=True, oxford=True) == "'bob'"
140-
assert words.word_join(("bob", "alice"), use_repr=True, oxford=True) == "'bob' and 'alice'"
141-
assert words.word_join(("bob", "alice", "fred"), use_repr=True, oxford=True) == "'bob', 'alice', and 'fred'"
114+
@pytest.mark.parametrize(
115+
"args, kwargs, expects",
116+
[
117+
(([], ), {}, ''),
118+
(((), ), {}, ''),
119+
((["bob"], ), {}, "bob"),
120+
((["bob", "alice"], ), {}, "bob and alice"),
121+
((["bob", "alice", "fred"], ), {}, "bob, alice and fred"),
122+
((("bob", ), ), {}, "bob"),
123+
((("bob", "alice"), ), {}, "bob and alice"),
124+
((("bob", "alice", "fred"), ), {}, "bob, alice and fred"),
125+
((("bob", ), ), {"delimiter": ';'}, "bob"),
126+
((("bob", "alice"), ), {"delimiter": ';'}, "bob and alice"),
127+
((("bob", "alice", "fred"), ), {"delimiter": ';'}, "bob; alice and fred"),
128+
((["bob"], ), {"use_repr": True}, "'bob'"),
129+
((["bob", "alice"], ), {"use_repr": True}, "'bob' and 'alice'"),
130+
((["bob", "alice", "fred"], ), {"use_repr": True}, "'bob', 'alice' and 'fred'"),
131+
((("bob", ), ), {"use_repr": True}, "'bob'"),
132+
((("bob", "alice"), ), {"use_repr": True}, "'bob' and 'alice'"),
133+
((("bob", "alice", "fred"), ), {"use_repr": True}, "'bob', 'alice' and 'fred'"),
134+
((["bob"], ), {"use_repr": True, "oxford": True}, "'bob'"),
135+
((["bob", "alice"], ), {"use_repr": True, "oxford": True}, "'bob' and 'alice'"),
136+
((["bob", "alice", "fred"], ), {"use_repr": True, "oxford": True}, "'bob', 'alice', and 'fred'"),
137+
((["bob", "alice", "fred"], ), {"use_repr": True, "oxford": True, "delimiter": ';'},
138+
"'bob'; 'alice'; and 'fred'"),
139+
((["bob", "alice", "fred"], ), {"use_repr": True, "oxford": True, "connective": 'or'},
140+
"'bob', 'alice', or 'fred'"),
141+
((("bob", ), ), {"use_repr": True, "oxford": True}, "'bob'"),
142+
((("bob", "alice"), ), {"use_repr": True, "oxford": True}, "'bob' and 'alice'"),
143+
((("bob", "alice", "fred"), ), {"use_repr": True, "oxford": True}, "'bob', 'alice', and 'fred'"),
144+
]
145+
)
146+
def test_word_join(args, kwargs, expects):
147+
assert words.word_join(*args, **kwargs) == expects

0 commit comments

Comments
 (0)