Skip to content

Commit

Permalink
Merge pull request #690 from zwimer/support_oxford_comma
Browse files Browse the repository at this point in the history
Support 'oxford comma' format and non-string types in listing
  • Loading branch information
staticdev authored Jan 17, 2025
2 parents f72bece + 49bfd4e commit 47ef9ab
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
4 changes: 4 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[report]
exclude_lines =
pragma: no cover
if TYPE_CHECKING:
15 changes: 11 additions & 4 deletions src/human_readable/lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

from __future__ import annotations

from collections.abc import Sequence
from typing import Any

__all__ = ["listing"]


def listing(items: list[str], separator: str, conjunction: str = "") -> str:
def listing(
items: Sequence[Any], separator: Any, conjunction: Any = None, oxford: bool = False
) -> str:
"""Return human readable list separated by separator.
Optional argument is conjuntion that substitutes the last separator.
Expand All @@ -15,6 +19,7 @@ def listing(items: list[str], separator: str, conjunction: str = "") -> str:
items: list of items.
separator: separator of items.
conjunction: word/string as last separator. Defaults to None.
oxford: apply separators in the same manner as an oxford comma
Returns:
str: list in natural language.
Expand All @@ -24,11 +29,13 @@ def listing(items: list[str], separator: str, conjunction: str = "") -> str:
if len_items == 0:
return ""
if len_items == 1:
return items[0]
phrase = items[0]
if conjunction:
return str(items[0])
phrase = str(items[0])
if conjunction is not None:
for i in range(1, len_items - 1):
phrase += f"{separator} {items[i]}"
if oxford and len_items > 2:
phrase += str(separator)
phrase += f" {conjunction} {items[len_items - 1]}"
else:
for i in range(1, len_items):
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/test_lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,22 @@ def test_listing_with_conjunction(
) -> None:
"""Listing with separator and conjunction."""
assert lists.listing(*params) == expected


@pytest.mark.parametrize(
"params, expected",
[
(([], ";", "or"), ""), # empty list
((["jorbas"], ";", "or"), "jorbas"), # one element
((["jorbas", "maria"], ";", "or"), "jorbas or maria"), # two elements
(
(["jorbas", "maria", "gustavo"], ";", "or"),
"jorbas; maria; or gustavo",
), # three elements
],
)
def test_listing_with_conjunction_oxford(
params: tuple[list[str], str, str], expected: str
) -> None:
"""Listing with separator and conjunction."""
assert lists.listing(*params, oxford=True) == expected

0 comments on commit 47ef9ab

Please sign in to comment.