Skip to content

Commit 47ef9ab

Browse files
authored
Merge pull request #690 from zwimer/support_oxford_comma
Support 'oxford comma' format and non-string types in listing
2 parents f72bece + 49bfd4e commit 47ef9ab

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

.coveragerc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[report]
2+
exclude_lines =
3+
pragma: no cover
4+
if TYPE_CHECKING:

src/human_readable/lists.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
from __future__ import annotations
44

5+
from collections.abc import Sequence
6+
from typing import Any
57

68
__all__ = ["listing"]
79

810

9-
def listing(items: list[str], separator: str, conjunction: str = "") -> str:
11+
def listing(
12+
items: Sequence[Any], separator: Any, conjunction: Any = None, oxford: bool = False
13+
) -> str:
1014
"""Return human readable list separated by separator.
1115
1216
Optional argument is conjuntion that substitutes the last separator.
@@ -15,6 +19,7 @@ def listing(items: list[str], separator: str, conjunction: str = "") -> str:
1519
items: list of items.
1620
separator: separator of items.
1721
conjunction: word/string as last separator. Defaults to None.
22+
oxford: apply separators in the same manner as an oxford comma
1823
1924
Returns:
2025
str: list in natural language.
@@ -24,11 +29,13 @@ def listing(items: list[str], separator: str, conjunction: str = "") -> str:
2429
if len_items == 0:
2530
return ""
2631
if len_items == 1:
27-
return items[0]
28-
phrase = items[0]
29-
if conjunction:
32+
return str(items[0])
33+
phrase = str(items[0])
34+
if conjunction is not None:
3035
for i in range(1, len_items - 1):
3136
phrase += f"{separator} {items[i]}"
37+
if oxford and len_items > 2:
38+
phrase += str(separator)
3239
phrase += f" {conjunction} {items[len_items - 1]}"
3340
else:
3441
for i in range(1, len_items):

tests/unit/test_lists.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,22 @@ def test_listing_with_conjunction(
3838
) -> None:
3939
"""Listing with separator and conjunction."""
4040
assert lists.listing(*params) == expected
41+
42+
43+
@pytest.mark.parametrize(
44+
"params, expected",
45+
[
46+
(([], ";", "or"), ""), # empty list
47+
((["jorbas"], ";", "or"), "jorbas"), # one element
48+
((["jorbas", "maria"], ";", "or"), "jorbas or maria"), # two elements
49+
(
50+
(["jorbas", "maria", "gustavo"], ";", "or"),
51+
"jorbas; maria; or gustavo",
52+
), # three elements
53+
],
54+
)
55+
def test_listing_with_conjunction_oxford(
56+
params: tuple[list[str], str, str], expected: str
57+
) -> None:
58+
"""Listing with separator and conjunction."""
59+
assert lists.listing(*params, oxford=True) == expected

0 commit comments

Comments
 (0)