From 8eed1f069ab24e9707bc297dee43fca4767c0682 Mon Sep 17 00:00:00 2001 From: Akshay Raj Gollahalli Date: Sat, 22 Apr 2023 11:39:40 +1200 Subject: [PATCH 01/12] Add naturallist --- .gitignore | 8 ++------ docs/index.md | 1 + docs/lists.md | 3 +++ src/humanize/__init__.py | 2 ++ src/humanize/lists.py | 27 +++++++++++++++++++++++++++ tests/test_lists.py | 16 ++++++++++++++++ 6 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 docs/lists.md create mode 100644 src/humanize/lists.py create mode 100644 tests/test_lists.py diff --git a/.gitignore b/.gitignore index 68bc17f9..4704ab69 100644 --- a/.gitignore +++ b/.gitignore @@ -152,9 +152,5 @@ dmypy.json # Cython debug symbols cython_debug/ -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +# Jetbrains IDEs +.idea/ diff --git a/docs/index.md b/docs/index.md index 1f8a6d65..8920c156 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,6 +6,7 @@ Welcome to the humanize API reference. * [Time](time) * [Filesize](filesize) * [I18n](i18n) +* [Lists](lists) {% include-markdown "../README.md" diff --git a/docs/lists.md b/docs/lists.md new file mode 100644 index 00000000..eab0e081 --- /dev/null +++ b/docs/lists.md @@ -0,0 +1,3 @@ +# Lists + +::: humanize.lists diff --git a/src/humanize/__init__.py b/src/humanize/__init__.py index 7d3ae654..6de5e71e 100644 --- a/src/humanize/__init__.py +++ b/src/humanize/__init__.py @@ -19,6 +19,7 @@ naturaltime, precisedelta, ) +from humanize.lists import naturallist try: # Python 3.8+ @@ -50,4 +51,5 @@ "precisedelta", "scientific", "thousands_separator", + "naturallist", ] diff --git a/src/humanize/lists.py b/src/humanize/lists.py new file mode 100644 index 00000000..30e4eb4a --- /dev/null +++ b/src/humanize/lists.py @@ -0,0 +1,27 @@ +from typing import List, AnyStr + +__all__ = ["naturallist"] + + +def naturallist(items: List[AnyStr]) -> str: + """Convert a list of items into a human-readable string with commas and 'and' + + Args: + items (list): A list of strings + Returns: + str: A string with commas and 'and' in the right places + Examples: + >>> naturallist(["one", "two", "three"]) + 'one, two and three' + >>> naturallist(["one", "two"]) + 'one and two' + >>> naturallist(["one"]) + 'one' + """ + + if len(items) == 1: + return items[0] + elif len(items) == 2: + return f"{items[0]} and {items[1]}" + else: + return ", ".join(items[:-1]) + f" and {items[-1]}" diff --git a/tests/test_lists.py b/tests/test_lists.py new file mode 100644 index 00000000..732476ec --- /dev/null +++ b/tests/test_lists.py @@ -0,0 +1,16 @@ +import pytest + +import humanize + +@pytest.mark.parametrize( + "test_args, expected", + [ + ([["1", "2", "3"]], "1, 2 and 3"), + ([["one", "two", "three"]], "one, two and three"), + ([["one", "two"]], "one and two"), + ([["one"]], "one"), + ([[""]], ""), + ], +) +def test_naturallist(test_args, expected): + assert humanize.naturallist(*test_args) == expected From 301a56b0f74abebd6836eeb52be4879b950ea595 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 21 Apr 2023 23:43:04 +0000 Subject: [PATCH 02/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/humanize/__init__.py | 2 +- src/humanize/lists.py | 2 +- tests/test_lists.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/humanize/__init__.py b/src/humanize/__init__.py index 6de5e71e..ead6715b 100644 --- a/src/humanize/__init__.py +++ b/src/humanize/__init__.py @@ -2,6 +2,7 @@ from humanize.filesize import naturalsize from humanize.i18n import activate, deactivate, decimal_separator, thousands_separator +from humanize.lists import naturallist from humanize.number import ( apnumber, clamp, @@ -19,7 +20,6 @@ naturaltime, precisedelta, ) -from humanize.lists import naturallist try: # Python 3.8+ diff --git a/src/humanize/lists.py b/src/humanize/lists.py index 30e4eb4a..eb54dff5 100644 --- a/src/humanize/lists.py +++ b/src/humanize/lists.py @@ -1,4 +1,4 @@ -from typing import List, AnyStr +from typing import AnyStr, List __all__ = ["naturallist"] diff --git a/tests/test_lists.py b/tests/test_lists.py index 732476ec..19651aac 100644 --- a/tests/test_lists.py +++ b/tests/test_lists.py @@ -2,6 +2,7 @@ import humanize + @pytest.mark.parametrize( "test_args, expected", [ From 14d76fb143eb579590952f85d309aaab999f8317 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sat, 22 Apr 2023 12:46:25 +1200 Subject: [PATCH 03/12] Fix pre-commit errors --- src/humanize/lists.py | 16 +++++++++------- tests/test_lists.py | 6 +++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/humanize/lists.py b/src/humanize/lists.py index eb54dff5..c8708147 100644 --- a/src/humanize/lists.py +++ b/src/humanize/lists.py @@ -1,10 +1,13 @@ -from typing import AnyStr, List +"""Lists related humanization.""" +from typing import Any, List __all__ = ["naturallist"] -def naturallist(items: List[AnyStr]) -> str: - """Convert a list of items into a human-readable string with commas and 'and' +def naturallist(items: List[Any]) -> str: + """Natural list. + + Convert a list of items into a human-readable string with commas and 'and' Args: items (list): A list of strings @@ -18,10 +21,9 @@ def naturallist(items: List[AnyStr]) -> str: >>> naturallist(["one"]) 'one' """ - if len(items) == 1: - return items[0] + return str(items[0]) elif len(items) == 2: - return f"{items[0]} and {items[1]}" + return f"{str(items[0])} and {str(items[1])}" else: - return ", ".join(items[:-1]) + f" and {items[-1]}" + return ", ".join(str(item) for item in items[:-1]) + f" and {str(items[-1])}" diff --git a/tests/test_lists.py b/tests/test_lists.py index 19651aac..fc7ed2b6 100644 --- a/tests/test_lists.py +++ b/tests/test_lists.py @@ -11,7 +11,11 @@ ([["one", "two"]], "one and two"), ([["one"]], "one"), ([[""]], ""), + ([[1, 2, 3]], "1, 2 and 3"), + ([[1, "two"]], "1 and two"), ], ) -def test_naturallist(test_args, expected): +def test_naturallist( + test_args: list[str] | list[int] | list[str | int], expected: str +) -> None: assert humanize.naturallist(*test_args) == expected From ef4521224fb2978acd1689f5ded6b6267a09b76e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 07:41:33 +0000 Subject: [PATCH 04/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/humanize/lists.py | 3 +++ tests/test_lists.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/humanize/lists.py b/src/humanize/lists.py index c8708147..aae87f02 100644 --- a/src/humanize/lists.py +++ b/src/humanize/lists.py @@ -1,4 +1,7 @@ """Lists related humanization.""" + +from __future__ import annotations + from typing import Any, List __all__ = ["naturallist"] diff --git a/tests/test_lists.py b/tests/test_lists.py index fc7ed2b6..d710449c 100644 --- a/tests/test_lists.py +++ b/tests/test_lists.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pytest import humanize From 83b5e1a7992872fb3a480cd896bd0842119b95a5 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 2 Oct 2024 10:44:33 +0300 Subject: [PATCH 05/12] Fix UP006: Use 'list' instead of 'List' for type annotation --- src/humanize/lists.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/humanize/lists.py b/src/humanize/lists.py index aae87f02..49361804 100644 --- a/src/humanize/lists.py +++ b/src/humanize/lists.py @@ -2,12 +2,12 @@ from __future__ import annotations -from typing import Any, List +from typing import Any __all__ = ["naturallist"] -def naturallist(items: List[Any]) -> str: +def naturallist(items: list[Any]) -> str: """Natural list. Convert a list of items into a human-readable string with commas and 'and' From b8ffe874d6fccafb237628c0440bb808bb4978df Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:59:48 +0300 Subject: [PATCH 06/12] Sort __all__ --- src/humanize/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/humanize/__init__.py b/src/humanize/__init__.py index 8ed67a79..72c2b9cd 100644 --- a/src/humanize/__init__.py +++ b/src/humanize/__init__.py @@ -39,11 +39,11 @@ "naturaldate", "naturalday", "naturaldelta", + "naturallist", "naturalsize", "naturaltime", "ordinal", "precisedelta", "scientific", "thousands_separator", - "naturallist", ] From 56ecd25a4a2bdf0c3f1e76c64ac8349636911cf0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:14:01 +0300 Subject: [PATCH 07/12] Include file extension --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index a0d68bf0..e1c002bf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,7 @@ Welcome to the humanize API reference. - [Time](time.md) - [Filesize](filesize.md) - [I18n](i18n.md) -- [Lists](lists) +- [Lists](lists.md) {% include-markdown "../README.md" From a4efc82ac51e365d13a8b84ab9a0b69183445089 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:15:26 +0300 Subject: [PATCH 08/12] Include lists in nav --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index e8184013..86054934 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,7 @@ nav: - Time: time.md - Filesize: filesize.md - Internationalisation: i18n.md + - Lists: lists.md plugins: - search From dfc488611bae8c1455cbe71646e00ee4e26085cb Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:27:14 +0300 Subject: [PATCH 09/12] Update naturallist docstring --- src/humanize/lists.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/humanize/lists.py b/src/humanize/lists.py index 49361804..bbab760f 100644 --- a/src/humanize/lists.py +++ b/src/humanize/lists.py @@ -2,20 +2,17 @@ from __future__ import annotations +from collections.abc import Iterable from typing import Any __all__ = ["naturallist"] -def naturallist(items: list[Any]) -> str: +def naturallist(items: Iterable[Any]) -> str: """Natural list. - Convert a list of items into a human-readable string with commas and 'and' + Convert an iterable of items into a human-readable string with commas and 'and'. - Args: - items (list): A list of strings - Returns: - str: A string with commas and 'and' in the right places Examples: >>> naturallist(["one", "two", "three"]) 'one, two and three' @@ -23,6 +20,12 @@ def naturallist(items: list[Any]) -> str: 'one and two' >>> naturallist(["one"]) 'one' + + Args: + items (Iterable): An iterable of items. + + Returns: + str: A string with commas and 'and' in the right places. """ if len(items) == 1: return str(items[0]) From 06af0feb6d903ab8057475aa6966ef9222303d17 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:28:06 +0300 Subject: [PATCH 10/12] Update .gitignore --- .gitignore | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7057013e..7ab546ca 100644 --- a/.gitignore +++ b/.gitignore @@ -152,8 +152,8 @@ dmypy.json # Cython debug symbols cython_debug/ -# hatch-vcs -src/*/_version.py - # Jetbrains IDEs .idea/ + +# hatch-vcs +src/*/_version.py From 234839ed23fa2896af2670ca56e9c0e505be7366 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:31:39 +0300 Subject: [PATCH 11/12] Fix mypy --- src/humanize/lists.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/humanize/lists.py b/src/humanize/lists.py index bbab760f..81217c9b 100644 --- a/src/humanize/lists.py +++ b/src/humanize/lists.py @@ -2,16 +2,15 @@ from __future__ import annotations -from collections.abc import Iterable from typing import Any __all__ = ["naturallist"] -def naturallist(items: Iterable[Any]) -> str: +def naturallist(items: list[Any]) -> str: """Natural list. - Convert an iterable of items into a human-readable string with commas and 'and'. + Convert a list of items into a human-readable string with commas and 'and'. Examples: >>> naturallist(["one", "two", "three"]) @@ -22,7 +21,7 @@ def naturallist(items: Iterable[Any]) -> str: 'one' Args: - items (Iterable): An iterable of items. + items (list): An iterable of items. Returns: str: A string with commas and 'and' in the right places. From 8a2ce250b81640bc4822c6bf4129a7ecc17452fb Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:33:46 +0300 Subject: [PATCH 12/12] Use underscore for new API --- src/humanize/__init__.py | 4 ++-- src/humanize/lists.py | 10 +++++----- tests/test_lists.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/humanize/__init__.py b/src/humanize/__init__.py index 72c2b9cd..224c4834 100644 --- a/src/humanize/__init__.py +++ b/src/humanize/__init__.py @@ -4,7 +4,7 @@ from humanize.filesize import naturalsize from humanize.i18n import activate, deactivate, decimal_separator, thousands_separator -from humanize.lists import naturallist +from humanize.lists import natural_list from humanize.number import ( apnumber, clamp, @@ -39,7 +39,7 @@ "naturaldate", "naturalday", "naturaldelta", - "naturallist", + "natural_list", "naturalsize", "naturaltime", "ordinal", diff --git a/src/humanize/lists.py b/src/humanize/lists.py index 81217c9b..1573be87 100644 --- a/src/humanize/lists.py +++ b/src/humanize/lists.py @@ -4,20 +4,20 @@ from typing import Any -__all__ = ["naturallist"] +__all__ = ["natural_list"] -def naturallist(items: list[Any]) -> str: +def natural_list(items: list[Any]) -> str: """Natural list. Convert a list of items into a human-readable string with commas and 'and'. Examples: - >>> naturallist(["one", "two", "three"]) + >>> natural_list(["one", "two", "three"]) 'one, two and three' - >>> naturallist(["one", "two"]) + >>> natural_list(["one", "two"]) 'one and two' - >>> naturallist(["one"]) + >>> natural_list(["one"]) 'one' Args: diff --git a/tests/test_lists.py b/tests/test_lists.py index d710449c..a39d3442 100644 --- a/tests/test_lists.py +++ b/tests/test_lists.py @@ -17,7 +17,7 @@ ([[1, "two"]], "1 and two"), ], ) -def test_naturallist( +def test_natural_list( test_args: list[str] | list[int] | list[str | int], expected: str ) -> None: - assert humanize.naturallist(*test_args) == expected + assert humanize.natural_list(*test_args) == expected