summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeth Morton <seth.m.morton@gmail.com>2022-08-29 08:05:58 -0700
committerGitHub <noreply@github.com>2022-08-29 08:05:58 -0700
commite5d2e4507728e53d1867ac87e169fca1d251d8cf (patch)
treebf4177617984e286483caeb9a7cc7d9d69ba3806
parente3c32f5638bf3a0e9a23633495269bea0e75d379 (diff)
parente4f8cd2254cbb500e5ab9eb38aae94f863d261ad (diff)
downloadnatsort-e5d2e4507728e53d1867ac87e169fca1d251d8cf.tar.gz
Merge pull request #153 from Gilthans/master
Treat paths as strings in StrParser
-rw-r--r--natsort/compat/locale.py13
-rw-r--r--natsort/utils.py14
-rw-r--r--tests/test_natsorted.py10
3 files changed, 26 insertions, 11 deletions
diff --git a/natsort/compat/locale.py b/natsort/compat/locale.py
index b4c5356..53080c3 100644
--- a/natsort/compat/locale.py
+++ b/natsort/compat/locale.py
@@ -38,10 +38,10 @@ try: # noqa: C901
# If using icu, get the locale from the current global locale,
def get_icu_locale() -> str:
- try:
- return cast(str, icu.Locale(".".join(getlocale())))
- except TypeError: # pragma: no cover
+ language_code, encoding = getlocale()
+ if language_code is None or encoding is None: # pragma: no cover
return cast(str, icu.Locale())
+ return cast(str, icu.Locale(f"{language_code}.{encoding}"))
def get_strxfrm() -> TrxfmFunc:
return cast(TrxfmFunc, icu.Collator.createInstance(get_icu_locale()).getSortKey)
@@ -75,10 +75,11 @@ except ImportError:
# characters are incorrectly blank. Here is a lookup table of the
# corrections I am aware of.
if dumb_sort():
- try:
- loc = ".".join(locale.getlocale())
- except TypeError: # No locale loaded, default to ','
+ language_code, encoding = locale.getlocale()
+ if language_code is None or encoding is None:
+ # No locale loaded, default to ','
return ","
+ loc = f"{language_code}.{encoding}"
return {
"de_DE.ISO8859-15": ".",
"es_ES.ISO8859-1": ".",
diff --git a/natsort/utils.py b/natsort/utils.py
index 3832318..2bceb85 100644
--- a/natsort/utils.py
+++ b/natsort/utils.py
@@ -103,14 +103,14 @@ TupleOfStrAnyPair = Tuple[Tuple[str], TupleOfAny]
FinalTransform = Union[TwoBlankTuple, TupleOfAny, TupleOfStrAnyPair]
FinalTransformer = Callable[[Iterable[Any], str], FinalTransform]
-# For the string parsing factory
-StrSplitter = Callable[[str], Iterable[str]]
-StrParser = Callable[[str], FinalTransform]
-
# For the path splitter
PathArg = Union[str, PurePath]
MatchFn = Callable[[str], Optional[Match]]
+# For the string parsing factory
+StrSplitter = Callable[[str], Iterable[str]]
+StrParser = Callable[[PathArg], FinalTransform]
+
# For the path parsing factory
PathSplitter = Callable[[PathArg], Tuple[FinalTransform, ...]]
@@ -493,7 +493,11 @@ def parse_string_factory(
normalize_input = _normalize_input_factory(alg)
compose_input = _compose_input_factory(alg) if alg & ns.LOCALEALPHA else _no_op
- def func(x: str) -> FinalTransform:
+ def func(x: PathArg) -> FinalTransform:
+ if isinstance(x, PurePath):
+ # While paths are technically not strings, it is natural for them
+ # to be treated the same.
+ x = str(x)
# Apply string input transformation function and return to x.
# Original function is usually a no-op, but some algorithms require it
# to also be the transformation function.
diff --git a/tests/test_natsorted.py b/tests/test_natsorted.py
index eb3aefe..eccb9d2 100644
--- a/tests/test_natsorted.py
+++ b/tests/test_natsorted.py
@@ -5,6 +5,7 @@ See the README or the natsort homepage for more details.
"""
from operator import itemgetter
+from pathlib import PurePosixPath
from typing import List, Tuple, Union
import pytest
@@ -84,6 +85,15 @@ def test_natsorted_can_sort_as_version_numbers() -> None:
assert natsorted(given) == expected
+def test_natsorted_can_sorts_paths_same_as_strings() -> None:
+ paths = [
+ PurePosixPath("a/1/something"),
+ PurePosixPath("a/2/something"),
+ PurePosixPath("a/10/something"),
+ ]
+ assert [str(p) for p in natsorted(paths)] == natsorted([str(p) for p in paths])
+
+
@pytest.mark.parametrize(
"alg, expected",
[