summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeth M Morton <seth.m.morton@gmail.com>2018-08-04 19:48:12 -0700
committerSeth M Morton <seth.m.morton@gmail.com>2018-08-10 15:02:25 -0400
commitc556296ff88902354da9f73a3555b5be3facaba8 (patch)
tree40473b8b999e7612c18a6cc91fc8b728f730e8b8
parentb613c763c581940561118ef4c3660db3d6a9cb2d (diff)
downloadnatsort-c556296ff88902354da9f73a3555b5be3facaba8.tar.gz
Blacken code.
As part of the blackening, the huge tuple of hex literals that represent unicode numerals has been placed into its own file, and the _version.py contents has been moved to __init__.py. PEP8 checks are updated to conform to black's style.
-rw-r--r--natsort/__init__.py52
-rw-r--r--natsort/__main__.py231
-rw-r--r--natsort/_version.py9
-rw-r--r--natsort/compat/fake_fastnumbers.py53
-rw-r--r--natsort/compat/fastnumbers.py20
-rw-r--r--natsort/compat/locale.py108
-rw-r--r--natsort/compat/pathlib.py7
-rw-r--r--natsort/compat/py23.py35
-rw-r--r--natsort/natsort.py34
-rw-r--r--natsort/ns_enum.py52
-rw-r--r--natsort/unicode_numbers.py322
-rw-r--r--natsort/unicode_numeric_hex.py1750
-rw-r--r--natsort/utils.py150
-rw-r--r--setup.cfg9
-rw-r--r--test_natsort/compat/locale.py17
-rw-r--r--test_natsort/compat/mock.py8
-rw-r--r--test_natsort/profile_natsorted.py54
-rw-r--r--test_natsort/slow_splitters.py71
-rw-r--r--test_natsort/test_fake_fastnumbers.py55
-rw-r--r--test_natsort/test_final_data_transform_factory.py62
-rw-r--r--test_natsort/test_input_string_transform_factory.py178
-rw-r--r--test_natsort/test_main.py123
-rw-r--r--test_natsort/test_natsort_cmp.py19
-rw-r--r--test_natsort/test_natsort_key.py50
-rw-r--r--test_natsort/test_natsort_keygen.py153
-rw-r--r--test_natsort/test_natsorted.py533
-rw-r--r--test_natsort/test_natsorted_convenience.py48
-rw-r--r--test_natsort/test_parse_bytes_function.py16
-rw-r--r--test_natsort/test_parse_number_function.py50
-rw-r--r--test_natsort/test_parse_string_function.py208
-rw-r--r--test_natsort/test_string_component_transform_factory.py109
-rw-r--r--test_natsort/test_unicode_numbers.py8
-rw-r--r--test_natsort/test_utils.py121
33 files changed, 3361 insertions, 1354 deletions
diff --git a/natsort/__init__.py b/natsort/__init__.py
index 45ede6e..81a2309 100644
--- a/natsort/__init__.py
+++ b/natsort/__init__.py
@@ -1,17 +1,11 @@
# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
-# Local imports.
+# Std. lib imports.
import sys
+# Local imports.
from natsort.utils import chain_functions
-from natsort._version import __version__
-
from natsort.natsort import (
natsort_key,
natsort_keygen,
@@ -33,27 +27,27 @@ from natsort.natsort import (
if float(sys.version[:3]) < 3:
from natsort.natsort import natcmp
+__version__ = "5.3.3"
+
__all__ = [
- 'natsort_key',
- 'natsort_keygen',
- 'natsorted',
- 'versorted',
- 'humansorted',
- 'realsorted',
- 'index_natsorted',
- 'index_versorted',
- 'index_humansorted',
- 'index_realsorted',
- 'order_by_index',
- 'decoder',
- 'natcmp',
- 'as_ascii',
- 'as_utf8',
- 'ns',
- 'chain_functions',
+ "natsort_key",
+ "natsort_keygen",
+ "natsorted",
+ "versorted",
+ "humansorted",
+ "realsorted",
+ "index_natsorted",
+ "index_versorted",
+ "index_humansorted",
+ "index_realsorted",
+ "order_by_index",
+ "decoder",
+ "natcmp",
+ "as_ascii",
+ "as_utf8",
+ "ns",
+ "chain_functions",
]
# Add the ns keys to this namespace for convenience.
-globals().update(
- dict((k, v) for k, v in vars(ns).items() if not k.startswith('_'))
-)
+globals().update(dict((k, v) for k, v in vars(ns).items() if not k.startswith("_")))
diff --git a/natsort/__main__.py b/natsort/__main__.py
index f2b4e29..5cdc0b2 100644
--- a/natsort/__main__.py
+++ b/natsort/__main__.py
@@ -1,18 +1,12 @@
# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
# Std. lib imports.
import sys
# Local imports.
-from natsort.natsort import natsorted, ns
+import natsort
from natsort.utils import _regex_chooser
-from natsort._version import __version__
from natsort.compat.py23 import py23_str
@@ -25,67 +19,118 @@ def main():
from argparse import ArgumentParser, RawDescriptionHelpFormatter
from textwrap import dedent
- parser = ArgumentParser(description=dedent(main.__doc__),
- formatter_class=RawDescriptionHelpFormatter)
- parser.add_argument('--version', action='version',
- version='%(prog)s {0}'.format(__version__))
+
+ parser = ArgumentParser(
+ description=dedent(main.__doc__), formatter_class=RawDescriptionHelpFormatter
+ )
+ parser.add_argument(
+ "--version",
+ action="version",
+ version="%(prog)s {0}".format(natsort.__version__),
+ )
parser.add_argument(
- '-p', '--paths', default=False, action='store_true',
- help='Interpret the input as file paths. This is not '
- 'strictly necessary to sort all file paths, but in cases '
- 'where there are OS-generated file paths like "Folder/" '
- 'and "Folder (1)/", this option is needed to make the '
- 'paths sorted in the order you expect ("Folder/" before '
- '"Folder (1)/").')
+ "-p",
+ "--paths",
+ default=False,
+ action="store_true",
+ help="Interpret the input as file paths. This is not "
+ "strictly necessary to sort all file paths, but in cases "
+ 'where there are OS-generated file paths like "Folder/" '
+ 'and "Folder (1)/", this option is needed to make the '
+ 'paths sorted in the order you expect ("Folder/" before '
+ '"Folder (1)/").',
+ )
parser.add_argument(
- '-f', '--filter', nargs=2, type=float, metavar=('LOW', 'HIGH'),
- action='append',
- help='Used for keeping only the entries that have a number '
- 'falling in the given range.')
+ "-f",
+ "--filter",
+ nargs=2,
+ type=float,
+ metavar=("LOW", "HIGH"),
+ action="append",
+ help="Used for keeping only the entries that have a number "
+ "falling in the given range.",
+ )
parser.add_argument(
- '-F', '--reverse-filter', nargs=2, type=float,
- metavar=('LOW', 'HIGH'), action='append', dest='reverse_filter',
- help='Used for excluding the entries that have a number '
- 'falling in the given range.')
+ "-F",
+ "--reverse-filter",
+ nargs=2,
+ type=float,
+ metavar=("LOW", "HIGH"),
+ action="append",
+ dest="reverse_filter",
+ help="Used for excluding the entries that have a number "
+ "falling in the given range.",
+ )
parser.add_argument(
- '-e', '--exclude', type=float, action='append',
- help='Used to exclude an entry that contains a specific number.')
+ "-e",
+ "--exclude",
+ type=float,
+ action="append",
+ help="Used to exclude an entry that contains a specific number.",
+ )
parser.add_argument(
- '-r', '--reverse', action='store_true', default=False,
- help='Returns in reversed order.')
+ "-r",
+ "--reverse",
+ action="store_true",
+ default=False,
+ help="Returns in reversed order.",
+ )
parser.add_argument(
- '-t', '--number-type', '--number_type', dest='number_type',
- choices=('digit', 'int', 'float', 'version', 'ver',
- 'real', 'f', 'i', 'r', 'd'),
- default='int',
+ "-t",
+ "--number-type",
+ "--number_type",
+ dest="number_type",
+ choices=("digit", "int", "float", "version", "ver", "real", "f", "i", "r", "d"),
+ default="int",
help='Choose the type of number to search for. "float" will search '
- 'for floating-point numbers. "int" will only search for '
- 'integers. "digit", "version", and "ver" are synonyms for "int".'
- '"real" is a shortcut for "float" with --sign. '
- '"i" and "d" are synonyms for "int", "f" is a synonym for '
- '"float", and "r" is a synonym for "real".'
- 'The default is %(default)s.')
+ 'for floating-point numbers. "int" will only search for '
+ 'integers. "digit", "version", and "ver" are synonyms for "int".'
+ '"real" is a shortcut for "float" with --sign. '
+ '"i" and "d" are synonyms for "int", "f" is a synonym for '
+ '"float", and "r" is a synonym for "real".'
+ "The default is %(default)s.",
+ )
parser.add_argument(
- '--nosign', default=False, action='store_false', dest='signed',
+ "--nosign",
+ default=False,
+ action="store_false",
+ dest="signed",
help='Do not consider "+" or "-" as part of a number, i.e. do not '
- 'take sign into consideration. This is the default.')
+ "take sign into consideration. This is the default.",
+ )
parser.add_argument(
- '-s', '--sign', default=False, action='store_true', dest='signed',
+ "-s",
+ "--sign",
+ default=False,
+ action="store_true",
+ dest="signed",
help='Consider "+" or "-" as part of a number, i.e. '
- 'take sign into consideration. The default is unsigned.')
+ "take sign into consideration. The default is unsigned.",
+ )
parser.add_argument(
- '--noexp', default=True, action='store_false', dest='exp',
- help='Do not consider an exponential as part of a number, i.e. 1e4, '
- 'would be considered as 1, "e", and 4, not as 10000. This only '
- 'effects the --number-type=float.')
+ "--noexp",
+ default=True,
+ action="store_false",
+ dest="exp",
+ help="Do not consider an exponential as part of a number, i.e. 1e4, "
+ 'would be considered as 1, "e", and 4, not as 10000. This only '
+ "effects the --number-type=float.",
+ )
parser.add_argument(
- '-l', '--locale', action='store_true', default=False,
- help='Causes natsort to use locale-aware sorting. You will get the '
- 'best results if you install PyICU.')
+ "-l",
+ "--locale",
+ action="store_true",
+ default=False,
+ help="Causes natsort to use locale-aware sorting. You will get the "
+ "best results if you install PyICU.",
+ )
parser.add_argument(
- 'entries', nargs='*', default=sys.stdin,
- help='The entries to sort. Taken from stdin if nothing is given on '
- 'the command line.', )
+ "entries",
+ nargs="*",
+ default=sys.stdin,
+ help="The entries to sort. Taken from stdin if nothing is given on "
+ "the command line.",
+ )
args = parser.parse_args()
# Make sure the filter range is given properly. Does nothing if no filter
@@ -106,7 +151,7 @@ def range_check(low, high):
Otherwise the input is returned as-is.
"""
if low >= high:
- raise ValueError('low >= high')
+ raise ValueError("low >= high")
else:
return low, high
@@ -123,8 +168,8 @@ def check_filter(filt):
return None
try:
return [range_check(f[0], f[1]) for f in filt]
- except ValueError as a:
- raise ValueError('Error in --filter: '+py23_str(a))
+ except ValueError as err:
+ raise ValueError("Error in --filter: " + py23_str(err))
def keep_entry_range(entry, lows, highs, converter, regex):
@@ -135,9 +180,11 @@ def keep_entry_range(entry, lows, highs, converter, regex):
Returns True if it should be kept (i.e. falls in the range),
and False if it is not in the range and should not be kept.
"""
- return any(low <= converter(num) <= high
- for num in regex.findall(entry)
- for low, high in zip(lows, highs))
+ return any(
+ low <= converter(num) <= high
+ for num in regex.findall(entry)
+ for low, high in zip(lows, highs)
+ )
def exclude_entry(entry, values, converter, regex):
@@ -155,48 +202,58 @@ def sort_and_print_entries(entries, args):
"""Sort the entries, applying the filters first if necessary."""
# Extract the proper number type.
- is_float = args.number_type in ('float', 'real', 'f', 'r')
- signed = args.signed or args.number_type in ('real', 'r')
- alg = (ns.FLOAT * is_float |
- ns.SIGNED * signed |
- ns.NOEXP * (not args.exp) |
- ns.PATH * args.paths |
- ns.LOCALE * args.locale)
+ is_float = args.number_type in ("float", "real", "f", "r")
+ signed = args.signed or args.number_type in ("real", "r")
+ alg = (
+ natsort.ns.FLOAT * is_float
+ | natsort.ns.SIGNED * signed
+ | natsort.ns.NOEXP * (not args.exp)
+ | natsort.ns.PATH * args.paths
+ | natsort.ns.LOCALE * args.locale
+ )
# Pre-remove entries that don't pass the filtering criteria
# Make sure we use the same searching algorithm for filtering
# as for sorting.
do_filter = args.filter is not None or args.reverse_filter is not None
if do_filter or args.exclude:
- inp_options = (ns.FLOAT * is_float |
- ns.SIGNED * signed |
- ns.NOEXP * (not args.exp)
- )
+ inp_options = (
+ natsort.ns.FLOAT * is_float
+ | natsort.ns.SIGNED * signed
+ | natsort.ns.NOEXP * (not args.exp)
+ )
regex = _regex_chooser[inp_options]
if args.filter is not None:
- lows, highs = ([f[0] for f in args.filter],
- [f[1] for f in args.filter])
- entries = [entry for entry in entries
- if keep_entry_range(entry, lows, highs,
- float, regex)]
+ lows, highs = ([f[0] for f in args.filter], [f[1] for f in args.filter])
+ entries = [
+ entry
+ for entry in entries
+ if keep_entry_range(entry, lows, highs, float, regex)
+ ]
if args.reverse_filter is not None:
- lows, highs = ([f[0] for f in args.reverse_filter],
- [f[1] for f in args.reverse_filter])
- entries = [entry for entry in entries
- if not keep_entry_range(entry, lows, highs,
- float, regex)]
+ lows, highs = (
+ [f[0] for f in args.reverse_filter],
+ [f[1] for f in args.reverse_filter],
+ )
+ entries = [
+ entry
+ for entry in entries
+ if not keep_entry_range(entry, lows, highs, float, regex)
+ ]
if args.exclude:
exclude = set(args.exclude)
- entries = [entry for entry in entries
- if exclude_entry(entry, exclude,
- float, regex)]
+ entries = [
+ entry
+ for entry in entries
+ if exclude_entry(entry, exclude, float, regex)
+ ]
# Print off the sorted results
- for entry in natsorted(entries, reverse=args.reverse, alg=alg):
+ for entry in natsort.natsorted(entries, reverse=args.reverse, alg=alg):
print(entry)
-if __name__ == '__main__':
+if __name__ == "__main__":
try:
main()
except ValueError as a:
diff --git a/natsort/_version.py b/natsort/_version.py
deleted file mode 100644
index e362806..0000000
--- a/natsort/_version.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
-
-__version__ = '5.3.3'
diff --git a/natsort/compat/fake_fastnumbers.py b/natsort/compat/fake_fastnumbers.py
index 6eee532..68076a4 100644
--- a/natsort/compat/fake_fastnumbers.py
+++ b/natsort/compat/fake_fastnumbers.py
@@ -4,31 +4,48 @@ This module is intended to replicate some of the functionality
from the fastnumbers module in the event that module is not
installed.
"""
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
# Std. lib imports.
import unicodedata
from natsort.unicode_numbers import decimal_chars
from natsort.compat.py23 import PY_VERSION
+
if PY_VERSION >= 3:
long = int
-NAN_INF = ['INF', 'INf', 'Inf', 'inF', 'iNF', 'InF', 'inf', 'iNf',
- 'NAN', 'nan', 'NaN', 'nAn', 'naN', 'NAn', 'nAN', 'Nan']
-NAN_INF.extend(['+'+x[:2] for x in NAN_INF] + ['-'+x[:2] for x in NAN_INF])
+NAN_INF = [
+ "INF",
+ "INf",
+ "Inf",
+ "inF",
+ "iNF",
+ "InF",
+ "inf",
+ "iNf",
+ "NAN",
+ "nan",
+ "NaN",
+ "nAn",
+ "naN",
+ "NAn",
+ "nAN",
+ "Nan",
+]
+NAN_INF.extend(["+" + x[:2] for x in NAN_INF] + ["-" + x[:2] for x in NAN_INF])
NAN_INF = frozenset(NAN_INF)
-ASCII_NUMS = '0123456789+-'
+ASCII_NUMS = "0123456789+-"
-def fast_float(x, key=lambda x: x, nan=None,
- uni=unicodedata.numeric, nan_inf=NAN_INF,
- _first_char=frozenset(decimal_chars + list(ASCII_NUMS + '.'))):
+def fast_float(
+ x,
+ key=lambda x: x,
+ nan=None,
+ uni=unicodedata.numeric,
+ nan_inf=NAN_INF,
+ _first_char=frozenset(decimal_chars + list(ASCII_NUMS + ".")),
+):
"""\
Convert a string to a float quickly, return input as-is if not possible.
We don't need to accept all input that the real fast_int accepts because
@@ -50,13 +67,19 @@ def fast_float(x, key=lambda x: x, nan=None,
return key(x)
-def fast_int(x, key=lambda x: x, nan=None, uni=unicodedata.digit,
- _first_char=frozenset(decimal_chars + list(ASCII_NUMS))):
+def fast_int(
+ x,
+ key=lambda x: x,
+ nan=None,
+ uni=unicodedata.digit,
+ _first_char=frozenset(decimal_chars + list(ASCII_NUMS)),
+):
"""\
Convert a string to a int quickly, return input as-is if not possible.
We don't need to accept all input that the real fast_int accepts because
the input will be controlled by the splitting algorithm.
"""
+ del nan # explicitly indicate we are not using the nan argument
if x[0] in _first_char:
try:
return long(x)
diff --git a/natsort/compat/fastnumbers.py b/natsort/compat/fastnumbers.py
index 787b553..3c15acc 100644
--- a/natsort/compat/fastnumbers.py
+++ b/natsort/compat/fastnumbers.py
@@ -1,26 +1,16 @@
# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
from distutils.version import StrictVersion
# If the user has fastnumbers installed, they will get great speed
# benefits. If not, we use the simulated functions that come with natsort.
try:
- from fastnumbers import (
- fast_float,
- fast_int,
- )
+ from fastnumbers import fast_float, fast_int
import fastnumbers
+
# Require >= version 0.7.1.
- if StrictVersion(fastnumbers.__version__) < StrictVersion('0.7.1'):
+ if StrictVersion(fastnumbers.__version__) < StrictVersion("0.7.1"):
raise ImportError # pragma: no cover
except ImportError:
- from natsort.compat.fake_fastnumbers import (
- fast_float,
- fast_int,
- )
+ from natsort.compat.fake_fastnumbers import fast_float, fast_int
diff --git a/natsort/compat/locale.py b/natsort/compat/locale.py
index ab392ee..a31a42c 100644
--- a/natsort/compat/locale.py
+++ b/natsort/compat/locale.py
@@ -1,25 +1,16 @@
# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
# Std. lib imports.
import sys
# Local imports.
-from natsort.compat.py23 import (
- PY_VERSION,
- cmp_to_key,
- py23_unichr,
-)
+from natsort.compat.py23 import PY_VERSION, cmp_to_key, py23_unichr
# This string should be sorted after any other byte string because
# it contains the max unicode character repeated 20 times.
# You would need some odd data to come after that.
-null_string = ''
+null_string = ""
null_string_max = py23_unichr(sys.maxunicode) * 20
# Make the strxfrm function from strcoll on Python2
@@ -29,12 +20,12 @@ try:
import icu
from locale import getlocale
- null_string_locale = b''
+ null_string_locale = b""
# This string should in theory be sorted after any other byte
# string because it contains the max byte char repeated many times.
# You would need some odd data to come after that.
- null_string_locale_max = b'x7f' * 50
+ null_string_locale_max = b"x7f" * 50
def dumb_sort():
return False
@@ -42,7 +33,7 @@ try:
# If using icu, get the locale from the current global locale,
def get_icu_locale():
try:
- return icu.Locale('.'.join(getlocale()))
+ return icu.Locale(".".join(getlocale()))
except TypeError: # pragma: no cover
return icu.Locale()
@@ -57,10 +48,13 @@ try:
sep = icu.DecimalFormatSymbols.kDecimalSeparatorSymbol
return icu.DecimalFormatSymbols(get_icu_locale()).getSymbol(sep)
+
except ImportError:
import locale
+
if PY_VERSION < 3:
from locale import strcoll
+
sentinel = object()
def custom_strcoll(a, b, last=sentinel):
@@ -73,11 +67,12 @@ except ImportError:
return strcoll(a, b)
strxfrm = cmp_to_key(custom_strcoll)
- null_string_locale = strxfrm('')
+ null_string_locale = strxfrm("")
null_string_locale_max = strxfrm(sentinel)
else:
from locale import strxfrm
- null_string_locale = ''
+
+ null_string_locale = ""
# This string should be sorted after any other byte string because
# it contains the max unicode character repeated 20 times.
@@ -87,57 +82,58 @@ except ImportError:
# On some systems, locale is broken and does not sort in the expected
# order. We will try to detect this and compensate.
def dumb_sort():
- return strxfrm('A') < strxfrm('a')
+ return strxfrm("A") < strxfrm("a")
def get_strxfrm():
return strxfrm
def get_thousands_sep():
- sep = locale.localeconv()['thousands_sep']
+ sep = locale.localeconv()["thousands_sep"]
# If this locale library is broken, some of the thousands separator
# characters are incorrectly blank. Here is a lookup table of the
# corrections I am aware of.
if dumb_sort():
try:
- loc = '.'.join(locale.getlocale())
+ loc = ".".join(locale.getlocale())
except TypeError: # No locale loaded, default to ','
- return ','
- return {'de_DE.ISO8859-15': '.',
- 'es_ES.ISO8859-1': '.',
- 'de_AT.ISO8859-1': '.',
- 'de_at': '\xa0',
- 'nl_NL.UTF-8': '.',
- 'es_es': '.',
- 'fr_CH.ISO8859-15': '\xa0',
- 'fr_CA.ISO8859-1': '\xa0',
- 'de_CH.ISO8859-1': '.',
- 'fr_FR.ISO8859-15': '\xa0',
- 'nl_NL.ISO8859-1': '.',
- 'ca_ES.UTF-8': '.',
- 'nl_NL.ISO8859-15': '.',
- 'de_ch': "'",
- 'ca_es': '.',
- 'de_AT.ISO8859-15': '.',
- 'ca_ES.ISO8859-1': '.',
- 'de_AT.UTF-8': '.',
- 'es_ES.UTF-8': '.',
- 'fr_fr': '\xa0',
- 'es_ES.ISO8859-15': '.',
- 'de_DE.ISO8859-1': '.',
- 'nl_nl': '.',
- 'fr_ch': '\xa0',
- 'fr_ca': '\xa0',
- 'de_DE.UTF-8': '.',
- 'ca_ES.ISO8859-15': '.',
- 'de_CH.ISO8859-15': '.',
- 'fr_FR.ISO8859-1': '\xa0',
- 'fr_CH.ISO8859-1': '\xa0',
- 'de_de': '.',
- 'fr_FR.UTF-8': '\xa0',
- 'fr_CA.ISO8859-15': '\xa0',
- }.get(loc, sep)
+ return ","
+ return {
+ "de_DE.ISO8859-15": ".",
+ "es_ES.ISO8859-1": ".",
+ "de_AT.ISO8859-1": ".",
+ "de_at": "\xa0",
+ "nl_NL.UTF-8": ".",
+ "es_es": ".",
+ "fr_CH.ISO8859-15": "\xa0",
+ "fr_CA.ISO8859-1": "\xa0",
+ "de_CH.ISO8859-1": ".",
+ "fr_FR.ISO8859-15": "\xa0",
+ "nl_NL.ISO8859-1": ".",
+ "ca_ES.UTF-8": ".",
+ "nl_NL.ISO8859-15": ".",
+ "de_ch": "'",
+ "ca_es": ".",
+ "de_AT.ISO8859-15": ".",
+ "ca_ES.ISO8859-1": ".",
+ "de_AT.UTF-8": ".",
+ "es_ES.UTF-8": ".",
+ "fr_fr": "\xa0",
+ "es_ES.ISO8859-15": ".",
+ "de_DE.ISO8859-1": ".",
+ "nl_nl": ".",
+ "fr_ch": "\xa0",
+ "fr_ca": "\xa0",
+ "de_DE.UTF-8": ".",
+ "ca_ES.ISO8859-15": ".",
+ "de_CH.ISO8859-15": ".",
+ "fr_FR.ISO8859-1": "\xa0",
+ "fr_CH.ISO8859-1": "\xa0",
+ "de_de": ".",
+ "fr_FR.UTF-8": "\xa0",
+ "fr_CA.ISO8859-15": "\xa0",
+ }.get(loc, sep)
else:
return sep
def get_decimal_point():
- return locale.localeconv()['decimal_point']
+ return locale.localeconv()["decimal_point"]
diff --git a/natsort/compat/pathlib.py b/natsort/compat/pathlib.py
index f0ab7eb..e95e847 100644
--- a/natsort/compat/pathlib.py
+++ b/natsort/compat/pathlib.py
@@ -1,10 +1,5 @@
# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
try:
from pathlib import PurePath # PurePath is the base object for Paths.
diff --git a/natsort/compat/py23.py b/natsort/compat/py23.py
index fa56b06..7d1bad2 100644
--- a/natsort/compat/py23.py
+++ b/natsort/compat/py23.py
@@ -1,10 +1,5 @@
# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
import functools
import sys
@@ -19,31 +14,32 @@ PY_VERSION = float(sys.version[:3])
NEWPY = PY_VERSION >= 3.3
# Assume all strings are Unicode in Python 2
-py23_str = str if sys.version[0] == '3' else unicode
+py23_str = str if sys.version[0] == "3" else unicode
# Use the range iterator always
-py23_range = range if sys.version[0] == '3' else xrange
+py23_range = range if sys.version[0] == "3" else xrange
# Uniform base string type
-py23_basestring = str if sys.version[0] == '3' else basestring
+py23_basestring = str if sys.version[0] == "3" else basestring
# unichr function
-py23_unichr = chr if sys.version[0] == '3' else unichr
+py23_unichr = chr if sys.version[0] == "3" else unichr
def _py23_cmp(a, b):
return (a > b) - (a < b)
-py23_cmp = _py23_cmp if sys.version[0] == '3' else cmp
+py23_cmp = _py23_cmp if sys.version[0] == "3" else cmp
# zip as an iterator
-if sys.version[0] == '3':
+if sys.version[0] == "3":
py23_zip = zip
py23_map = map
py23_filter = filter
else:
import itertools
+
py23_zip = itertools.izip
py23_map = itertools.imap
py23_filter = itertools.ifilter
@@ -53,10 +49,12 @@ else:
try:
from functools import cmp_to_key
except ImportError: # pragma: no cover
+
def cmp_to_key(mycmp):
"""Convert a cmp= function into a key= function"""
+
class K(object):
- __slots__ = ['obj']
+ __slots__ = ["obj"]
def __init__(self, obj):
self.obj = obj
@@ -80,7 +78,7 @@ except ImportError: # pragma: no cover
return mycmp(self.obj, other.obj) != 0
def __hash__(self):
- raise TypeError('hash not implemented')
+ raise TypeError("hash not implemented")
return K
@@ -104,18 +102,21 @@ def _modify_str_or_docstring(str_change_func):
func.__doc__ = doc
return func
return doc
+
return wrapper
# Properly modify a doctstring to either have the unicode literal or not.
-if sys.version[0] == '3':
+if sys.version[0] == "3":
# Abstract u'abc' syntax:
@_modify_str_or_docstring
def u_format(s):
""""{u}'abc'" --> "'abc'" (Python 3)
Accepts a string or a function, so it can be used as a decorator."""
- return s.format(u='')
+ return s.format(u="")
+
+
else:
# Abstract u'abc' syntax:
@_modify_str_or_docstring
@@ -123,4 +124,4 @@ else:
""""{u}'abc'" --> "u'abc'" (Python 2)
Accepts a string or a function, so it can be used as a decorator."""
- return s.format(u='u')
+ return s.format(u="u")
diff --git a/natsort/natsort.py b/natsort/natsort.py
index 557e07b..66c663e 100644
--- a/natsort/natsort.py
+++ b/natsort/natsort.py
@@ -10,12 +10,7 @@ descend into lists of lists so you can sort by the sublist contents.
See the README or the natsort homepage for more details.
"""
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
# Std lib. imports.
from operator import itemgetter
@@ -27,10 +22,7 @@ import sys
import natsort.compat.locale
from natsort.ns_enum import ns
-from natsort.compat.py23 import (
- u_format,
- py23_str,
- py23_cmp)
+from natsort.compat.py23 import u_format, py23_str, py23_cmp
from natsort.utils import (
_natsort_key,
_args_to_enum,
@@ -113,7 +105,7 @@ def as_ascii(s):
decoder
"""
- return _do_decoding(s, 'ascii')
+ return _do_decoding(s, "ascii")
@u_format
@@ -138,7 +130,7 @@ def as_utf8(s):
decoder
"""
- return _do_decoding(s, 'utf-8')
+ return _do_decoding(s, "utf-8")
def natsort_key(val, key=None, alg=0, **_kwargs):
@@ -200,7 +192,7 @@ def natsort_keygen(key=None, alg=0, **_kwargs):
alg = _args_to_enum(**_kwargs) | alg
except TypeError:
msg = "natsort_keygen: 'alg' argument must be from the enum 'ns'"
- raise ValueError(msg+', got {0}'.format(py23_str(alg)))
+ raise ValueError(msg + ", got {0}".format(py23_str(alg)))
# Add the _DUMB option if the locale library is broken.
if alg & ns.LOCALEALPHA and natsort.compat.locale.dumb_sort():
@@ -228,8 +220,7 @@ def natsort_keygen(key=None, alg=0, **_kwargs):
# Create the high-level parsing functions for strings, bytes, and numbers.
string_func = _parse_string_factory(
- alg, sep, regex.split,
- input_transform, component_transform, final_transform
+ alg, sep, regex.split, input_transform, component_transform, final_transform
)
if alg & ns.PATH:
string_func = _parse_path_factory(string_func)
@@ -242,7 +233,7 @@ def natsort_keygen(key=None, alg=0, **_kwargs):
key=key,
string_func=string_func,
bytes_func=bytes_func,
- num_func=num_func
+ num_func=num_func,
)
@@ -485,12 +476,13 @@ def index_natsorted(seq, key=None, reverse=False, alg=0, **_kwargs):
if key is None:
newkey = itemgetter(1)
else:
+
def newkey(x):
return key(itemgetter(1)(x))
+
# Pair the index and sequence together, then sort by element
index_seq_pair = [[x, y] for x, y in enumerate(seq)]
- index_seq_pair.sort(reverse=reverse,
- key=natsort_keygen(newkey, alg, **_kwargs))
+ index_seq_pair.sort(reverse=reverse, key=natsort_keygen(newkey, alg, **_kwargs))
return [x for x, _ in index_seq_pair]
@@ -726,15 +718,15 @@ if float(sys.version[:3]) < 3:
>>> natcmp(one, two)
-1
"""
+
cached_keys = {}
def __new__(cls, x, y, alg=0, *args, **kwargs):
try:
alg = _args_to_enum(**kwargs) | alg
except TypeError:
- msg = ("natsort_keygen: 'alg' argument must be "
- "from the enum 'ns'")
- raise ValueError(msg + ', got {0}'.format(py23_str(alg)))
+ msg = "natsort_keygen: 'alg' argument must be " "from the enum 'ns'"
+ raise ValueError(msg + ", got {0}".format(py23_str(alg)))
# Add the _DUMB option if the locale library is broken.
if alg & ns.LOCALEALPHA and natsort.compat.locale.dumb_sort():
diff --git a/natsort/ns_enum.py b/natsort/ns_enum.py
index b3aa917..54ca133 100644
--- a/natsort/ns_enum.py
+++ b/natsort/ns_enum.py
@@ -1,11 +1,6 @@
# -*- coding: utf-8 -*-
"""This module defines the "ns" enum for natsort."""
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
class ns(object):
@@ -130,32 +125,33 @@ class ns(object):
True
"""
+
# Following were previously now options but are now defaults.
- TYPESAFE = T = 0
- INT = I = 0
- VERSION = V = 0
- DIGIT = D = 0
- UNSIGNED = U = 0
+ TYPESAFE = T = 0
+ INT = I = 0
+ VERSION = V = 0
+ DIGIT = D = 0
+ UNSIGNED = U = 0
# The below are options. The values are stored as powers of two
# so bitmasks can be used to extract the user's requested options.
- FLOAT = F = 1 << 0
- SIGNED = S = 1 << 1
- REAL = R = FLOAT | SIGNED
- NOEXP = N = 1 << 2
- PATH = P = 1 << 3
- LOCALEALPHA = LA = 1 << 4
- LOCALENUM = LN = 1 << 5
- LOCALE = L = LOCALEALPHA | LOCALENUM
- IGNORECASE = IC = 1 << 6
- LOWERCASEFIRST = LF = 1 << 7
- GROUPLETTERS = G = 1 << 8
- UNGROUPLETTERS = UG = 1 << 9
- CAPITALFIRST = C = UNGROUPLETTERS
- NANLAST = NL = 1 << 10
+ FLOAT = F = 1 << 0
+ SIGNED = S = 1 << 1
+ REAL = R = FLOAT | SIGNED
+ NOEXP = N = 1 << 2
+ PATH = P = 1 << 3
+ LOCALEALPHA = LA = 1 << 4
+ LOCALENUM = LN = 1 << 5
+ LOCALE = L = LOCALEALPHA | LOCALENUM
+ IGNORECASE = IC = 1 << 6
+ LOWERCASEFIRST = LF = 1 << 7
+ GROUPLETTERS = G = 1 << 8
+ UNGROUPLETTERS = UG = 1 << 9
+ CAPITALFIRST = C = UNGROUPLETTERS
+ NANLAST = NL = 1 << 10
COMPATIBILITYNORMALIZE = CN = 1 << 11
- NUMAFTER = NA = 1 << 12
+ NUMAFTER = NA = 1 << 12
# The below are private options for internal use only.
- _NUMERIC_ONLY = REAL | NOEXP
- _DUMB = 1 << 31
+ _NUMERIC_ONLY = REAL | NOEXP
+ _DUMB = 1 << 31
diff --git a/natsort/unicode_numbers.py b/natsort/unicode_numbers.py
index a0ae0a5..86172df 100644
--- a/natsort/unicode_numbers.py
+++ b/natsort/unicode_numbers.py
@@ -2,291 +2,15 @@
"""
Contains all possible non-ASCII unicode numbers.
"""
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
# Std. lib imports.
import unicodedata
# Local imports.
+from natsort.unicode_numeric_hex import numeric_hex
from natsort.compat.py23 import py23_unichr
-
-# Rather than determine this on the fly, which would incur a startup
-# runtime penalty, the hex values of the Unicode numeric characters
-# are hard-coded below.
-numeric_hex = (
- 0XB2, 0XB3, 0XB9, 0XBC, 0XBD, 0XBE, 0X660, 0X661, 0X662,
- 0X663, 0X664, 0X665, 0X666, 0X667, 0X668, 0X669, 0X6F0,
- 0X6F1, 0X6F2, 0X6F3, 0X6F4, 0X6F5, 0X6F6, 0X6F7, 0X6F8,
- 0X6F9, 0X7C0, 0X7C1, 0X7C2, 0X7C3, 0X7C4, 0X7C5, 0X7C6,
- 0X7C7, 0X7C8, 0X7C9, 0X966, 0X967, 0X968, 0X969, 0X96A,
- 0X96B, 0X96C, 0X96D, 0X96E, 0X96F, 0X9E6, 0X9E7, 0X9E8,
- 0X9E9, 0X9EA, 0X9EB, 0X9EC, 0X9ED, 0X9EE, 0X9EF, 0X9F4,
- 0X9F5, 0X9F6, 0X9F7, 0X9F8, 0X9F9, 0XA66, 0XA67, 0XA68,
- 0XA69, 0XA6A, 0XA6B, 0XA6C, 0XA6D, 0XA6E, 0XA6F, 0XAE6,
- 0XAE7, 0XAE8, 0XAE9, 0XAEA, 0XAEB, 0XAEC, 0XAED, 0XAEE,
- 0XAEF, 0XB66, 0XB67, 0XB68, 0XB69, 0XB6A, 0XB6B, 0XB6C,
- 0XB6D, 0XB6E, 0XB6F, 0XB72, 0XB73, 0XB74, 0XB75, 0XB76,
- 0XB77, 0XBE6, 0XBE7, 0XBE8, 0XBE9, 0XBEA, 0XBEB, 0XBEC,
- 0XBED, 0XBEE, 0XBEF, 0XBF0, 0XBF1, 0XBF2, 0XC66, 0XC67,
- 0XC68, 0XC69, 0XC6A, 0XC6B, 0XC6C, 0XC6D, 0XC6E, 0XC6F,
- 0XC78, 0XC79, 0XC7A, 0XC7B, 0XC7C, 0XC7D, 0XC7E, 0XCE6,
- 0XCE7, 0XCE8, 0XCE9, 0XCEA, 0XCEB, 0XCEC, 0XCED, 0XCEE,
- 0XCEF, 0XD58, 0XD59, 0XD5A, 0XD5B, 0XD5C, 0XD5D, 0XD5E,
- 0XD66, 0XD67, 0XD68, 0XD69, 0XD6A, 0XD6B, 0XD6C, 0XD6D,
- 0XD6E, 0XD6F, 0XD70, 0XD71, 0XD72, 0XD73, 0XD74, 0XD75,
- 0XD76, 0XD77, 0XD78, 0XDE6, 0XDE7, 0XDE8, 0XDE9, 0XDEA,
- 0XDEB, 0XDEC, 0XDED, 0XDEE, 0XDEF, 0XE50, 0XE51, 0XE52,
- 0XE53, 0XE54, 0XE55, 0XE56, 0XE57, 0XE58, 0XE59, 0XED0,
- 0XED1, 0XED2, 0XED3, 0XED4, 0XED5, 0XED6, 0XED7, 0XED8,
- 0XED9, 0XF20, 0XF21, 0XF22, 0XF23, 0XF24, 0XF25, 0XF26,
- 0XF27, 0XF28, 0XF29, 0XF2A, 0XF2B, 0XF2C, 0XF2D, 0XF2E,
- 0XF2F, 0XF30, 0XF31, 0XF32, 0XF33, 0X1040, 0X1041, 0X1042,
- 0X1043, 0X1044, 0X1045, 0X1046, 0X1047, 0X1048, 0X1049,
- 0X1090, 0X1091, 0X1092, 0X1093, 0X1094, 0X1095, 0X1096,
- 0X1097, 0X1098, 0X1099, 0X1369, 0X136A, 0X136B, 0X136C,
- 0X136D, 0X136E, 0X136F, 0X1370, 0X1371, 0X1372, 0X1373,
- 0X1374, 0X1375, 0X1376, 0X1377, 0X1378, 0X1379, 0X137A,
- 0X137B, 0X137C, 0X16EE, 0X16EF, 0X16F0, 0X17E0, 0X17E1,
- 0X17E2, 0X17E3, 0X17E4, 0X17E5, 0X17E6, 0X17E7, 0X17E8,
- 0X17E9, 0X17F0, 0X17F1, 0X17F2, 0X17F3, 0X17F4, 0X17F5,
- 0X17F6, 0X17F7, 0X17F8, 0X17F9, 0X1810, 0X1811, 0X1812,
- 0X1813, 0X1814, 0X1815, 0X1816, 0X1817, 0X1818, 0X1819,
- 0X1946, 0X1947, 0X1948, 0X1949, 0X194A, 0X194B, 0X194C,
- 0X194D, 0X194E, 0X194F, 0X19D0, 0X19D1, 0X19D2, 0X19D3,
- 0X19D4, 0X19D5, 0X19D6, 0X19D7, 0X19D8, 0X19D9, 0X19DA,
- 0X1A80, 0X1A81, 0X1A82, 0X1A83, 0X1A84, 0X1A85, 0X1A86,
- 0X1A87, 0X1A88, 0X1A89, 0X1A90, 0X1A91, 0X1A92, 0X1A93,
- 0X1A94, 0X1A95, 0X1A96, 0X1A97, 0X1A98, 0X1A99, 0X1B50,
- 0X1B51, 0X1B52, 0X1B53, 0X1B54, 0X1B55, 0X1B56, 0X1B57,
- 0X1B58, 0X1B59, 0X1BB0, 0X1BB1, 0X1BB2, 0X1BB3, 0X1BB4,
- 0X1BB5, 0X1BB6, 0X1BB7, 0X1BB8, 0X1BB9, 0X1C40, 0X1C41,
- 0X1C42, 0X1C43, 0X1C44, 0X1C45, 0X1C46, 0X1C47, 0X1C48,
- 0X1C49, 0X1C50, 0X1C51, 0X1C52, 0X1C53, 0X1C54, 0X1C55,
- 0X1C56, 0X1C57, 0X1C58, 0X1C59, 0X2070, 0X2074, 0X2075,
- 0X2076, 0X2077, 0X2078, 0X2079, 0X2080, 0X2081, 0X2082,
- 0X2083, 0X2084, 0X2085, 0X2086, 0X2087, 0X2088, 0X2089,
- 0X2150, 0X2151, 0X2152, 0X2153, 0X2154, 0X2155, 0X2156,
- 0X2157, 0X2158, 0X2159, 0X215A, 0X215B, 0X215C, 0X215D,
- 0X215E, 0X215F, 0X2160, 0X2161, 0X2162, 0X2163, 0X2164,
- 0X2165, 0X2166, 0X2167, 0X2168, 0X2169, 0X216A, 0X216B,
- 0X216C, 0X216D, 0X216E, 0X216F, 0X2170, 0X2171, 0X2172,
- 0X2173, 0X2174, 0X2175, 0X2176, 0X2177, 0X2178, 0X2179,
- 0X217A, 0X217B, 0X217C, 0X217D, 0X217E, 0X217F, 0X2180,
- 0X2181, 0X2182, 0X2185, 0X2186, 0X2187, 0X2188, 0X2189,
- 0X2460, 0X2461, 0X2462, 0X2463, 0X2464, 0X2465, 0X2466,
- 0X2467, 0X2468, 0X2469, 0X246A, 0X246B, 0X246C, 0X246D,
- 0X246E, 0X246F, 0X2470, 0X2471, 0X2472, 0X2473, 0X2474,
- 0X2475, 0X2476, 0X2477, 0X2478, 0X2479, 0X247A, 0X247B,
- 0X247C, 0X247D, 0X247E, 0X247F, 0X2480, 0X2481, 0X2482,
- 0X2483, 0X2484, 0X2485, 0X2486, 0X2487, 0X2488, 0X2489,
- 0X248A, 0X248B, 0X248C, 0X248D, 0X248E, 0X248F, 0X2490,
- 0X2491, 0X2492, 0X2493, 0X2494, 0X2495, 0X2496, 0X2497,
- 0X2498, 0X2499, 0X249A, 0X249B, 0X24EA, 0X24EB, 0X24EC,
- 0X24ED, 0X24EE, 0X24EF, 0X24F0, 0X24F1, 0X24F2, 0X24F3,
- 0X24F4, 0X24F5, 0X24F6, 0X24F7, 0X24F8, 0X24F9, 0X24FA,
- 0X24FB, 0X24FC, 0X24FD, 0X24FE, 0X24FF, 0X2776, 0X2777,
- 0X2778, 0X2779, 0X277A, 0X277B, 0X277C, 0X277D, 0X277E,
- 0X277F, 0X2780, 0X2781, 0X2782, 0X2783, 0X2784, 0X2785,
- 0X2786, 0X2787, 0X2788, 0X2789, 0X278A, 0X278B, 0X278C,
- 0X278D, 0X278E, 0X278F, 0X2790, 0X2791, 0X2792, 0X2793,
- 0X2CFD, 0X3007, 0X3021, 0X3022, 0X3023, 0X3024, 0X3025,
- 0X3026, 0X3027, 0X3028, 0X3029, 0X3038, 0X3039, 0X303A,
- 0X3192, 0X3193, 0X3194, 0X3195, 0X3220, 0X3221, 0X3222,
- 0X3223, 0X3224, 0X3225, 0X3226, 0X3227, 0X3228, 0X3229,
- 0X3248, 0X3249, 0X324A, 0X324B, 0X324C, 0X324D, 0X324E,
- 0X324F, 0X3251, 0X3252, 0X3253, 0X3254, 0X3255, 0X3256,
- 0X3257, 0X3258, 0X3259, 0X325A, 0X325B, 0X325C, 0X325D,
- 0X325E, 0X325F, 0X3280, 0X3281, 0X3282, 0X3283, 0X3284,
- 0X3285, 0X3286, 0X3287, 0X3288, 0X3289, 0X32B1, 0X32B2,
- 0X32B3, 0X32B4, 0X32B5, 0X32B6, 0X32B7, 0X32B8, 0X32B9,
- 0X32BA, 0X32BB, 0X32BC, 0X32BD, 0X32BE, 0X32BF, 0X3405,
- 0X3483, 0X382A, 0X3B4D, 0X4E00, 0X4E03, 0X4E07, 0X4E09,
- 0X4E5D, 0X4E8C, 0X4E94, 0X4E96, 0X4EBF, 0X4EC0, 0X4EDF,
- 0X4EE8, 0X4F0D, 0X4F70, 0X5104, 0X5146, 0X5169, 0X516B,
- 0X516D, 0X5341, 0X5343, 0X5344, 0X5345, 0X534C, 0X53C1,
- 0X53C2, 0X53C3, 0X53C4, 0X56DB, 0X58F1, 0X58F9, 0X5E7A,
- 0X5EFE, 0X5EFF, 0X5F0C, 0X5F0D, 0X5F0E, 0X5F10, 0X62FE,
- 0X634C, 0X67D2, 0X6F06, 0X7396, 0X767E, 0X8086, 0X842C,
- 0X8CAE, 0X8CB3, 0X8D30, 0X9621, 0X9646, 0X964C, 0X9678,
- 0X96F6, 0XA620, 0XA621, 0XA622, 0XA623, 0XA624, 0XA625,
- 0XA626, 0XA627, 0XA628, 0XA629, 0XA6E6, 0XA6E7, 0XA6E8,
- 0XA6E9, 0XA6EA, 0XA6EB, 0XA6EC, 0XA6ED, 0XA6EE, 0XA6EF,
- 0XA830, 0XA831, 0XA832, 0XA833, 0XA834, 0XA835, 0XA8D0,
- 0XA8D1, 0XA8D2, 0XA8D3, 0XA8D4, 0XA8D5, 0XA8D6, 0XA8D7,
- 0XA8D8, 0XA8D9, 0XA900, 0XA901, 0XA902, 0XA903, 0XA904,
- 0XA905, 0XA906, 0XA907, 0XA908, 0XA909, 0XA9D0, 0XA9D1,
- 0XA9D2, 0XA9D3, 0XA9D4, 0XA9D5, 0XA9D6, 0XA9D7, 0XA9D8,
- 0XA9D9, 0XA9F0, 0XA9F1, 0XA9F2, 0XA9F3, 0XA9F4, 0XA9F5,
- 0XA9F6, 0XA9F7, 0XA9F8, 0XA9F9, 0XAA50, 0XAA51, 0XAA52,
- 0XAA53, 0XAA54, 0XAA55, 0XAA56, 0XAA57, 0XAA58, 0XAA59,
- 0XABF0, 0XABF1, 0XABF2, 0XABF3, 0XABF4, 0XABF5, 0XABF6,
- 0XABF7, 0XABF8, 0XABF9, 0XF96B, 0XF973, 0XF978, 0XF9B2,
- 0XF9D1, 0XF9D3, 0XF9FD, 0XFF10, 0XFF11, 0XFF12, 0XFF13,
- 0XFF14, 0XFF15, 0XFF16, 0XFF17, 0XFF18, 0XFF19, 0X10107,
- 0X10108, 0X10109, 0X1010A, 0X1010B, 0X1010C, 0X1010D,
- 0X1010E, 0X1010F, 0X10110, 0X10111, 0X10112, 0X10113,
- 0X10114, 0X10115, 0X10116, 0X10117, 0X10118, 0X10119,
- 0X1011A, 0X1011B, 0X1011C, 0X1011D, 0X1011E, 0X1011F,
- 0X10120, 0X10121, 0X10122, 0X10123, 0X10124, 0X10125,
- 0X10126, 0X10127, 0X10128, 0X10129, 0X1012A, 0X1012B,
- 0X1012C, 0X1012D, 0X1012E, 0X1012F, 0X10130, 0X10131,
- 0X10132, 0X10133, 0X10140, 0X10141, 0X10142, 0X10143,
- 0X10144, 0X10145, 0X10146, 0X10147, 0X10148, 0X10149,
- 0X1014A, 0X1014B, 0X1014C, 0X1014D, 0X1014E, 0X1014F,
- 0X10150, 0X10151, 0X10152, 0X10153, 0X10154, 0X10155,
- 0X10156, 0X10157, 0X10158, 0X10159, 0X1015A, 0X1015B,
- 0X1015C, 0X1015D, 0X1015E, 0X1015F, 0X10160, 0X10161,
- 0X10162, 0X10163, 0X10164, 0X10165, 0X10166, 0X10167,
- 0X10168, 0X10169, 0X1016A, 0X1016B, 0X1016C, 0X1016D,
- 0X1016E, 0X1016F, 0X10170, 0X10171, 0X10172, 0X10173,
- 0X10174, 0X10175, 0X10176, 0X10177, 0X10178, 0X1018A,
- 0X1018B, 0X102E1, 0X102E2, 0X102E3, 0X102E4, 0X102E5,
- 0X102E6, 0X102E7, 0X102E8, 0X102E9, 0X102EA, 0X102EB,
- 0X102EC, 0X102ED, 0X102EE, 0X102EF, 0X102F0, 0X102F1,
- 0X102F2, 0X102F3, 0X102F4, 0X102F5, 0X102F6, 0X102F7,
- 0X102F8, 0X102F9, 0X102FA, 0X102FB, 0X10320, 0X10321,
- 0X10322, 0X10323, 0X10341, 0X1034A, 0X103D1, 0X103D2,
- 0X103D3, 0X103D4, 0X103D5, 0X104A0, 0X104A1, 0X104A2,
- 0X104A3, 0X104A4, 0X104A5, 0X104A6, 0X104A7, 0X104A8,
- 0X104A9, 0X10858, 0X10859, 0X1085A, 0X1085B, 0X1085C,
- 0X1085D, 0X1085E, 0X1085F, 0X10879, 0X1087A, 0X1087B,
- 0X1087C, 0X1087D, 0X1087E, 0X1087F, 0X108A7, 0X108A8,
- 0X108A9, 0X108AA, 0X108AB, 0X108AC, 0X108AD, 0X108AE,
- 0X108AF, 0X108FB, 0X108FC, 0X108FD, 0X108FE, 0X108FF,
- 0X10916, 0X10917, 0X10918, 0X10919, 0X1091A, 0X1091B,
- 0X109BC, 0X109BD, 0X109C0, 0X109C1, 0X109C2, 0X109C3,
- 0X109C4, 0X109C5, 0X109C6, 0X109C7, 0X109C8, 0X109C9,
- 0X109CA, 0X109CB, 0X109CC, 0X109CD, 0X109CE, 0X109CF,
- 0X109D2, 0X109D3, 0X109D4, 0X109D5, 0X109D6, 0X109D7,
- 0X109D8, 0X109D9, 0X109DA, 0X109DB, 0X109DC, 0X109DD,
- 0X109DE, 0X109DF, 0X109E0, 0X109E1, 0X109E2, 0X109E3,
- 0X109E4, 0X109E5, 0X109E6, 0X109E7, 0X109E8, 0X109E9,
- 0X109EA, 0X109EB, 0X109EC, 0X109ED, 0X109EE, 0X109EF,
- 0X109F0, 0X109F1, 0X109F2, 0X109F3, 0X109F4, 0X109F5,
- 0X109F6, 0X109F7, 0X109F8, 0X109F9, 0X109FA, 0X109FB,
- 0X109FC, 0X109FD, 0X109FE, 0X109FF, 0X10A40, 0X10A41,
- 0X10A42, 0X10A43, 0X10A44, 0X10A45, 0X10A46, 0X10A47,
- 0X10A48, 0X10A7D, 0X10A7E, 0X10A9D, 0X10A9E, 0X10A9F,
- 0X10AEB, 0X10AEC, 0X10AED, 0X10AEE, 0X10AEF, 0X10B58,
- 0X10B59, 0X10B5A, 0X10B5B, 0X10B5C, 0X10B5D, 0X10B5E,
- 0X10B5F, 0X10B78, 0X10B79, 0X10B7A, 0X10B7B, 0X10B7C,
- 0X10B7D, 0X10B7E, 0X10B7F, 0X10BA9, 0X10BAA, 0X10BAB,
- 0X10BAC, 0X10BAD, 0X10BAE, 0X10BAF, 0X10CFA, 0X10CFB,
- 0X10CFC, 0X10CFD, 0X10CFE, 0X10CFF, 0X10D30, 0X10D31,
- 0X10D32, 0X10D33, 0X10D34, 0X10D35, 0X10D36, 0X10D37,
- 0X10D38, 0X10D39, 0X10E60, 0X10E61, 0X10E62, 0X10E63,
- 0X10E64, 0X10E65, 0X10E66, 0X10E67, 0X10E68, 0X10E69,
- 0X10E6A, 0X10E6B, 0X10E6C, 0X10E6D, 0X10E6E, 0X10E6F,
- 0X10E70, 0X10E71, 0X10E72, 0X10E73, 0X10E74, 0X10E75,
- 0X10E76, 0X10E77, 0X10E78, 0X10E79, 0X10E7A, 0X10E7B,
- 0X10E7C, 0X10E7D, 0X10E7E, 0X10F1D, 0X10F1E, 0X10F1F,
- 0X10F20, 0X10F21, 0X10F22, 0X10F23, 0X10F24, 0X10F25,
- 0X10F26, 0X10F51, 0X10F52, 0X10F53, 0X10F54, 0X11052,
- 0X11053, 0X11054, 0X11055, 0X11056, 0X11057, 0X11058,
- 0X11059, 0X1105A, 0X1105B, 0X1105C, 0X1105D, 0X1105E,
- 0X1105F, 0X11060, 0X11061, 0X11062, 0X11063, 0X11064,
- 0X11065, 0X11066, 0X11067, 0X11068, 0X11069, 0X1106A,
- 0X1106B, 0X1106C, 0X1106D, 0X1106E, 0X1106F, 0X110F0,
- 0X110F1, 0X110F2, 0X110F3, 0X110F4, 0X110F5, 0X110F6,
- 0X110F7, 0X110F8, 0X110F9, 0X11136, 0X11137, 0X11138,
- 0X11139, 0X1113A, 0X1113B, 0X1113C, 0X1113D, 0X1113E,
- 0X1113F, 0X111D0, 0X111D1, 0X111D2, 0X111D3, 0X111D4,
- 0X111D5, 0X111D6, 0X111D7, 0X111D8, 0X111D9, 0X111E1,
- 0X111E2, 0X111E3, 0X111E4, 0X111E5, 0X111E6, 0X111E7,
- 0X111E8, 0X111E9, 0X111EA, 0X111EB, 0X111EC, 0X111ED,
- 0X111EE, 0X111EF, 0X111F0, 0X111F1, 0X111F2, 0X111F3,
- 0X111F4, 0X112F0, 0X112F1, 0X112F2, 0X112F3, 0X112F4,
- 0X112F5, 0X112F6, 0X112F7, 0X112F8, 0X112F9, 0X11450,
- 0X11451, 0X11452, 0X11453, 0X11454, 0X11455, 0X11456,
- 0X11457, 0X11458, 0X11459, 0X114D0, 0X114D1, 0X114D2,
- 0X114D3, 0X114D4, 0X114D5, 0X114D6, 0X114D7, 0X114D8,
- 0X114D9, 0X11650, 0X11651, 0X11652, 0X11653, 0X11654,
- 0X11655, 0X11656, 0X11657, 0X11658, 0X11659, 0X116C0,
- 0X116C1, 0X116C2, 0X116C3, 0X116C4, 0X116C5, 0X116C6,
- 0X116C7, 0X116C8, 0X116C9, 0X11730, 0X11731, 0X11732,
- 0X11733, 0X11734, 0X11735, 0X11736, 0X11737, 0X11738,
- 0X11739, 0X1173A, 0X1173B, 0X118E0, 0X118E1, 0X118E2,
- 0X118E3, 0X118E4, 0X118E5, 0X118E6, 0X118E7, 0X118E8,
- 0X118E9, 0X118EA, 0X118EB, 0X118EC, 0X118ED, 0X118EE,
- 0X118EF, 0X118F0, 0X118F1, 0X118F2, 0X11C50, 0X11C51,
- 0X11C52, 0X11C53, 0X11C54, 0X11C55, 0X11C56, 0X11C57,
- 0X11C58, 0X11C59, 0X11C5A, 0X11C5B, 0X11C5C, 0X11C5D,
- 0X11C5E, 0X11C5F, 0X11C60, 0X11C61, 0X11C62, 0X11C63,
- 0X11C64, 0X11C65, 0X11C66, 0X11C67, 0X11C68, 0X11C69,
- 0X11C6A, 0X11C6B, 0X11C6C, 0X11D50, 0X11D51, 0X11D52,
- 0X11D53, 0X11D54, 0X11D55, 0X11D56, 0X11D57, 0X11D58,
- 0X11D59, 0X11DA0, 0X11DA1, 0X11DA2, 0X11DA3, 0X11DA4,
- 0X11DA5, 0X11DA6, 0X11DA7, 0X11DA8, 0X11DA9, 0X12400,
- 0X12401, 0X12402, 0X12403, 0X12404, 0X12405, 0X12406,
- 0X12407, 0X12408, 0X12409, 0X1240A, 0X1240B, 0X1240C,
- 0X1240D, 0X1240E, 0X1240F, 0X12410, 0X12411, 0X12412,
- 0X12413, 0X12414, 0X12415, 0X12416, 0X12417, 0X12418,
- 0X12419, 0X1241A, 0X1241B, 0X1241C, 0X1241D, 0X1241E,
- 0X1241F, 0X12420, 0X12421, 0X12422, 0X12423, 0X12424,
- 0X12425, 0X12426, 0X12427, 0X12428, 0X12429, 0X1242A,
- 0X1242B, 0X1242C, 0X1242D, 0X1242E, 0X1242F, 0X12430,
- 0X12431, 0X12432, 0X12433, 0X12434, 0X12435, 0X12436,
- 0X12437, 0X12438, 0X12439, 0X1243A, 0X1243B, 0X1243C,
- 0X1243D, 0X1243E, 0X1243F, 0X12440, 0X12441, 0X12442,
- 0X12443, 0X12444, 0X12445, 0X12446, 0X12447, 0X12448,
- 0X12449, 0X1244A, 0X1244B, 0X1244C, 0X1244D, 0X1244E,
- 0X1244F, 0X12450, 0X12451, 0X12452, 0X12453, 0X12454,
- 0X12455, 0X12456, 0X12457, 0X12458, 0X12459, 0X1245A,
- 0X1245B, 0X1245C, 0X1245D, 0X1245E, 0X1245F, 0X12460,
- 0X12461, 0X12462, 0X12463, 0X12464, 0X12465, 0X12466,
- 0X12467, 0X12468, 0X12469, 0X1246A, 0X1246B, 0X1246C,
- 0X1246D, 0X1246E, 0X16A60, 0X16A61, 0X16A62, 0X16A63,
- 0X16A64, 0X16A65, 0X16A66, 0X16A67, 0X16A68, 0X16A69,
- 0X16B50, 0X16B51, 0X16B52, 0X16B53, 0X16B54, 0X16B55,
- 0X16B56, 0X16B57, 0X16B58, 0X16B59, 0X16B5B, 0X16B5C,
- 0X16B5D, 0X16B5E, 0X16B5F, 0X16B60, 0X16B61, 0X16E80,
- 0X16E81, 0X16E82, 0X16E83, 0X16E84, 0X16E85, 0X16E86,
- 0X16E87, 0X16E88, 0X16E89, 0X16E8A, 0X16E8B, 0X16E8C,
- 0X16E8D, 0X16E8E, 0X16E8F, 0X16E90, 0X16E91, 0X16E92,
- 0X16E93, 0X16E94, 0X16E95, 0X16E96, 0X1D2E0, 0X1D2E1,
- 0X1D2E2, 0X1D2E3, 0X1D2E4, 0X1D2E5, 0X1D2E6, 0X1D2E7,
- 0X1D2E8, 0X1D2E9, 0X1D2EA, 0X1D2EB, 0X1D2EC, 0X1D2ED,
- 0X1D2EE, 0X1D2EF, 0X1D2F0, 0X1D2F1, 0X1D2F2, 0X1D2F3,
- 0X1D360, 0X1D361, 0X1D362, 0X1D363, 0X1D364, 0X1D365,
- 0X1D366, 0X1D367, 0X1D368, 0X1D369, 0X1D36A, 0X1D36B,
- 0X1D36C, 0X1D36D, 0X1D36E, 0X1D36F, 0X1D370, 0X1D371,
- 0X1D372, 0X1D373, 0X1D374, 0X1D375, 0X1D376, 0X1D377,
- 0X1D378, 0X1D7CE, 0X1D7CF, 0X1D7D0, 0X1D7D1, 0X1D7D2,
- 0X1D7D3, 0X1D7D4, 0X1D7D5, 0X1D7D6, 0X1D7D7, 0X1D7D8,
- 0X1D7D9, 0X1D7DA, 0X1D7DB, 0X1D7DC, 0X1D7DD, 0X1D7DE,
- 0X1D7DF, 0X1D7E0, 0X1D7E1, 0X1D7E2, 0X1D7E3, 0X1D7E4,
- 0X1D7E5, 0X1D7E6, 0X1D7E7, 0X1D7E8, 0X1D7E9, 0X1D7EA,
- 0X1D7EB, 0X1D7EC, 0X1D7ED, 0X1D7EE, 0X1D7EF, 0X1D7F0,
- 0X1D7F1, 0X1D7F2, 0X1D7F3, 0X1D7F4, 0X1D7F5, 0X1D7F6,
- 0X1D7F7, 0X1D7F8, 0X1D7F9, 0X1D7FA, 0X1D7FB, 0X1D7FC,
- 0X1D7FD, 0X1D7FE, 0X1D7FF, 0X1E8C7, 0X1E8C8, 0X1E8C9,
- 0X1E8CA, 0X1E8CB, 0X1E8CC, 0X1E8CD, 0X1E8CE, 0X1E8CF,
- 0X1E950, 0X1E951, 0X1E952, 0X1E953, 0X1E954, 0X1E955,
- 0X1E956, 0X1E957, 0X1E958, 0X1E959, 0X1EC71, 0X1EC72,
- 0X1EC73, 0X1EC74, 0X1EC75, 0X1EC76, 0X1EC77, 0X1EC78,
- 0X1EC79, 0X1EC7A, 0X1EC7B, 0X1EC7C, 0X1EC7D, 0X1EC7E,
- 0X1EC7F, 0X1EC80, 0X1EC81, 0X1EC82, 0X1EC83, 0X1EC84,
- 0X1EC85, 0X1EC86, 0X1EC87, 0X1EC88, 0X1EC89, 0X1EC8A,
- 0X1EC8B, 0X1EC8C, 0X1EC8D, 0X1EC8E, 0X1EC8F, 0X1EC90,
- 0X1EC91, 0X1EC92, 0X1EC93, 0X1EC94, 0X1EC95, 0X1EC96,
- 0X1EC97, 0X1EC98, 0X1EC99, 0X1EC9A, 0X1EC9B, 0X1EC9C,
- 0X1EC9D, 0X1EC9E, 0X1EC9F, 0X1ECA0, 0X1ECA1, 0X1ECA2,
- 0X1ECA3, 0X1ECA4, 0X1ECA5, 0X1ECA6, 0X1ECA7, 0X1ECA8,
- 0X1ECA9, 0X1ECAA, 0X1ECAB, 0X1ECAD, 0X1ECAE, 0X1ECAF,
- 0X1ECB1, 0X1ECB2, 0X1ECB3, 0X1ECB4, 0X1F100, 0X1F101,
- 0X1F102, 0X1F103, 0X1F104, 0X1F105, 0X1F106, 0X1F107,
- 0X1F108, 0X1F109, 0X1F10A, 0X1F10B, 0X1F10C, 0X20001,
- 0X20064, 0X200E2, 0X20121, 0X2092A, 0X20983, 0X2098C,
- 0X2099C, 0X20AEA, 0X20AFD, 0X20B19, 0X22390, 0X22998,
- 0X23B1B, 0X2626D, 0X2F890,
-)
-
# Convert each hex into the literal Unicode character.
# Stop if a ValueError is raised in case of a narrow Unicode build.
# The extra check with unicodedata is in case this Python version
@@ -294,45 +18,23 @@ numeric_hex = (
numeric_chars = []
for a in numeric_hex:
try:
- l = py23_unichr(a)
+ character = py23_unichr(a)
except ValueError: # pragma: no cover
break
- if unicodedata.numeric(l, None) is None:
+ if unicodedata.numeric(character, None) is None:
continue # pragma: no cover
- numeric_chars.append(l)
+ numeric_chars.append(character)
# The digit characters are a subset of the numerals.
-digit_chars = [a for a in numeric_chars
- if unicodedata.digit(a, None) is not None]
+digit_chars = [a for a in numeric_chars if unicodedata.digit(a, None) is not None]
# The decimal characters are a subset of the numberals
# (probably of the digits, but let's be safe).
-decimal_chars = [a for a in numeric_chars
- if unicodedata.decimal(a, None) is not None]
+decimal_chars = [a for a in numeric_chars if unicodedata.decimal(a, None) is not None]
# Create a single string with the above data.
-decimals = ''.join(decimal_chars)
-digits = ''.join(digit_chars)
-numeric = ''.join(numeric_chars)
-digits_no_decimals = ''.join([x for x in digits if x not in decimals])
-numeric_no_decimals = ''.join([x for x in numeric if x not in decimals])
-
-# Some code that can be used to create the above list of hex numbers.
-if __name__ == '__main__':
- import textwrap
- from natsort.compat.py23 import py23_range
-
- hex_chars = []
- for i in py23_range(0X110000):
- try:
- a = py23_unichr(i)
- except ValueError:
- break
- if a in set('0123456789'):
- continue
- if unicodedata.numeric(a, None) is not None:
- hex_chars.append(i)
-
- hex_string = ', '.join(['0X{:X}'.format(i) for i in hex_chars])
- for line in textwrap.wrap(hex_string, width=60):
- print(' ', line)
+decimals = "".join(decimal_chars)
+digits = "".join(digit_chars)
+numeric = "".join(numeric_chars)
+digits_no_decimals = "".join([x for x in digits if x not in decimals])
+numeric_no_decimals = "".join([x for x in numeric if x not in decimals])
diff --git a/natsort/unicode_numeric_hex.py b/natsort/unicode_numeric_hex.py
new file mode 100644
index 0000000..0a74144
--- /dev/null
+++ b/natsort/unicode_numeric_hex.py
@@ -0,0 +1,1750 @@
+# -*- coding: utf-8 -*-
+"""
+Rather than determine what unicode characters are numeric on the fly which
+would incur a startup runtime penalty, the hex values are hard-coded below.
+"""
+
+numeric_hex = (
+ 0XB2,
+ 0XB3,
+ 0XB9,
+ 0XBC,
+ 0XBD,
+ 0XBE,
+ 0X660,
+ 0X661,
+ 0X662,
+ 0X663,
+ 0X664,
+ 0X665,
+ 0X666,
+ 0X667,
+ 0X668,
+ 0X669,
+ 0X6F0,
+ 0X6F1,
+ 0X6F2,
+ 0X6F3,
+ 0X6F4,
+ 0X6F5,
+ 0X6F6,
+ 0X6F7,
+ 0X6F8,
+ 0X6F9,
+ 0X7C0,
+ 0X7C1,
+ 0X7C2,
+ 0X7C3,
+ 0X7C4,
+ 0X7C5,
+ 0X7C6,
+ 0X7C7,
+ 0X7C8,
+ 0X7C9,
+ 0X966,
+ 0X967,
+ 0X968,
+ 0X969,
+ 0X96A,
+ 0X96B,
+ 0X96C,
+ 0X96D,
+ 0X96E,
+ 0X96F,
+ 0X9E6,
+ 0X9E7,
+ 0X9E8,
+ 0X9E9,
+ 0X9EA,
+ 0X9EB,
+ 0X9EC,
+ 0X9ED,
+ 0X9EE,
+ 0X9EF,
+ 0X9F4,
+ 0X9F5,
+ 0X9F6,
+ 0X9F7,
+ 0X9F8,
+ 0X9F9,
+ 0XA66,
+ 0XA67,
+ 0XA68,
+ 0XA69,
+ 0XA6A,
+ 0XA6B,
+ 0XA6C,
+ 0XA6D,
+ 0XA6E,
+ 0XA6F,
+ 0XAE6,
+ 0XAE7,
+ 0XAE8,
+ 0XAE9,
+ 0XAEA,
+ 0XAEB,
+ 0XAEC,
+ 0XAED,
+ 0XAEE,
+ 0XAEF,
+ 0XB66,
+ 0XB67,
+ 0XB68,
+ 0XB69,
+ 0XB6A,
+ 0XB6B,
+ 0XB6C,
+ 0XB6D,
+ 0XB6E,
+ 0XB6F,
+ 0XB72,
+ 0XB73,
+ 0XB74,
+ 0XB75,
+ 0XB76,
+ 0XB77,
+ 0XBE6,
+ 0XBE7,
+ 0XBE8,
+ 0XBE9,
+ 0XBEA,
+ 0XBEB,
+ 0XBEC,
+ 0XBED,
+ 0XBEE,
+ 0XBEF,
+ 0XBF0,
+ 0XBF1,
+ 0XBF2,
+ 0XC66,
+ 0XC67,
+ 0XC68,
+ 0XC69,
+ 0XC6A,
+ 0XC6B,
+ 0XC6C,
+ 0XC6D,
+ 0XC6E,
+ 0XC6F,
+ 0XC78,
+ 0XC79,
+ 0XC7A,
+ 0XC7B,
+ 0XC7C,
+ 0XC7D,
+ 0XC7E,
+ 0XCE6,
+ 0XCE7,
+ 0XCE8,
+ 0XCE9,
+ 0XCEA,
+ 0XCEB,
+ 0XCEC,
+ 0XCED,
+ 0XCEE,
+ 0XCEF,
+ 0XD58,
+ 0XD59,
+ 0XD5A,
+ 0XD5B,
+ 0XD5C,
+ 0XD5D,
+ 0XD5E,
+ 0XD66,
+ 0XD67,
+ 0XD68,
+ 0XD69,
+ 0XD6A,
+ 0XD6B,
+ 0XD6C,
+ 0XD6D,
+ 0XD6E,
+ 0XD6F,
+ 0XD70,
+ 0XD71,
+ 0XD72,
+ 0XD73,
+ 0XD74,
+ 0XD75,
+ 0XD76,
+ 0XD77,
+ 0XD78,
+ 0XDE6,
+ 0XDE7,
+ 0XDE8,
+ 0XDE9,
+ 0XDEA,
+ 0XDEB,
+ 0XDEC,
+ 0XDED,
+ 0XDEE,
+ 0XDEF,
+ 0XE50,
+ 0XE51,
+ 0XE52,
+ 0XE53,
+ 0XE54,
+ 0XE55,
+ 0XE56,
+ 0XE57,
+ 0XE58,
+ 0XE59,
+ 0XED0,
+ 0XED1,
+ 0XED2,
+ 0XED3,
+ 0XED4,
+ 0XED5,
+ 0XED6,
+ 0XED7,
+ 0XED8,
+ 0XED9,
+ 0XF20,
+ 0XF21,
+ 0XF22,
+ 0XF23,
+ 0XF24,
+ 0XF25,
+ 0XF26,
+ 0XF27,
+ 0XF28,
+ 0XF29,
+ 0XF2A,
+ 0XF2B,
+ 0XF2C,
+ 0XF2D,
+ 0XF2E,
+ 0XF2F,
+ 0XF30,
+ 0XF31,
+ 0XF32,
+ 0XF33,
+ 0X1040,
+ 0X1041,
+ 0X1042,
+ 0X1043,
+ 0X1044,
+ 0X1045,
+ 0X1046,
+ 0X1047,
+ 0X1048,
+ 0X1049,
+ 0X1090,
+ 0X1091,
+ 0X1092,
+ 0X1093,
+ 0X1094,
+ 0X1095,
+ 0X1096,
+ 0X1097,
+ 0X1098,
+ 0X1099,
+ 0X1369,
+ 0X136A,
+ 0X136B,
+ 0X136C,
+ 0X136D,
+ 0X136E,
+ 0X136F,
+ 0X1370,
+ 0X1371,
+ 0X1372,
+ 0X1373,
+ 0X1374,
+ 0X1375,
+ 0X1376,
+ 0X1377,
+ 0X1378,
+ 0X1379,
+ 0X137A,
+ 0X137B,
+ 0X137C,
+ 0X16EE,
+ 0X16EF,
+ 0X16F0,
+ 0X17E0,
+ 0X17E1,
+ 0X17E2,
+ 0X17E3,
+ 0X17E4,
+ 0X17E5,
+ 0X17E6,
+ 0X17E7,
+ 0X17E8,
+ 0X17E9,
+ 0X17F0,
+ 0X17F1,
+ 0X17F2,
+ 0X17F3,
+ 0X17F4,
+ 0X17F5,
+ 0X17F6,
+ 0X17F7,
+ 0X17F8,
+ 0X17F9,
+ 0X1810,
+ 0X1811,
+ 0X1812,
+ 0X1813,
+ 0X1814,
+ 0X1815,
+ 0X1816,
+ 0X1817,
+ 0X1818,
+ 0X1819,
+ 0X1946,
+ 0X1947,
+ 0X1948,
+ 0X1949,
+ 0X194A,
+ 0X194B,
+ 0X194C,
+ 0X194D,
+ 0X194E,
+ 0X194F,
+ 0X19D0,
+ 0X19D1,
+ 0X19D2,
+ 0X19D3,
+ 0X19D4,
+ 0X19D5,
+ 0X19D6,
+ 0X19D7,
+ 0X19D8,
+ 0X19D9,
+ 0X19DA,
+ 0X1A80,
+ 0X1A81,
+ 0X1A82,
+ 0X1A83,
+ 0X1A84,
+ 0X1A85,
+ 0X1A86,
+ 0X1A87,
+ 0X1A88,
+ 0X1A89,
+ 0X1A90,
+ 0X1A91,
+ 0X1A92,
+ 0X1A93,
+ 0X1A94,
+ 0X1A95,
+ 0X1A96,
+ 0X1A97,
+ 0X1A98,
+ 0X1A99,
+ 0X1B50,
+ 0X1B51,
+ 0X1B52,
+ 0X1B53,
+ 0X1B54,
+ 0X1B55,
+ 0X1B56,
+ 0X1B57,
+ 0X1B58,
+ 0X1B59,
+ 0X1BB0,
+ 0X1BB1,
+ 0X1BB2,
+ 0X1BB3,
+ 0X1BB4,
+ 0X1BB5,
+ 0X1BB6,
+ 0X1BB7,
+ 0X1BB8,
+ 0X1BB9,
+ 0X1C40,
+ 0X1C41,
+ 0X1C42,
+ 0X1C43,
+ 0X1C44,
+ 0X1C45,
+ 0X1C46,
+ 0X1C47,
+ 0X1C48,
+ 0X1C49,
+ 0X1C50,
+ 0X1C51,
+ 0X1C52,
+ 0X1C53,
+ 0X1C54,
+ 0X1C55,
+ 0X1C56,
+ 0X1C57,
+ 0X1C58,
+ 0X1C59,
+ 0X2070,
+ 0X2074,
+ 0X2075,
+ 0X2076,
+ 0X2077,
+ 0X2078,
+ 0X2079,
+ 0X2080,
+ 0X2081,
+ 0X2082,
+ 0X2083,
+ 0X2084,
+ 0X2085,
+ 0X2086,
+ 0X2087,
+ 0X2088,
+ 0X2089,
+ 0X2150,
+ 0X2151,
+ 0X2152,
+ 0X2153,
+ 0X2154,
+ 0X2155,
+ 0X2156,
+ 0X2157,
+ 0X2158,
+ 0X2159,
+ 0X215A,
+ 0X215B,
+ 0X215C,
+ 0X215D,
+ 0X215E,
+ 0X215F,
+ 0X2160,
+ 0X2161,
+ 0X2162,
+ 0X2163,
+ 0X2164,
+ 0X2165,
+ 0X2166,
+ 0X2167,
+ 0X2168,
+ 0X2169,
+ 0X216A,
+ 0X216B,
+ 0X216C,
+ 0X216D,
+ 0X216E,
+ 0X216F,
+ 0X2170,
+ 0X2171,
+ 0X2172,
+ 0X2173,
+ 0X2174,
+ 0X2175,
+ 0X2176,
+ 0X2177,
+ 0X2178,
+ 0X2179,
+ 0X217A,
+ 0X217B,
+ 0X217C,
+ 0X217D,
+ 0X217E,
+ 0X217F,
+ 0X2180,
+ 0X2181,
+ 0X2182,
+ 0X2185,
+ 0X2186,
+ 0X2187,
+ 0X2188,
+ 0X2189,
+ 0X2460,
+ 0X2461,
+ 0X2462,
+ 0X2463,
+ 0X2464,
+ 0X2465,
+ 0X2466,
+ 0X2467,
+ 0X2468,
+ 0X2469,
+ 0X246A,
+ 0X246B,
+ 0X246C,
+ 0X246D,
+ 0X246E,
+ 0X246F,
+ 0X2470,
+ 0X2471,
+ 0X2472,
+ 0X2473,
+ 0X2474,
+ 0X2475,
+ 0X2476,
+ 0X2477,
+ 0X2478,
+ 0X2479,
+ 0X247A,
+ 0X247B,
+ 0X247C,
+ 0X247D,
+ 0X247E,
+ 0X247F,
+ 0X2480,
+ 0X2481,
+ 0X2482,
+ 0X2483,
+ 0X2484,
+ 0X2485,
+ 0X2486,
+ 0X2487,
+ 0X2488,
+ 0X2489,
+ 0X248A,
+ 0X248B,
+ 0X248C,
+ 0X248D,
+ 0X248E,
+ 0X248F,
+ 0X2490,
+ 0X2491,
+ 0X2492,
+ 0X2493,
+ 0X2494,
+ 0X2495,
+ 0X2496,
+ 0X2497,
+ 0X2498,
+ 0X2499,
+ 0X249A,
+ 0X249B,
+ 0X24EA,
+ 0X24EB,
+ 0X24EC,
+ 0X24ED,
+ 0X24EE,
+ 0X24EF,
+ 0X24F0,
+ 0X24F1,
+ 0X24F2,
+ 0X24F3,
+ 0X24F4,
+ 0X24F5,
+ 0X24F6,
+ 0X24F7,
+ 0X24F8,
+ 0X24F9,
+ 0X24FA,
+ 0X24FB,
+ 0X24FC,
+ 0X24FD,
+ 0X24FE,
+ 0X24FF,
+ 0X2776,
+ 0X2777,
+ 0X2778,
+ 0X2779,
+ 0X277A,
+ 0X277B,
+ 0X277C,
+ 0X277D,
+ 0X277E,
+ 0X277F,
+ 0X2780,
+ 0X2781,
+ 0X2782,
+ 0X2783,
+ 0X2784,
+ 0X2785,
+ 0X2786,
+ 0X2787,
+ 0X2788,
+ 0X2789,
+ 0X278A,
+ 0X278B,
+ 0X278C,
+ 0X278D,
+ 0X278E,
+ 0X278F,
+ 0X2790,
+ 0X2791,
+ 0X2792,
+ 0X2793,
+ 0X2CFD,
+ 0X3007,
+ 0X3021,
+ 0X3022,
+ 0X3023,
+ 0X3024,
+ 0X3025,
+ 0X3026,
+ 0X3027,
+ 0X3028,
+ 0X3029,
+ 0X3038,
+ 0X3039,
+ 0X303A,
+ 0X3192,
+ 0X3193,
+ 0X3194,
+ 0X3195,
+ 0X3220,
+ 0X3221,
+ 0X3222,
+ 0X3223,
+ 0X3224,
+ 0X3225,
+ 0X3226,
+ 0X3227,
+ 0X3228,
+ 0X3229,
+ 0X3248,
+ 0X3249,
+ 0X324A,
+ 0X324B,
+ 0X324C,
+ 0X324D,
+ 0X324E,
+ 0X324F,
+ 0X3251,
+ 0X3252,
+ 0X3253,
+ 0X3254,
+ 0X3255,
+ 0X3256,
+ 0X3257,
+ 0X3258,
+ 0X3259,
+ 0X325A,
+ 0X325B,
+ 0X325C,
+ 0X325D,
+ 0X325E,
+ 0X325F,
+ 0X3280,
+ 0X3281,
+ 0X3282,
+ 0X3283,
+ 0X3284,
+ 0X3285,
+ 0X3286,
+ 0X3287,
+ 0X3288,
+ 0X3289,
+ 0X32B1,
+ 0X32B2,
+ 0X32B3,
+ 0X32B4,
+ 0X32B5,
+ 0X32B6,
+ 0X32B7,
+ 0X32B8,
+ 0X32B9,
+ 0X32BA,
+ 0X32BB,
+ 0X32BC,
+ 0X32BD,
+ 0X32BE,
+ 0X32BF,
+ 0X3405,
+ 0X3483,
+ 0X382A,
+ 0X3B4D,
+ 0X4E00,
+ 0X4E03,
+ 0X4E07,
+ 0X4E09,
+ 0X4E5D,
+ 0X4E8C,
+ 0X4E94,
+ 0X4E96,
+ 0X4EBF,
+ 0X4EC0,
+ 0X4EDF,
+ 0X4EE8,
+ 0X4F0D,
+ 0X4F70,
+ 0X5104,
+ 0X5146,
+ 0X5169,
+ 0X516B,
+ 0X516D,
+ 0X5341,
+ 0X5343,
+ 0X5344,
+ 0X5345,
+ 0X534C,
+ 0X53C1,
+ 0X53C2,
+ 0X53C3,
+ 0X53C4,
+ 0X56DB,
+ 0X58F1,
+ 0X58F9,
+ 0X5E7A,
+ 0X5EFE,
+ 0X5EFF,
+ 0X5F0C,
+ 0X5F0D,
+ 0X5F0E,
+ 0X5F10,
+ 0X62FE,
+ 0X634C,
+ 0X67D2,
+ 0X6F06,
+ 0X7396,
+ 0X767E,
+ 0X8086,
+ 0X842C,
+ 0X8CAE,
+ 0X8CB3,
+ 0X8D30,
+ 0X9621,
+ 0X9646,
+ 0X964C,
+ 0X9678,
+ 0X96F6,
+ 0XA620,
+ 0XA621,
+ 0XA622,
+ 0XA623,
+ 0XA624,
+ 0XA625,
+ 0XA626,
+ 0XA627,
+ 0XA628,
+ 0XA629,
+ 0XA6E6,
+ 0XA6E7,
+ 0XA6E8,
+ 0XA6E9,
+ 0XA6EA,
+ 0XA6EB,
+ 0XA6EC,
+ 0XA6ED,
+ 0XA6EE,
+ 0XA6EF,
+ 0XA830,
+ 0XA831,
+ 0XA832,
+ 0XA833,
+ 0XA834,
+ 0XA835,
+ 0XA8D0,
+ 0XA8D1,
+ 0XA8D2,
+ 0XA8D3,
+ 0XA8D4,
+ 0XA8D5,
+ 0XA8D6,
+ 0XA8D7,
+ 0XA8D8,
+ 0XA8D9,
+ 0XA900,
+ 0XA901,
+ 0XA902,
+ 0XA903,
+ 0XA904,
+ 0XA905,
+ 0XA906,
+ 0XA907,
+ 0XA908,
+ 0XA909,
+ 0XA9D0,
+ 0XA9D1,
+ 0XA9D2,
+ 0XA9D3,
+ 0XA9D4,
+ 0XA9D5,
+ 0XA9D6,
+ 0XA9D7,
+ 0XA9D8,
+ 0XA9D9,
+ 0XA9F0,
+ 0XA9F1,
+ 0XA9F2,
+ 0XA9F3,
+ 0XA9F4,
+ 0XA9F5,
+ 0XA9F6,
+ 0XA9F7,
+ 0XA9F8,
+ 0XA9F9,
+ 0XAA50,
+ 0XAA51,
+ 0XAA52,
+ 0XAA53,
+ 0XAA54,
+ 0XAA55,
+ 0XAA56,
+ 0XAA57,
+ 0XAA58,
+ 0XAA59,
+ 0XABF0,
+ 0XABF1,
+ 0XABF2,
+ 0XABF3,
+ 0XABF4,
+ 0XABF5,
+ 0XABF6,
+ 0XABF7,
+ 0XABF8,
+ 0XABF9,
+ 0XF96B,
+ 0XF973,
+ 0XF978,
+ 0XF9B2,
+ 0XF9D1,
+ 0XF9D3,
+ 0XF9FD,
+ 0XFF10,
+ 0XFF11,
+ 0XFF12,
+ 0XFF13,
+ 0XFF14,
+ 0XFF15,
+ 0XFF16,
+ 0XFF17,
+ 0XFF18,
+ 0XFF19,
+ 0X10107,
+ 0X10108,
+ 0X10109,
+ 0X1010A,
+ 0X1010B,
+ 0X1010C,
+ 0X1010D,
+ 0X1010E,
+ 0X1010F,
+ 0X10110,
+ 0X10111,
+ 0X10112,
+ 0X10113,
+ 0X10114,
+ 0X10115,
+ 0X10116,
+ 0X10117,
+ 0X10118,
+ 0X10119,
+ 0X1011A,
+ 0X1011B,
+ 0X1011C,
+ 0X1011D,
+ 0X1011E,
+ 0X1011F,
+ 0X10120,
+ 0X10121,
+ 0X10122,
+ 0X10123,
+ 0X10124,
+ 0X10125,
+ 0X10126,
+ 0X10127,
+ 0X10128,
+ 0X10129,
+ 0X1012A,
+ 0X1012B,
+ 0X1012C,
+ 0X1012D,
+ 0X1012E,
+ 0X1012F,
+ 0X10130,
+ 0X10131,
+ 0X10132,
+ 0X10133,
+ 0X10140,
+ 0X10141,
+ 0X10142,
+ 0X10143,
+ 0X10144,
+ 0X10145,
+ 0X10146,
+ 0X10147,
+ 0X10148,
+ 0X10149,
+ 0X1014A,
+ 0X1014B,
+ 0X1014C,
+ 0X1014D,
+ 0X1014E,
+ 0X1014F,
+ 0X10150,
+ 0X10151,
+ 0X10152,
+ 0X10153,
+ 0X10154,
+ 0X10155,
+ 0X10156,
+ 0X10157,
+ 0X10158,
+ 0X10159,
+ 0X1015A,
+ 0X1015B,
+ 0X1015C,
+ 0X1015D,
+ 0X1015E,
+ 0X1015F,
+ 0X10160,
+ 0X10161,
+ 0X10162,
+ 0X10163,
+ 0X10164,
+ 0X10165,
+ 0X10166,
+ 0X10167,
+ 0X10168,
+ 0X10169,
+ 0X1016A,
+ 0X1016B,
+ 0X1016C,
+ 0X1016D,
+ 0X1016E,
+ 0X1016F,
+ 0X10170,
+ 0X10171,
+ 0X10172,
+ 0X10173,
+ 0X10174,
+ 0X10175,
+ 0X10176,
+ 0X10177,
+ 0X10178,
+ 0X1018A,
+ 0X1018B,
+ 0X102E1,
+ 0X102E2,
+ 0X102E3,
+ 0X102E4,
+ 0X102E5,
+ 0X102E6,
+ 0X102E7,
+ 0X102E8,
+ 0X102E9,
+ 0X102EA,
+ 0X102EB,
+ 0X102EC,
+ 0X102ED,
+ 0X102EE,
+ 0X102EF,
+ 0X102F0,
+ 0X102F1,
+ 0X102F2,
+ 0X102F3,
+ 0X102F4,
+ 0X102F5,
+ 0X102F6,
+ 0X102F7,
+ 0X102F8,
+ 0X102F9,
+ 0X102FA,
+ 0X102FB,
+ 0X10320,
+ 0X10321,
+ 0X10322,
+ 0X10323,
+ 0X10341,
+ 0X1034A,
+ 0X103D1,
+ 0X103D2,
+ 0X103D3,
+ 0X103D4,
+ 0X103D5,
+ 0X104A0,
+ 0X104A1,
+ 0X104A2,
+ 0X104A3,
+ 0X104A4,
+ 0X104A5,
+ 0X104A6,
+ 0X104A7,
+ 0X104A8,
+ 0X104A9,
+ 0X10858,
+ 0X10859,
+ 0X1085A,
+ 0X1085B,
+ 0X1085C,
+ 0X1085D,
+ 0X1085E,
+ 0X1085F,
+ 0X10879,
+ 0X1087A,
+ 0X1087B,
+ 0X1087C,
+ 0X1087D,
+ 0X1087E,
+ 0X1087F,
+ 0X108A7,
+ 0X108A8,
+ 0X108A9,
+ 0X108AA,
+ 0X108AB,
+ 0X108AC,
+ 0X108AD,
+ 0X108AE,
+ 0X108AF,
+ 0X108FB,
+ 0X108FC,
+ 0X108FD,
+ 0X108FE,
+ 0X108FF,
+ 0X10916,
+ 0X10917,
+ 0X10918,
+ 0X10919,
+ 0X1091A,
+ 0X1091B,
+ 0X109BC,
+ 0X109BD,
+ 0X109C0,
+ 0X109C1,
+ 0X109C2,
+ 0X109C3,
+ 0X109C4,
+ 0X109C5,
+ 0X109C6,
+ 0X109C7,
+ 0X109C8,
+ 0X109C9,
+ 0X109CA,
+ 0X109CB,
+ 0X109CC,
+ 0X109CD,
+ 0X109CE,
+ 0X109CF,
+ 0X109D2,
+ 0X109D3,
+ 0X109D4,
+ 0X109D5,
+ 0X109D6,
+ 0X109D7,
+ 0X109D8,
+ 0X109D9,
+ 0X109DA,
+ 0X109DB,
+ 0X109DC,
+ 0X109DD,
+ 0X109DE,
+ 0X109DF,
+ 0X109E0,
+ 0X109E1,
+ 0X109E2,
+ 0X109E3,
+ 0X109E4,
+ 0X109E5,
+ 0X109E6,
+ 0X109E7,
+ 0X109E8,
+ 0X109E9,
+ 0X109EA,
+ 0X109EB,
+ 0X109EC,
+ 0X109ED,
+ 0X109EE,
+ 0X109EF,
+ 0X109F0,
+ 0X109F1,
+ 0X109F2,
+ 0X109F3,
+ 0X109F4,
+ 0X109F5,
+ 0X109F6,
+ 0X109F7,
+ 0X109F8,
+ 0X109F9,
+ 0X109FA,
+ 0X109FB,
+ 0X109FC,
+ 0X109FD,
+ 0X109FE,
+ 0X109FF,
+ 0X10A40,
+ 0X10A41,
+ 0X10A42,
+ 0X10A43,
+ 0X10A44,
+ 0X10A45,
+ 0X10A46,
+ 0X10A47,
+ 0X10A48,
+ 0X10A7D,
+ 0X10A7E,
+ 0X10A9D,
+ 0X10A9E,
+ 0X10A9F,
+ 0X10AEB,
+ 0X10AEC,
+ 0X10AED,
+ 0X10AEE,
+ 0X10AEF,
+ 0X10B58,
+ 0X10B59,
+ 0X10B5A,
+ 0X10B5B,
+ 0X10B5C,
+ 0X10B5D,
+ 0X10B5E,
+ 0X10B5F,
+ 0X10B78,
+ 0X10B79,
+ 0X10B7A,
+ 0X10B7B,
+ 0X10B7C,
+ 0X10B7D,
+ 0X10B7E,
+ 0X10B7F,
+ 0X10BA9,
+ 0X10BAA,
+ 0X10BAB,
+ 0X10BAC,
+ 0X10BAD,
+ 0X10BAE,
+ 0X10BAF,
+ 0X10CFA,
+ 0X10CFB,
+ 0X10CFC,
+ 0X10CFD,
+ 0X10CFE,
+ 0X10CFF,
+ 0X10D30,
+ 0X10D31,
+ 0X10D32,
+ 0X10D33,
+ 0X10D34,
+ 0X10D35,
+ 0X10D36,
+ 0X10D37,
+ 0X10D38,
+ 0X10D39,
+ 0X10E60,
+ 0X10E61,
+ 0X10E62,
+ 0X10E63,
+ 0X10E64,
+ 0X10E65,
+ 0X10E66,
+ 0X10E67,
+ 0X10E68,
+ 0X10E69,
+ 0X10E6A,
+ 0X10E6B,
+ 0X10E6C,
+ 0X10E6D,
+ 0X10E6E,
+ 0X10E6F,
+ 0X10E70,
+ 0X10E71,
+ 0X10E72,
+ 0X10E73,
+ 0X10E74,
+ 0X10E75,
+ 0X10E76,
+ 0X10E77,
+ 0X10E78,
+ 0X10E79,
+ 0X10E7A,
+ 0X10E7B,
+ 0X10E7C,
+ 0X10E7D,
+ 0X10E7E,
+ 0X10F1D,
+ 0X10F1E,
+ 0X10F1F,
+ 0X10F20,
+ 0X10F21,
+ 0X10F22,
+ 0X10F23,
+ 0X10F24,
+ 0X10F25,
+ 0X10F26,
+ 0X10F51,
+ 0X10F52,
+ 0X10F53,
+ 0X10F54,
+ 0X11052,
+ 0X11053,
+ 0X11054,
+ 0X11055,
+ 0X11056,
+ 0X11057,
+ 0X11058,
+ 0X11059,
+ 0X1105A,
+ 0X1105B,
+ 0X1105C,
+ 0X1105D,
+ 0X1105E,
+ 0X1105F,
+ 0X11060,
+ 0X11061,
+ 0X11062,
+ 0X11063,
+ 0X11064,
+ 0X11065,
+ 0X11066,
+ 0X11067,
+ 0X11068,
+ 0X11069,
+ 0X1106A,
+ 0X1106B,
+ 0X1106C,
+ 0X1106D,
+ 0X1106E,
+ 0X1106F,
+ 0X110F0,
+ 0X110F1,
+ 0X110F2,
+ 0X110F3,
+ 0X110F4,
+ 0X110F5,
+ 0X110F6,
+ 0X110F7,
+ 0X110F8,
+ 0X110F9,
+ 0X11136,
+ 0X11137,
+ 0X11138,
+ 0X11139,
+ 0X1113A,
+ 0X1113B,
+ 0X1113C,
+ 0X1113D,
+ 0X1113E,
+ 0X1113F,
+ 0X111D0,
+ 0X111D1,
+ 0X111D2,
+ 0X111D3,
+ 0X111D4,
+ 0X111D5,
+ 0X111D6,
+ 0X111D7,
+ 0X111D8,
+ 0X111D9,
+ 0X111E1,
+ 0X111E2,
+ 0X111E3,
+ 0X111E4,
+ 0X111E5,
+ 0X111E6,
+ 0X111E7,
+ 0X111E8,
+ 0X111E9,
+ 0X111EA,
+ 0X111EB,
+ 0X111EC,
+ 0X111ED,
+ 0X111EE,
+ 0X111EF,
+ 0X111F0,
+ 0X111F1,
+ 0X111F2,
+ 0X111F3,
+ 0X111F4,
+ 0X112F0,
+ 0X112F1,
+ 0X112F2,
+ 0X112F3,
+ 0X112F4,
+ 0X112F5,
+ 0X112F6,
+ 0X112F7,
+ 0X112F8,
+ 0X112F9,
+ 0X11450,
+ 0X11451,
+ 0X11452,
+ 0X11453,
+ 0X11454,
+ 0X11455,
+ 0X11456,
+ 0X11457,
+ 0X11458,
+ 0X11459,
+ 0X114D0,
+ 0X114D1,
+ 0X114D2,
+ 0X114D3,
+ 0X114D4,
+ 0X114D5,
+ 0X114D6,
+ 0X114D7,
+ 0X114D8,
+ 0X114D9,
+ 0X11650,
+ 0X11651,
+ 0X11652,
+ 0X11653,
+ 0X11654,
+ 0X11655,
+ 0X11656,
+ 0X11657,
+ 0X11658,
+ 0X11659,
+ 0X116C0,
+ 0X116C1,
+ 0X116C2,
+ 0X116C3,
+ 0X116C4,
+ 0X116C5,
+ 0X116C6,
+ 0X116C7,
+ 0X116C8,
+ 0X116C9,
+ 0X11730,
+ 0X11731,
+ 0X11732,
+ 0X11733,
+ 0X11734,
+ 0X11735,
+ 0X11736,
+ 0X11737,
+ 0X11738,
+ 0X11739,
+ 0X1173A,
+ 0X1173B,
+ 0X118E0,
+ 0X118E1,
+ 0X118E2,
+ 0X118E3,
+ 0X118E4,
+ 0X118E5,
+ 0X118E6,
+ 0X118E7,
+ 0X118E8,
+ 0X118E9,
+ 0X118EA,
+ 0X118EB,
+ 0X118EC,
+ 0X118ED,
+ 0X118EE,
+ 0X118EF,
+ 0X118F0,
+ 0X118F1,
+ 0X118F2,
+ 0X11C50,
+ 0X11C51,
+ 0X11C52,
+ 0X11C53,
+ 0X11C54,
+ 0X11C55,
+ 0X11C56,
+ 0X11C57,
+ 0X11C58,
+ 0X11C59,
+ 0X11C5A,
+ 0X11C5B,
+ 0X11C5C,
+ 0X11C5D,
+ 0X11C5E,
+ 0X11C5F,
+ 0X11C60,
+ 0X11C61,
+ 0X11C62,
+ 0X11C63,
+ 0X11C64,
+ 0X11C65,
+ 0X11C66,
+ 0X11C67,
+ 0X11C68,
+ 0X11C69,
+ 0X11C6A,
+ 0X11C6B,
+ 0X11C6C,
+ 0X11D50,
+ 0X11D51,
+ 0X11D52,
+ 0X11D53,
+ 0X11D54,
+ 0X11D55,
+ 0X11D56,
+ 0X11D57,
+ 0X11D58,
+ 0X11D59,
+ 0X11DA0,
+ 0X11DA1,
+ 0X11DA2,
+ 0X11DA3,
+ 0X11DA4,
+ 0X11DA5,
+ 0X11DA6,
+ 0X11DA7,
+ 0X11DA8,
+ 0X11DA9,
+ 0X12400,
+ 0X12401,
+ 0X12402,
+ 0X12403,
+ 0X12404,
+ 0X12405,
+ 0X12406,
+ 0X12407,
+ 0X12408,
+ 0X12409,
+ 0X1240A,
+ 0X1240B,
+ 0X1240C,
+ 0X1240D,
+ 0X1240E,
+ 0X1240F,
+ 0X12410,
+ 0X12411,
+ 0X12412,
+ 0X12413,
+ 0X12414,
+ 0X12415,
+ 0X12416,
+ 0X12417,
+ 0X12418,
+ 0X12419,
+ 0X1241A,
+ 0X1241B,
+ 0X1241C,
+ 0X1241D,
+ 0X1241E,
+ 0X1241F,
+ 0X12420,
+ 0X12421,
+ 0X12422,
+ 0X12423,
+ 0X12424,
+ 0X12425,
+ 0X12426,
+ 0X12427,
+ 0X12428,
+ 0X12429,
+ 0X1242A,
+ 0X1242B,
+ 0X1242C,
+ 0X1242D,
+ 0X1242E,
+ 0X1242F,
+ 0X12430,
+ 0X12431,
+ 0X12432,
+ 0X12433,
+ 0X12434,
+ 0X12435,
+ 0X12436,
+ 0X12437,
+ 0X12438,
+ 0X12439,
+ 0X1243A,
+ 0X1243B,
+ 0X1243C,
+ 0X1243D,
+ 0X1243E,
+ 0X1243F,
+ 0X12440,
+ 0X12441,
+ 0X12442,
+ 0X12443,
+ 0X12444,
+ 0X12445,
+ 0X12446,
+ 0X12447,
+ 0X12448,
+ 0X12449,
+ 0X1244A,
+ 0X1244B,
+ 0X1244C,
+ 0X1244D,
+ 0X1244E,
+ 0X1244F,
+ 0X12450,
+ 0X12451,
+ 0X12452,
+ 0X12453,
+ 0X12454,
+ 0X12455,
+ 0X12456,
+ 0X12457,
+ 0X12458,
+ 0X12459,
+ 0X1245A,
+ 0X1245B,
+ 0X1245C,
+ 0X1245D,
+ 0X1245E,
+ 0X1245F,
+ 0X12460,
+ 0X12461,
+ 0X12462,
+ 0X12463,
+ 0X12464,
+ 0X12465,
+ 0X12466,
+ 0X12467,
+ 0X12468,
+ 0X12469,
+ 0X1246A,
+ 0X1246B,
+ 0X1246C,
+ 0X1246D,
+ 0X1246E,
+ 0X16A60,
+ 0X16A61,
+ 0X16A62,
+ 0X16A63,
+ 0X16A64,
+ 0X16A65,
+ 0X16A66,
+ 0X16A67,
+ 0X16A68,
+ 0X16A69,
+ 0X16B50,
+ 0X16B51,
+ 0X16B52,
+ 0X16B53,
+ 0X16B54,
+ 0X16B55,
+ 0X16B56,
+ 0X16B57,
+ 0X16B58,
+ 0X16B59,
+ 0X16B5B,
+ 0X16B5C,
+ 0X16B5D,
+ 0X16B5E,
+ 0X16B5F,
+ 0X16B60,
+ 0X16B61,
+ 0X16E80,
+ 0X16E81,
+ 0X16E82,
+ 0X16E83,
+ 0X16E84,
+ 0X16E85,
+ 0X16E86,
+ 0X16E87,
+ 0X16E88,
+ 0X16E89,
+ 0X16E8A,
+ 0X16E8B,
+ 0X16E8C,
+ 0X16E8D,
+ 0X16E8E,
+ 0X16E8F,
+ 0X16E90,
+ 0X16E91,
+ 0X16E92,
+ 0X16E93,
+ 0X16E94,
+ 0X16E95,
+ 0X16E96,
+ 0X1D2E0,
+ 0X1D2E1,
+ 0X1D2E2,
+ 0X1D2E3,
+ 0X1D2E4,
+ 0X1D2E5,
+ 0X1D2E6,
+ 0X1D2E7,
+ 0X1D2E8,
+ 0X1D2E9,
+ 0X1D2EA,
+ 0X1D2EB,
+ 0X1D2EC,
+ 0X1D2ED,
+ 0X1D2EE,
+ 0X1D2EF,
+ 0X1D2F0,
+ 0X1D2F1,
+ 0X1D2F2,
+ 0X1D2F3,
+ 0X1D360,
+ 0X1D361,
+ 0X1D362,
+ 0X1D363,
+ 0X1D364,
+ 0X1D365,
+ 0X1D366,
+ 0X1D367,
+ 0X1D368,
+ 0X1D369,
+ 0X1D36A,
+ 0X1D36B,
+ 0X1D36C,
+ 0X1D36D,
+ 0X1D36E,
+ 0X1D36F,
+ 0X1D370,
+ 0X1D371,
+ 0X1D372,
+ 0X1D373,
+ 0X1D374,
+ 0X1D375,
+ 0X1D376,
+ 0X1D377,
+ 0X1D378,
+ 0X1D7CE,
+ 0X1D7CF,
+ 0X1D7D0,
+ 0X1D7D1,
+ 0X1D7D2,
+ 0X1D7D3,
+ 0X1D7D4,
+ 0X1D7D5,
+ 0X1D7D6,
+ 0X1D7D7,
+ 0X1D7D8,
+ 0X1D7D9,
+ 0X1D7DA,
+ 0X1D7DB,
+ 0X1D7DC,
+ 0X1D7DD,
+ 0X1D7DE,
+ 0X1D7DF,
+ 0X1D7E0,
+ 0X1D7E1,
+ 0X1D7E2,
+ 0X1D7E3,
+ 0X1D7E4,
+ 0X1D7E5,
+ 0X1D7E6,
+ 0X1D7E7,
+ 0X1D7E8,
+ 0X1D7E9,
+ 0X1D7EA,
+ 0X1D7EB,
+ 0X1D7EC,
+ 0X1D7ED,
+ 0X1D7EE,
+ 0X1D7EF,
+ 0X1D7F0,
+ 0X1D7F1,
+ 0X1D7F2,
+ 0X1D7F3,
+ 0X1D7F4,
+ 0X1D7F5,
+ 0X1D7F6,
+ 0X1D7F7,
+ 0X1D7F8,
+ 0X1D7F9,
+ 0X1D7FA,
+ 0X1D7FB,
+ 0X1D7FC,
+ 0X1D7FD,
+ 0X1D7FE,
+ 0X1D7FF,
+ 0X1E8C7,
+ 0X1E8C8,
+ 0X1E8C9,
+ 0X1E8CA,
+ 0X1E8CB,
+ 0X1E8CC,
+ 0X1E8CD,
+ 0X1E8CE,
+ 0X1E8CF,
+ 0X1E950,
+ 0X1E951,
+ 0X1E952,
+ 0X1E953,
+ 0X1E954,
+ 0X1E955,
+ 0X1E956,
+ 0X1E957,
+ 0X1E958,
+ 0X1E959,
+ 0X1EC71,
+ 0X1EC72,
+ 0X1EC73,
+ 0X1EC74,
+ 0X1EC75,
+ 0X1EC76,
+ 0X1EC77,
+ 0X1EC78,
+ 0X1EC79,
+ 0X1EC7A,
+ 0X1EC7B,
+ 0X1EC7C,
+ 0X1EC7D,
+ 0X1EC7E,
+ 0X1EC7F,
+ 0X1EC80,
+ 0X1EC81,
+ 0X1EC82,
+ 0X1EC83,
+ 0X1EC84,
+ 0X1EC85,
+ 0X1EC86,
+ 0X1EC87,
+ 0X1EC88,
+ 0X1EC89,
+ 0X1EC8A,
+ 0X1EC8B,
+ 0X1EC8C,
+ 0X1EC8D,
+ 0X1EC8E,
+ 0X1EC8F,
+ 0X1EC90,
+ 0X1EC91,
+ 0X1EC92,
+ 0X1EC93,
+ 0X1EC94,
+ 0X1EC95,
+ 0X1EC96,
+ 0X1EC97,
+ 0X1EC98,
+ 0X1EC99,
+ 0X1EC9A,
+ 0X1EC9B,
+ 0X1EC9C,
+ 0X1EC9D,
+ 0X1EC9E,
+ 0X1EC9F,
+ 0X1ECA0,
+ 0X1ECA1,
+ 0X1ECA2,
+ 0X1ECA3,
+ 0X1ECA4,
+ 0X1ECA5,
+ 0X1ECA6,
+ 0X1ECA7,
+ 0X1ECA8,
+ 0X1ECA9,
+ 0X1ECAA,
+ 0X1ECAB,
+ 0X1ECAD,
+ 0X1ECAE,
+ 0X1ECAF,
+ 0X1ECB1,
+ 0X1ECB2,
+ 0X1ECB3,
+ 0X1ECB4,
+ 0X1F100,
+ 0X1F101,
+ 0X1F102,
+ 0X1F103,
+ 0X1F104,
+ 0X1F105,
+ 0X1F106,
+ 0X1F107,
+ 0X1F108,
+ 0X1F109,
+ 0X1F10A,
+ 0X1F10B,
+ 0X1F10C,
+ 0X20001,
+ 0X20064,
+ 0X200E2,
+ 0X20121,
+ 0X2092A,
+ 0X20983,
+ 0X2098C,
+ 0X2099C,
+ 0X20AEA,
+ 0X20AFD,
+ 0X20B19,
+ 0X22390,
+ 0X22998,
+ 0X23B1B,
+ 0X2626D,
+ 0X2F890,
+)
+
+# Some code that can be used to create the above list of hex numbers.
+if __name__ == "__main__":
+ import unicodedata
+ from natsort.compat.py23 import py23_range, py23_unichr
+
+ hex_chars = []
+ for i in py23_range(0X110000):
+ try:
+ a = py23_unichr(i)
+ except ValueError:
+ break
+ if a in set("0123456789"):
+ continue
+ if unicodedata.numeric(a, None) is not None:
+ hex_chars.append(i)
+
+ print(", ".join(["0X{:X}".format(i) for i in hex_chars]))
diff --git a/natsort/utils.py b/natsort/utils.py
index 306762a..0da401a 100644
--- a/natsort/utils.py
+++ b/natsort/utils.py
@@ -38,12 +38,7 @@ that ensures "val" is a local variable instead of global variable
and thus has a slightly improved performance at runtime.
"""
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
# Std. lib imports.
import re
@@ -60,57 +55,45 @@ from unicodedata import normalize
from natsort.ns_enum import ns
from natsort.unicode_numbers import numeric_no_decimals, digits_no_decimals
from natsort.compat.pathlib import PurePath, has_pathlib
-from natsort.compat.locale import (
- get_strxfrm,
- get_thousands_sep,
- get_decimal_point,
-)
-from natsort.compat.py23 import (
- py23_str,
- py23_map,
- py23_filter,
- PY_VERSION,
- NEWPY,
-)
-from natsort.compat.fastnumbers import (
- fast_float,
- fast_int,
-)
+from natsort.compat.locale import get_strxfrm, get_thousands_sep, get_decimal_point
+from natsort.compat.py23 import py23_str, py23_map, py23_filter, PY_VERSION, NEWPY
+from natsort.compat.fastnumbers import fast_float, fast_int
+
if PY_VERSION >= 3:
long = int
# The regex that locates floats - include Unicode numerals.
_nnd = numeric_no_decimals
-_exp = r'(?:[eE][-+]?\d+)?'
-_num = r'(?:\d+\.?\d*|\.\d+)'
-_float_sign_exp_re = r'([-+]?{0}{1}|[{2}])'
+_exp = r"(?:[eE][-+]?\d+)?"
+_num = r"(?:\d+\.?\d*|\.\d+)"
+_float_sign_exp_re = r"([-+]?{0}{1}|[{2}])"
_float_sign_exp_re = _float_sign_exp_re.format(_num, _exp, _nnd)
_float_sign_exp_re = re.compile(_float_sign_exp_re, flags=re.U)
-_float_nosign_exp_re = r'({0}{1}|[{2}])'
+_float_nosign_exp_re = r"({0}{1}|[{2}])"
_float_nosign_exp_re = _float_nosign_exp_re.format(_num, _exp, _nnd)
_float_nosign_exp_re = re.compile(_float_nosign_exp_re, flags=re.U)
-_float_sign_noexp_re = r'([-+]?{0}|[{1}])'
+_float_sign_noexp_re = r"([-+]?{0}|[{1}])"
_float_sign_noexp_re = _float_sign_noexp_re.format(_num, _nnd)
_float_sign_noexp_re = re.compile(_float_sign_noexp_re, flags=re.U)
-_float_nosign_noexp_re = r'({0}|[{1}])'
+_float_nosign_noexp_re = r"({0}|[{1}])"
_float_nosign_noexp_re = _float_nosign_noexp_re.format(_num, _nnd)
_float_nosign_noexp_re = re.compile(_float_nosign_noexp_re, flags=re.U)
# Integer regexes - include Unicode digits.
-_int_nosign_re = r'(\d+|[{0}])'.format(digits_no_decimals)
+_int_nosign_re = r"(\d+|[{0}])".format(digits_no_decimals)
_int_nosign_re = re.compile(_int_nosign_re, flags=re.U)
-_int_sign_re = r'([-+]?\d+|[{0}])'.format(digits_no_decimals)
+_int_sign_re = r"([-+]?\d+|[{0}])".format(digits_no_decimals)
_int_sign_re = re.compile(_int_sign_re, flags=re.U)
# This dict will help select the correct regex and number conversion function.
_regex_chooser = {
- (ns.F | ns.S): _float_sign_exp_re,
+ (ns.F | ns.S): _float_sign_exp_re,
(ns.F | ns.S | ns.N): _float_sign_noexp_re,
- (ns.F | ns.U): _float_nosign_exp_re,
+ (ns.F | ns.U): _float_nosign_exp_re,
(ns.F | ns.U | ns.N): _float_nosign_noexp_re,
- (ns.I | ns.S): _int_sign_re,
+ (ns.I | ns.S): _int_sign_re,
(ns.I | ns.S | ns.N): _int_sign_re,
- (ns.I | ns.U): _int_nosign_re,
+ (ns.I | ns.U): _int_nosign_re,
(ns.I | ns.U | ns.N): _int_nosign_re,
}
@@ -122,17 +105,19 @@ def _no_op(x):
def _normalize_input_factory(alg):
"""Create a function that will normalize unicode input data."""
- normalization_form = 'NFKD' if alg & ns.COMPATIBILITYNORMALIZE else 'NFD'
+ normalization_form = "NFKD" if alg & ns.COMPATIBILITYNORMALIZE else "NFD"
if NEWPY:
return partial(normalize, normalization_form)
else:
+
def func(x):
"""Normalize unicode input."""
if isinstance(x, py23_str): # unicode
return normalize(normalization_form, x)
else:
return x
+
return func
@@ -175,9 +160,9 @@ def _natsort_key(val, key, string_func, bytes_func, num_func):
# Otherwise, assume it is an iterable that must be parses recursively.
# Do not apply the key recursively.
try:
- return tuple(_natsort_key(
- x, None, string_func, bytes_func, num_func
- ) for x in val)
+ return tuple(
+ _natsort_key(x, None, string_func, bytes_func, num_func) for x in val
+ )
# If that failed, it must be a number.
except TypeError:
@@ -200,7 +185,7 @@ def _parse_bytes_factory(alg):
def _parse_number_factory(alg, sep, pre_sep):
"""Create a function that will properly format a number in a tuple."""
- nan_replace = float('+inf') if alg & ns.NANLAST else float('-inf')
+ nan_replace = float("+inf") if alg & ns.NANLAST else float("-inf")
def func(val, nan_replace=nan_replace, sep=sep):
"""Given a number, place it in a tuple with a leading null string."""
@@ -217,10 +202,9 @@ def _parse_number_factory(alg, sep, pre_sep):
return func
-def _parse_string_factory(alg, sep, splitter,
- input_transform,
- component_transform,
- final_transform):
+def _parse_string_factory(
+ alg, sep, splitter, input_transform, component_transform, final_transform
+):
"""Create a function that will properly split and format a string."""
# Sometimes we store the "original" input before transformation,
# sometimes after.
@@ -234,11 +218,11 @@ def _parse_string_factory(alg, sep, splitter,
# to also be the transformation function.
x = normalize_input(x)
x, original = input_transform(x), original_func(x)
- x = splitter(x) # Split string into components.
- x = py23_filter(None, x) # Remove empty strings.
+ x = splitter(x) # Split string into components.
+ x = py23_filter(None, x) # Remove empty strings.
x = py23_map(component_transform, x) # Apply transform on components.
- x = _sep_inserter(x, sep) # Insert '' between numbers.
- return final_transform(x, original) # Apply the final transform.
+ x = _sep_inserter(x, sep) # Insert '' between numbers.
+ return final_transform(x, original) # Apply the final transform.
return func
@@ -291,17 +275,17 @@ def _input_string_transform_factory(alg):
# Build the chain of functions to execute in order.
function_chain = []
if (dumb and not lowfirst) or (lowfirst and not dumb):
- function_chain.append(methodcaller('swapcase'))
+ function_chain.append(methodcaller("swapcase"))
if alg & ns.IGNORECASE:
if NEWPY:
- function_chain.append(methodcaller('casefold'))
+ function_chain.append(methodcaller("casefold"))
else:
- function_chain.append(methodcaller('lower'))
+ function_chain.append(methodcaller("lower"))
if alg & ns.LOCALENUM:
# Create a regular expression that will remove thousands separators.
- strip_thousands = r'''
+ strip_thousands = r"""
(?<=[0-9]{{1}}) # At least 1 number
(?<![0-9]{{4}}) # No more than 3 numbers
{nodecimal} # Cannot follow decimal
@@ -309,29 +293,30 @@ def _input_string_transform_factory(alg):
(?=[0-9]{{3}} # Three numbers must follow
([^0-9]|$) # But a non-number after that
)
- '''
- nodecimal = r''
+ """
+ nodecimal = r""
if alg & ns.FLOAT:
# Make a regular expression component that will ensure no
# separators are removed after a decimal point.
d = get_decimal_point()
- d = r'\.' if d == r'.' else d
- nodecimal += r'(?<!' + d + r'[0-9])'
- nodecimal += r'(?<!' + d + r'[0-9]{2})'
- nodecimal += r'(?<!' + d + r'[0-9]{3})'
- strip_thousands = strip_thousands.format(thou=get_thousands_sep(),
- nodecimal=nodecimal)
+ d = r"\." if d == r"." else d
+ nodecimal += r"(?<!" + d + r"[0-9])"
+ nodecimal += r"(?<!" + d + r"[0-9]{2})"
+ nodecimal += r"(?<!" + d + r"[0-9]{3})"
+ strip_thousands = strip_thousands.format(
+ thou=get_thousands_sep(), nodecimal=nodecimal
+ )
strip_thousands = re.compile(strip_thousands, flags=re.VERBOSE)
- function_chain.append(partial(strip_thousands.sub, ''))
+ function_chain.append(partial(strip_thousands.sub, ""))
# Create a regular expression that will change the decimal point to
# a period if not already a period.
decimal = get_decimal_point()
- if alg & ns.FLOAT and decimal != '.':
- switch_decimal = r'(?<=[0-9]){decimal}|{decimal}(?=[0-9])'
+ if alg & ns.FLOAT and decimal != ".":
+ switch_decimal = r"(?<=[0-9]){decimal}|{decimal}(?=[0-9])"
switch_decimal = switch_decimal.format(decimal=decimal)
switch_decimal = re.compile(switch_decimal)
- function_chain.append(partial(switch_decimal.sub, '.'))
+ function_chain.append(partial(switch_decimal.sub, "."))
# Return the chained functions.
return chain_functions(function_chain)
@@ -346,7 +331,7 @@ def _string_component_transform_factory(alg):
use_locale = alg & ns.LOCALEALPHA
dumb = alg & ns._DUMB
group_letters = (alg & ns.GROUPLETTERS) or (use_locale and dumb)
- nan_val = float('+inf') if alg & ns.NANLAST else float('-inf')
+ nan_val = float("+inf") if alg & ns.NANLAST else float("-inf")
# Build the chain of functions to execute in order.
func_chain = []
@@ -354,11 +339,11 @@ def _string_component_transform_factory(alg):
func_chain.append(_groupletters)
if use_locale:
func_chain.append(get_strxfrm())
- kwargs = {'key': chain_functions(func_chain)} if func_chain else {}
+ kwargs = {"key": chain_functions(func_chain)} if func_chain else {}
# Return the correct chained functions.
if alg & ns.FLOAT:
- kwargs['nan'] = nan_val
+ kwargs["nan"] = nan_val
return partial(fast_float, **kwargs)
else:
return partial(fast_int, **kwargs)
@@ -371,7 +356,7 @@ def _final_data_transform_factory(alg, sep, pre_sep):
"""
if alg & ns.UNGROUPLETTERS and alg & ns.LOCALEALPHA:
swap = alg & ns._DUMB and alg & ns.LOWERCASEFIRST
- transform = methodcaller('swapcase') if swap else _no_op
+ transform = methodcaller("swapcase") if swap else _no_op
def func(split_val, val, transform=transform):
"""
@@ -387,14 +372,15 @@ def _final_data_transform_factory(alg, sep, pre_sep):
return (pre_sep,), split_val
else:
return (transform(val[0]),), split_val
+
return func
else:
return lambda split_val, val: tuple(split_val)
-def _groupletters(x, _low=methodcaller('casefold' if NEWPY else 'lower')):
+def _groupletters(x, _low=methodcaller("casefold" if NEWPY else "lower")):
"""Double all characters, making doubled letters lowercase."""
- return ''.join(ichain.from_iterable((_low(y), y) for y in x))
+ return "".join(ichain.from_iterable((_low(y), y) for y in x))
def chain_functions(functions):
@@ -443,7 +429,7 @@ def _do_decoding(s, encoding):
return s
-def _path_splitter(s, _d_match=re.compile(r'\.\d').match):
+def _path_splitter(s, _d_match=re.compile(r"\.\d").match):
"""Split a string into its path components. Assumes a string is a path."""
# If a PathLib Object, use it's functionality to perform the split.
if has_pathlib and isinstance(s, PurePath):
@@ -490,30 +476,30 @@ def _path_splitter(s, _d_match=re.compile(r'\.\d').match):
def _args_to_enum(**kwargs):
"""A function to convert input booleans to an enum-type argument."""
alg = 0
- keys = ('number_type', 'signed', 'exp', 'as_path', 'py3_safe')
+ keys = ("number_type", "signed", "exp", "as_path", "py3_safe")
if any(x not in keys for x in kwargs):
x = set(kwargs) - set(keys)
- raise TypeError('Invalid argument(s): ' + ', '.join(x))
- if 'number_type' in kwargs and kwargs['number_type'] is not int:
+ raise TypeError("Invalid argument(s): " + ", ".join(x))
+ if "number_type" in kwargs and kwargs["number_type"] is not int:
msg = "The 'number_type' argument is deprecated as of 3.5.0, "
msg += "please use 'alg=ns.FLOAT', 'alg=ns.INT', or 'alg=ns.VERSION'"
warn(msg, DeprecationWarning)
- alg |= (ns.FLOAT * bool(kwargs['number_type'] is float))
- alg |= (ns.INT * bool(kwargs['number_type'] in (int, None)))
- alg |= (ns.SIGNED * (kwargs['number_type'] not in (float, None)))
- if 'signed' in kwargs and kwargs['signed'] is not None:
+ alg |= ns.FLOAT * bool(kwargs["number_type"] is float)
+ alg |= ns.INT * bool(kwargs["number_type"] in (int, None))
+ alg |= ns.SIGNED * (kwargs["number_type"] not in (float, None))
+ if "signed" in kwargs and kwargs["signed"] is not None:
msg = "The 'signed' argument is deprecated as of 3.5.0, "
msg += "please use 'alg=ns.SIGNED'."
warn(msg, DeprecationWarning)
- alg |= (ns.SIGNED * bool(kwargs['signed']))
- if 'exp' in kwargs and kwargs['exp'] is not None:
+ alg |= ns.SIGNED * bool(kwargs["signed"])
+ if "exp" in kwargs and kwargs["exp"] is not None:
msg = "The 'exp' argument is deprecated as of 3.5.0, "
msg += "please use 'alg=ns.NOEXP'."
warn(msg, DeprecationWarning)
- alg |= (ns.NOEXP * (not kwargs['exp']))
- if 'as_path' in kwargs and kwargs['as_path'] is not None:
+ alg |= ns.NOEXP * (not kwargs["exp"])
+ if "as_path" in kwargs and kwargs["as_path"] is not None:
msg = "The 'as_path' argument is deprecated as of 3.5.0, "
msg += "please use 'alg=ns.PATH'."
warn(msg, DeprecationWarning)
- alg |= (ns.PATH * kwargs['as_path'])
+ alg |= ns.PATH * kwargs["as_path"]
return alg
diff --git a/setup.cfg b/setup.cfg
index 272a46b..73d4c78 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -41,7 +41,7 @@ formats = gztar
[bumpversion:file:setup.py]
-[bumpversion:file:natsort/_version.py]
+[bumpversion:file:natsort/__init__.py]
[bumpversion:file:docs/source/conf.py]
@@ -64,8 +64,5 @@ pep8ignore =
test_natsort/test_natsort_keygen.py E501 E241 E221 E701
test_natsort/profile_natsorted.py ALL
docs/source/conf.py ALL
-
-[flake8]
-max-line-length = 160
-ignore = E231,E302
-
+ * W503
+pep8maxlinelength = 90
diff --git a/test_natsort/compat/locale.py b/test_natsort/compat/locale.py
index bf484a3..76e387c 100644
--- a/test_natsort/compat/locale.py
+++ b/test_natsort/compat/locale.py
@@ -1,10 +1,5 @@
# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
# Std. lib imports.
import locale
@@ -16,13 +11,14 @@ from natsort.compat.py23 import py23_str, py23_unichr, py23_range
def load_locale(x):
""" Convenience to load a locale, trying ISO8859-1 first."""
try:
- locale.setlocale(locale.LC_ALL, str('{0}.ISO8859-1'.format(x)))
+ locale.setlocale(locale.LC_ALL, str("{0}.ISO8859-1".format(x)))
except locale.Error:
- locale.setlocale(locale.LC_ALL, str('{0}.UTF-8'.format(x)))
+ locale.setlocale(locale.LC_ALL, str("{0}.UTF-8".format(x)))
+
# Check if de_DE is installed.
try:
- load_locale('de_DE')
+ load_locale("de_DE")
has_locale_de_DE = True
except locale.Error:
has_locale_de_DE = False
@@ -38,8 +34,7 @@ except AttributeError:
# that has nothing to do with natsort (a ValueError is raised by strxfrm).
# Let's filter them out.
try:
- bad_uni_chars = set(py23_unichr(x) for x in py23_range(0X10fefd,
- 0X10ffff+1))
+ bad_uni_chars = set(py23_unichr(x) for x in py23_range(0X10fefd, 0X10ffff + 1))
except ValueError:
# Narrow unicode build... no worries.
bad_uni_chars = set()
diff --git a/test_natsort/compat/mock.py b/test_natsort/compat/mock.py
index 9ddb302..10c6ccd 100644
--- a/test_natsort/compat/mock.py
+++ b/test_natsort/compat/mock.py
@@ -1,10 +1,6 @@
# -*- coding: utf-8 -*-
-from __future__ import (
- print_function,
- division,
- unicode_literals,
- absolute_import
-)
+from __future__ import print_function, division, unicode_literals, absolute_import
+
# Load mock functions from the right place.
try:
from unittest.mock import MagicMock, patch, call
diff --git a/test_natsort/profile_natsorted.py b/test_natsort/profile_natsorted.py
index e744b16..6fe5746 100644
--- a/test_natsort/profile_natsorted.py
+++ b/test_natsort/profile_natsorted.py
@@ -7,21 +7,22 @@ from __future__ import print_function
import cProfile
import sys
-sys.path.insert(0, '.')
+sys.path.insert(0, ".")
from natsort import natsort_keygen, ns
from natsort.compat.py23 import py23_range
import locale
-locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
+
+locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
# Samples to parse
number = 14695498
-int_string = '43493'
-float_string = '-434.93e7'
-plain_string = 'hello world'
-fancy_string = '7abba9342fdab'
-a_path = '/p/Folder (1)/file (1).tar.gz'
-some_bytes = b'these are bytes'
-a_list = ['hello', 'goodbye', '74']
+int_string = "43493"
+float_string = "-434.93e7"
+plain_string = "hello world"
+fancy_string = "7abba9342fdab"
+a_path = "/p/Folder (1)/file (1).tar.gz"
+some_bytes = b"these are bytes"
+a_list = ["hello", "goodbye", "74"]
basic_key = natsort_keygen()
real_key = natsort_keygen(alg=ns.REAL)
@@ -30,22 +31,35 @@ locale_key = natsort_keygen(alg=ns.LOCALE)
def prof_time_to_generate():
- print('*** Generate Plain Key ***')
+ print("*** Generate Plain Key ***")
for _ in py23_range(100000):
natsort_keygen()
-cProfile.run('prof_time_to_generate()', sort='time')
+
+
+cProfile.run("prof_time_to_generate()", sort="time")
def prof_parsing(a, msg, key=basic_key):
print(msg)
for _ in py23_range(100000):
key(a)
-cProfile.run('prof_parsing(int_string, "*** Basic Call, Int as String ***")', sort='time')
-cProfile.run('prof_parsing(float_string, "*** Basic Call, Float as String ***")', sort='time')
-cProfile.run('prof_parsing(float_string, "*** Real Call ***", real_key)', sort='time')
-cProfile.run('prof_parsing(number, "*** Basic Call, Number ***")', sort='time')
-cProfile.run('prof_parsing(fancy_string, "*** Basic Call, Mixed String ***")', sort='time')
-cProfile.run('prof_parsing(some_bytes, "*** Basic Call, Byte String ***")', sort='time')
-cProfile.run('prof_parsing(a_path, "*** Path Call ***", path_key)', sort='time')
-cProfile.run('prof_parsing(a_list, "*** Basic Call, Recursive ***")', sort='time')
-cProfile.run('prof_parsing("434,930,000 dollars", "*** Locale Call ***", locale_key)', sort='time')
+
+
+cProfile.run(
+ 'prof_parsing(int_string, "*** Basic Call, Int as String ***")', sort="time"
+)
+cProfile.run(
+ 'prof_parsing(float_string, "*** Basic Call, Float as String ***")', sort="time"
+)
+cProfile.run('prof_parsing(float_string, "*** Real Call ***", real_key)', sort="time")
+cProfile.run('prof_parsing(number, "*** Basic Call, Number ***")', sort="time")
+cProfile.run(
+ 'prof_parsing(fancy_string, "*** Basic Call, Mixed String ***")', sort="time"
+)
+cProfile.run('prof_parsing(some_bytes, "*** Basic Call, Byte String ***")', sort="time")
+cProfile.run('prof_parsing(a_path, "*** Path Call ***", path_key)', sort="time")
+cProfile.run('prof_parsing(a_list, "*** Basic Call, Recursive ***")', sort="time")
+cProfile.run(
+ 'prof_parsing("434,930,000 dollars", "*** Locale Call ***", locale_key)',
+ sort="time",
+)
diff --git a/test_natsort/slow_splitters.py b/test_natsort/slow_splitters.py
index cd36161..51989ab 100644
--- a/test_natsort/slow_splitters.py
+++ b/test_natsort/slow_splitters.py
@@ -14,13 +14,12 @@ if PY_VERSION >= 3.0:
triple_none = None, None, None
_sentinel = object()
-SplitElement = collections.namedtuple('SplitElement',
- ['isnum', 'val', 'isuni'])
+SplitElement = collections.namedtuple("SplitElement", ["isnum", "val", "isuni"])
def int_splitter(iterable, signed, sep):
"""Alternate (slow) method to split a string into numbers."""
- iterable = unicodedata.normalize('NFD', iterable)
+ iterable = unicodedata.normalize("NFD", iterable)
split_by_decimal = itertools.groupby(iterable, lambda a: a.isdigit())
split_by_decimal = refine_split_grouping(split_by_decimal)
split = int_splitter_iter(split_by_decimal, signed)
@@ -34,7 +33,7 @@ def float_splitter(iterable, signed, exp, sep):
def number_tester(x):
return x.isdecimal() or unicodedata.numeric(x, None) is not None
- iterable = unicodedata.normalize('NFD', iterable)
+ iterable = unicodedata.normalize("NFD", iterable)
split_by_decimal = itertools.groupby(iterable, number_tester)
split_by_decimal = peekable(refine_split_grouping(split_by_decimal))
split = float_splitter_iter(split_by_decimal, signed, exp)
@@ -56,17 +55,17 @@ def refine_split_grouping(iterable):
yield SplitElement(True, u, True)
# If ASCII, combine into a single multicharacter number.
else:
- val = ''.join(num_values)
+ val = "".join(num_values)
yield SplitElement(True, val, False)
else:
# If non-numeric, combine into a single string.
- val = ''.join(values)
+ val = "".join(values)
yield SplitElement(False, val, False)
def group_unicode_and_ascii_numbers(
- iterable, ascii_digits=frozenset(decimals + '0123456789')
+ iterable, ascii_digits=frozenset(decimals + "0123456789")
):
"""
Use groupby to group ASCII and unicode numeric characters.
@@ -84,31 +83,42 @@ def int_splitter_iter(iterable, signed):
yield int(val)
elif signed:
for x in try_to_read_signed_integer(iterable, val):
- yield int(''.join(x)) if isinstance(x, list) else x
+ yield int("".join(x)) if isinstance(x, list) else x
else:
yield val
def float_splitter_iter(iterable, signed, exp):
"""Split the input into integers and other."""
- weird_check = ('-inf', '-infinity', '+inf', '+infinity',
- 'inf', 'infinity', 'nan', '-nan', '+nan')
+ weird_check = (
+ "-inf",
+ "-infinity",
+ "+inf",
+ "+infinity",
+ "inf",
+ "infinity",
+ "nan",
+ "-nan",
+ "+nan",
+ )
try_to_read_float_correctly = [
try_to_read_float,
try_to_read_float_with_exp,
- functools.partial(try_to_read_signed_float_template,
- key=try_to_read_float),
- functools.partial(try_to_read_signed_float_template,
- key=try_to_read_float_with_exp),
- ][signed * 2 + exp * 1] # Choose the appropriate converter function.
+ functools.partial(try_to_read_signed_float_template, key=try_to_read_float),
+ functools.partial(
+ try_to_read_signed_float_template, key=try_to_read_float_with_exp
+ ),
+ ][
+ signed * 2 + exp * 1
+ ] # Choose the appropriate converter function.
for isnum, val, isuni in iterable:
if isuni:
yield unicodedata.numeric(val)
else:
for x in try_to_read_float_correctly(iterable, isnum, val):
if isinstance(x, list):
- yield float(''.join(x))
- elif x.lower().strip(' \t\n\r\f\v') in weird_check:
+ yield float("".join(x))
+ elif x.lower().strip(" \t\n\r\f\v") in weird_check:
yield float(x)
else:
yield x
@@ -119,7 +129,7 @@ def try_to_read_signed_integer(iterable, val):
If the given string ends with +/-, attempt to return a signed int.
Otherwise, return the string as-is.
"""
- if val.endswith(('+', '-')):
+ if val.endswith(("+", "-")):
next_element = next(iterable, None)
# Last element, return as-is.
@@ -138,7 +148,7 @@ def try_to_read_signed_integer(iterable, val):
yield unicodedata.digit(next_val)
# If the val is *only* the sign, return only the number.
- elif val in ('-', '+'):
+ elif val in ("-", "+"):
yield [val, next_val]
# Otherwise, remove the sign from the val and apply it to the number,
@@ -167,14 +177,14 @@ def try_to_read_float(iterable, isnum, val):
yield val
# If this the decimal point, add it to the number and return.
- elif val == '.':
+ elif val == ".":
next(iterable) # To progress the iterator.
yield [val, next_val]
# If the val ends with the decimal point, split the decimal point
# off the end of the string then place it to the front of the
# iterable so that we can use it later.
- elif val.endswith('.'):
+ elif val.endswith("."):
iterable.push(SplitElement(False, val[-1], False))
yield val[:-1]
@@ -186,9 +196,9 @@ def try_to_read_float(iterable, isnum, val):
else:
# If the next element is not '.', return now.
- if next_val != '.':
+ if next_val != ".":
# If the next val starts with a '.', let's add that.
- if next_val is not None and next_val.startswith('.'):
+ if next_val is not None and next_val.startswith("."):
next(iterable) # To progress the iterator.
iterable.push(SplitElement(False, next_val[1:], False))
yield [val, next_val[0]]
@@ -214,7 +224,7 @@ def try_to_read_float_with_exp(iterable, isnum, val):
Try to read a string that matches num.numE[+-]num and return as a float.
Otherwise return the input as found.
"""
- exp_ident = ('e', 'E', 'e-', 'E-', 'e+', 'E+')
+ exp_ident = ("e", "E", "e-", "E-", "e+", "E+")
# Start by reading the floating point part.
float_ret = next(try_to_read_float(iterable, isnum, val))
@@ -253,10 +263,10 @@ def try_to_read_signed_float_template(iterable, isnum, val, key):
# If it looks like there is a sign here and the next value is a
# non-unicode number, try to parse that with the sign.
- if val.endswith(('+', '-')) and next_isnum and not next_isuni:
+ if val.endswith(("+", "-")) and next_isnum and not next_isuni:
# If this value is a sign, return the combo.
- if val in ('+', '-'):
+ if val in ("+", "-"):
next(iterable) # To progress the iterator.
yield [val] + next(key(iterable, next_isnum, next_val))
@@ -269,13 +279,13 @@ def try_to_read_signed_float_template(iterable, isnum, val, key):
# If it looks like there is a sign here and the next value is a
# decimal, try to parse as a decimal.
- elif val.endswith(('+.', '-.')) and next_isnum and not next_isuni:
+ elif val.endswith(("+.", "-.")) and next_isnum and not next_isuni:
# Push back a zero before the decimal then parse.
print(val, iterable.peek())
# If this value is a sign, return the combo
- if val[:-1] in ('+', '-'):
+ if val[:-1] in ("+", "-"):
yield [val[:-1]] + next(key(iterable, False, val[-1]))
# If the val ends with the sign split the decimal the end of
@@ -366,6 +376,7 @@ class peekable(object):
>>> assert peekable(xrange(1))
>>> assert not peekable([])
"""
+
# Lowercase to blend in with itertools. The fact that it's a class is an
# implementation detail.
@@ -389,7 +400,7 @@ class peekable(object):
Return ``default`` if there are no items left. If ``default`` is not
provided, raise ``StopIteration``.
"""
- if not hasattr(self, '_peek'):
+ if not hasattr(self, "_peek"):
try:
self._peek = next(self._it)
except StopIteration:
@@ -410,7 +421,7 @@ class peekable(object):
def push(self, value):
"""Put an element at the front of the iterable."""
- if hasattr(self, '_peek'):
+ if hasattr(self, "_peek"):
self._it = itertools.chain([value, self._peek], self._it)
del self._peek
else:
diff --git a/test_natsort/test_fake_fastnumbers.py b/test_natsort/test_fake_fastnumbers.py
index 52bbb8c..e22714d 100644
--- a/test_natsort/test_fake_fastnumbers.py
+++ b/test_natsort/test_fake_fastnumbers.py
@@ -7,18 +7,9 @@ from __future__ import unicode_literals
import unicodedata
from math import isnan
from natsort.compat.py23 import PY_VERSION
-from natsort.compat.fake_fastnumbers import (
- fast_float,
- fast_int,
-)
-from hypothesis import (
- given,
-)
-from hypothesis.strategies import (
- floats,
- integers,
- text,
-)
+from natsort.compat.fake_fastnumbers import fast_float, fast_int
+from hypothesis import given
+from hypothesis.strategies import floats, integers, text
if PY_VERSION >= 3:
long = int
@@ -68,18 +59,18 @@ def not_an_int(x):
def test_fast_float_returns_nan_alternate_if_nan_option_is_given():
- assert fast_float('nan', nan=7) == 7
+ assert fast_float("nan", nan=7) == 7
def test_fast_float_converts_float_string_to_float_example():
- assert fast_float('45.8') == 45.8
- assert fast_float('-45') == -45.0
- assert fast_float('45.8e-2', key=len) == 45.8e-2
- assert isnan(fast_float('nan'))
- assert isnan(fast_float('+nan'))
- assert isnan(fast_float('-NaN'))
- assert fast_float('۱۲.۱۲') == 12.12
- assert fast_float('-۱۲.۱۲') == -12.12
+ assert fast_float("45.8") == 45.8
+ assert fast_float("-45") == -45.0
+ assert fast_float("45.8e-2", key=len) == 45.8e-2
+ assert isnan(fast_float("nan"))
+ assert isnan(fast_float("+nan"))
+ assert isnan(fast_float("-NaN"))
+ assert fast_float("۱۲.۱۲") == 12.12
+ assert fast_float("-۱۲.۱۲") == -12.12
@given(floats(allow_nan=False))
@@ -88,7 +79,7 @@ def test_fast_float_converts_float_string_to_float(x):
def test_fast_float_leaves_string_as_is_example():
- assert fast_float('invalid') == 'invalid'
+ assert fast_float("invalid") == "invalid"
@given(text().filter(not_a_float).filter(bool))
@@ -97,7 +88,7 @@ def test_fast_float_leaves_string_as_is(x):
def test_fast_float_with_key_applies_to_string_example():
- assert fast_float('invalid', key=len) == len('invalid')
+ assert fast_float("invalid", key=len) == len("invalid")
@given(text().filter(not_a_float).filter(bool))
@@ -106,9 +97,9 @@ def test_fast_float_with_key_applies_to_string(x):
def test_fast_int_leaves_float_string_as_is_example():
- assert fast_int('45.8') == '45.8'
- assert fast_int('nan') == 'nan'
- assert fast_int('inf') == 'inf'
+ assert fast_int("45.8") == "45.8"
+ assert fast_int("nan") == "nan"
+ assert fast_int("inf") == "inf"
@given(floats().filter(not_an_int))
@@ -117,10 +108,10 @@ def test_fast_int_leaves_float_string_as_is(x):
def test_fast_int_converts_int_string_to_int_example():
- assert fast_int('-45') == -45
- assert fast_int('+45') == 45
- assert fast_int('۱۲') == 12
- assert fast_int('-۱۲') == -12
+ assert fast_int("-45") == -45
+ assert fast_int("+45") == 45
+ assert fast_int("۱۲") == 12
+ assert fast_int("-۱۲") == -12
@given(integers())
@@ -129,7 +120,7 @@ def test_fast_int_converts_int_string_to_int(x):
def test_fast_int_leaves_string_as_is_example():
- assert fast_int('invalid') == 'invalid'
+ assert fast_int("invalid") == "invalid"
@given(text().filter(not_an_int).filter(bool))
@@ -138,7 +129,7 @@ def test_fast_int_leaves_string_as_is(x):
def test_fast_int_with_key_applies_to_string_example():
- assert fast_int('invalid', key=len) == len('invalid')
+ assert fast_int("invalid", key=len) == len("invalid")
@given(text().filter(not_an_int).filter(bool))
diff --git a/test_natsort/test_final_data_transform_factory.py b/test_natsort/test_final_data_transform_factory.py
index f0207e6..d5f5d61 100644
--- a/test_natsort/test_final_data_transform_factory.py
+++ b/test_natsort/test_final_data_transform_factory.py
@@ -5,14 +5,8 @@ from __future__ import unicode_literals
from natsort.ns_enum import ns
from natsort.utils import _final_data_transform_factory
from natsort.compat.py23 import py23_str
-from hypothesis import (
- given,
-)
-from hypothesis.strategies import (
- text,
- floats,
- integers,
-)
+from hypothesis import given
+from hypothesis.strategies import text, floats, integers
# Each test has an "example" version for demonstrative purposes,
@@ -20,38 +14,62 @@ from hypothesis.strategies import (
def test_final_data_transform_factory_with_iterable_returns_tuple_with_no_options_example():
- assert _final_data_transform_factory(0, '', '')(iter([7]), '') == (7,)
+ assert _final_data_transform_factory(0, "", "")(iter([7]), "") == (7,)
@given(text())
def test_final_data_transform_factory_with_iterable_returns_tuple_with_no_options(x):
- assert _final_data_transform_factory(0, '', '')(iter([x]), '') == (x,)
+ assert _final_data_transform_factory(0, "", "")(iter([x]), "") == (x,)
# UNGROUPLETTERS without LOCALE does nothing, as does LOCALE without UNGROUPLETTERS
- assert _final_data_transform_factory(ns.UNGROUPLETTERS, '', '')(iter([x]), '') == _final_data_transform_factory(0, '', '')(iter([x]), '')
- assert _final_data_transform_factory(ns.LOCALE, '', '')(iter([x]), '') == _final_data_transform_factory(0, '', '')(iter([x]), '')
+ assert _final_data_transform_factory(ns.UNGROUPLETTERS, "", "")(
+ iter([x]), ""
+ ) == _final_data_transform_factory(0, "", "")(iter([x]), "")
+ assert _final_data_transform_factory(ns.LOCALE, "", "")(
+ iter([x]), ""
+ ) == _final_data_transform_factory(0, "", "")(iter([x]), "")
def test_final_data_transform_factory_with_empty_tuple_returns_double_empty_tuple():
- assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS, '', '')((), '') == ((), ())
+ assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS, "", "")(
+ (), ""
+ ) == ((), ())
def test_final_data_transform_factory_with_null_string_first_element_adds_empty_string_on_first_tuple_element():
- assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS, '', 'xx')(('', 60), '') == (('xx',), ('', 60))
+ assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS, "", "xx")(
+ ("", 60), ""
+ ) == (("xx",), ("", 60))
def test_final_data_transform_factory_returns_first_element_in_first_tuple_element_example():
- assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS, '', '')(('this', 60), 'this60') == (('t',), ('this', 60))
+ assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS, "", "")(
+ ("this", 60), "this60"
+ ) == (("t",), ("this", 60))
-@given(x=text().filter(bool), y=floats(allow_nan=False, allow_infinity=False) | integers())
-def test_final_data_transform_factory_returns_first_element_in_first_tuple_element(x, y):
- assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS, '', '')((x, y), ''.join(map(py23_str, [x, y]))) == ((x[0],), (x, y))
+@given(
+ x=text().filter(bool), y=floats(allow_nan=False, allow_infinity=False) | integers()
+)
+def test_final_data_transform_factory_returns_first_element_in_first_tuple_element(
+ x, y
+):
+ assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS, "", "")(
+ (x, y), "".join(map(py23_str, [x, y]))
+ ) == ((x[0],), (x, y))
def test_final_data_transform_factory_returns_first_element_in_first_tuple_element_caseswapped_with_DUMB_and_LOWERCASEFIRST_example():
- assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS | ns._DUMB | ns.LOWERCASEFIRST, '', '')(('this', 60), 'this60') == (('T',), ('this', 60))
+ assert _final_data_transform_factory(
+ ns.LOCALE | ns.UNGROUPLETTERS | ns._DUMB | ns.LOWERCASEFIRST, "", ""
+ )(("this", 60), "this60") == (("T",), ("this", 60))
-@given(x=text().filter(bool), y=floats(allow_nan=False, allow_infinity=False) | integers())
-def test_final_data_transform_factory_returns_first_element_in_first_tuple_element_caseswapped_with_DUMB_and_LOWERCASEFIRST(x, y):
- assert _final_data_transform_factory(ns.LOCALE | ns.UNGROUPLETTERS | ns._DUMB | ns.LOWERCASEFIRST, '', '')((x, y), ''.join(map(py23_str, [x, y]))) == ((x[0].swapcase(),), (x, y))
+@given(
+ x=text().filter(bool), y=floats(allow_nan=False, allow_infinity=False) | integers()
+)
+def test_final_data_transform_factory_returns_first_element_in_first_tuple_element_caseswapped_with_DUMB_and_LOWERCASEFIRST(
+ x, y
+):
+ assert _final_data_transform_factory(
+ ns.LOCALE | ns.UNGROUPLETTERS | ns._DUMB | ns.LOWERCASEFIRST, "", ""
+ )((x, y), "".join(map(py23_str, [x, y]))) == ((x[0].swapcase(),), (x, y))
diff --git a/test_natsort/test_input_string_transform_factory.py b/test_natsort/test_input_string_transform_factory.py
index 3dbd843..dbc4c09 100644
--- a/test_natsort/test_input_string_transform_factory.py
+++ b/test_natsort/test_input_string_transform_factory.py
@@ -8,18 +8,9 @@ from operator import methodcaller
from natsort.ns_enum import ns
from natsort.utils import _input_string_transform_factory
from natsort.compat.py23 import NEWPY
-from compat.locale import (
- load_locale,
- has_locale_de_DE,
-)
-from hypothesis import (
- given,
-)
-from hypothesis.strategies import (
- text,
- integers,
- lists,
-)
+from compat.locale import load_locale, has_locale_de_DE
+from hypothesis import given
+from hypothesis.strategies import text, integers, lists
# Each test has an "example" version for demonstrative purposes,
@@ -27,7 +18,7 @@ from hypothesis.strategies import (
def test_input_string_transform_factory_is_no_op_for_no_alg_options_examples():
- x = 'feijGGAd'
+ x = "feijGGAd"
assert _input_string_transform_factory(0)(x) is x
@@ -37,7 +28,7 @@ def test_input_string_transform_factory_is_no_op_for_no_alg_options(x):
def test_input_string_transform_factory_performs_casefold_with_IGNORECASE_examples():
- x = 'feijGGAd'
+ x = "feijGGAd"
if NEWPY:
assert _input_string_transform_factory(ns.IGNORECASE)(x) == x.casefold()
else:
@@ -53,7 +44,7 @@ def test_input_string_transform_factory_performs_casefold_with_IGNORECASE(x):
def test_input_string_transform_factory_performs_swapcase_with_DUMB_examples():
- x = 'feijGGAd'
+ x = "feijGGAd"
assert _input_string_transform_factory(ns._DUMB)(x) == x.swapcase()
@@ -63,18 +54,18 @@ def test_input_string_transform_factory_performs_swapcase_with_DUMB(x):
def test_input_string_transform_factory_performs_swapcase_with_LOWERCASEFIRST_example():
- x = 'feijGGAd'
+ x = "feijGGAd"
assert _input_string_transform_factory(ns.LOWERCASEFIRST)(x) == x.swapcase()
@given(text())
def test_input_string_transform_factory_performs_swapcase_with_LOWERCASEFIRST(x):
- x = 'feijGGAd'
+ x = "feijGGAd"
assert _input_string_transform_factory(ns.LOWERCASEFIRST)(x) == x.swapcase()
def test_input_string_transform_factory_is_no_op_with_both_LOWERCASEFIRST_AND_DUMB_example():
- x = 'feijGGAd'
+ x = "feijGGAd"
assert _input_string_transform_factory(ns._DUMB | ns.LOWERCASEFIRST)(x) is x
@@ -84,100 +75,145 @@ def test_input_string_transform_factory_is_no_op_with_both_LOWERCASEFIRST_AND_DU
def test_input_string_transform_factory_performs_swapcase_and_casefold_both_LOWERCASEFIRST_AND_IGNORECASE_example():
- x = 'feijGGAd'
+ x = "feijGGAd"
if NEWPY:
- assert _input_string_transform_factory(ns.IGNORECASE | ns.LOWERCASEFIRST)(x) == x.swapcase().casefold()
+ assert (
+ _input_string_transform_factory(ns.IGNORECASE | ns.LOWERCASEFIRST)(x)
+ == x.swapcase().casefold()
+ )
else:
- assert _input_string_transform_factory(ns.IGNORECASE | ns.LOWERCASEFIRST)(x) == x.swapcase().lower()
+ assert (
+ _input_string_transform_factory(ns.IGNORECASE | ns.LOWERCASEFIRST)(x)
+ == x.swapcase().lower()
+ )
@given(text())
-def test_input_string_transform_factory_performs_swapcase_and_casefold_both_LOWERCASEFIRST_AND_IGNORECASE(x):
+def test_input_string_transform_factory_performs_swapcase_and_casefold_both_LOWERCASEFIRST_AND_IGNORECASE(
+ x
+):
if NEWPY:
- assert _input_string_transform_factory(ns.IGNORECASE | ns.LOWERCASEFIRST)(x) == x.swapcase().casefold()
+ assert (
+ _input_string_transform_factory(ns.IGNORECASE | ns.LOWERCASEFIRST)(x)
+ == x.swapcase().casefold()
+ )
else:
- assert _input_string_transform_factory(ns.IGNORECASE | ns.LOWERCASEFIRST)(x) == x.swapcase().lower()
+ assert (
+ _input_string_transform_factory(ns.IGNORECASE | ns.LOWERCASEFIRST)(x)
+ == x.swapcase().lower()
+ )
def test_input_string_transform_factory_removes_thousands_separator_with_LOCALE_example():
- load_locale('en_US')
- x = '12,543,642,642.534,534,980' # Without FLOAT it does not account for decimal.
- assert _input_string_transform_factory(ns.LOCALE)(x) == '12543642642.534534980'
- x = '12,543,642,642.534,534,980' # LOCALEALPHA doesn't do anything... need LOCALENUM
- assert _input_string_transform_factory(ns.LOCALEALPHA)(x) == '12,543,642,642.534,534,980'
- locale.setlocale(locale.LC_ALL, str(''))
+ load_locale("en_US")
+ x = "12,543,642,642.534,534,980" # Without FLOAT it does not account for decimal.
+ assert _input_string_transform_factory(ns.LOCALE)(x) == "12543642642.534534980"
+ x = (
+ "12,543,642,642.534,534,980"
+ ) # LOCALEALPHA doesn't do anything... need LOCALENUM
+ assert (
+ _input_string_transform_factory(ns.LOCALEALPHA)(x)
+ == "12,543,642,642.534,534,980"
+ )
+ locale.setlocale(locale.LC_ALL, str(""))
@given(lists(elements=integers(), min_size=4, max_size=20))
def test_input_string_transform_factory_removes_thousands_separator_with_LOCALE(x):
- load_locale('en_US')
- t = ''.join(map(methodcaller('rstrip', 'lL'), map(str, map(abs, x)))) # Remove negative signs trailing L
- s = ''
+ load_locale("en_US")
+ t = "".join(
+ map(methodcaller("rstrip", "lL"), map(str, map(abs, x)))
+ ) # Remove negative signs trailing L
+ s = ""
for i, y in enumerate(reversed(t), 1):
s = y + s
if i % 3 == 0 and i != len(t):
- s = ',' + s
+ s = "," + s
assert _input_string_transform_factory(ns.LOCALE)(s) == t
- locale.setlocale(locale.LC_ALL, str(''))
+ locale.setlocale(locale.LC_ALL, str(""))
def test_input_string_transform_factory_removes_thousands_separator_and_is_float_aware_with_LOCALE_and_FLOAT_example():
- x = '12,543,642,642.534,534,980'
- assert _input_string_transform_factory(ns.LOCALE | ns.FLOAT)(x) == '12543642642.534,534980'
+ x = "12,543,642,642.534,534,980"
+ assert (
+ _input_string_transform_factory(ns.LOCALE | ns.FLOAT)(x)
+ == "12543642642.534,534980"
+ )
-@given(lists(elements=integers(), min_size=4, max_size=20), lists(elements=integers(), min_size=4, max_size=20))
-def test_input_string_transform_factory_removes_thousands_separator_and_is_float_aware_with_LOCALE_and_FLOAT(x, y):
- load_locale('en_US')
- t = ''.join(map(methodcaller('rstrip', 'lL'), map(str, map(abs, x)))) # Remove negative signs trailing L
- s = ''
+@given(
+ lists(elements=integers(), min_size=4, max_size=20),
+ lists(elements=integers(), min_size=4, max_size=20),
+)
+def test_input_string_transform_factory_removes_thousands_separator_and_is_float_aware_with_LOCALE_and_FLOAT(
+ x, y
+):
+ load_locale("en_US")
+ t = "".join(
+ map(methodcaller("rstrip", "lL"), map(str, map(abs, x)))
+ ) # Remove negative signs trailing L
+ s = ""
for i, z in enumerate(reversed(t), 1):
s = z + s
if i % 3 == 0 and i != len(t):
- s = ',' + s
- u = ''.join(map(methodcaller('rstrip', 'lL'), map(str, map(abs, y)))) # Remove negative signs trailing L
- v = ''
+ s = "," + s
+ u = "".join(
+ map(methodcaller("rstrip", "lL"), map(str, map(abs, y)))
+ ) # Remove negative signs trailing L
+ v = ""
for i, z in enumerate(reversed(u), 1):
v = z + v
if i % 3 == 0 and i != len(u):
- v = ',' + v
+ v = "," + v
# Remove all but first comma.
- a = v.split(',', 1)
- p = a[0] + ',' + a[1].replace(',', '')
- assert _input_string_transform_factory(ns.LOCALE)('.'.join([s, v])) == '.'.join([t, u])
- assert _input_string_transform_factory(ns.LOCALE | ns.FLOAT)('.'.join([s, v])) == '.'.join([t, p])
- locale.setlocale(locale.LC_ALL, str(''))
+ a = v.split(",", 1)
+ p = a[0] + "," + a[1].replace(",", "")
+ assert _input_string_transform_factory(ns.LOCALE)(".".join([s, v])) == ".".join(
+ [t, u]
+ )
+ assert _input_string_transform_factory(ns.LOCALE | ns.FLOAT)(
+ ".".join([s, v])
+ ) == ".".join([t, p])
+ locale.setlocale(locale.LC_ALL, str(""))
# These might be too much to test with hypothesis.
def test_input_string_transform_factory_leaves_invalid_thousands_separator_with_LOCALE_example():
- load_locale('en_US')
- x = '12,543,642642.5345,34980'
- assert _input_string_transform_factory(ns.LOCALE)(x) == '12543,642642.5345,34980'
- x = '12,59443,642,642.53,4534980'
- assert _input_string_transform_factory(ns.LOCALE)(x) == '12,59443,642642.53,4534980'
- x = '12543,642,642.5,34534980'
- assert _input_string_transform_factory(ns.LOCALE)(x) == '12543,642642.5,34534980'
- locale.setlocale(locale.LC_ALL, str(''))
+ load_locale("en_US")
+ x = "12,543,642642.5345,34980"
+ assert _input_string_transform_factory(ns.LOCALE)(x) == "12543,642642.5345,34980"
+ x = "12,59443,642,642.53,4534980"
+ assert _input_string_transform_factory(ns.LOCALE)(x) == "12,59443,642642.53,4534980"
+ x = "12543,642,642.5,34534980"
+ assert _input_string_transform_factory(ns.LOCALE)(x) == "12543,642642.5,34534980"
+ locale.setlocale(locale.LC_ALL, str(""))
# @pytest.mark.skipif(not has_locale_de_DE or dumb_sort(), reason='requires de_DE locale and working locale')
-@pytest.mark.skipif(not has_locale_de_DE, reason='requires de_DE locale and working locale')
+@pytest.mark.skipif(
+ not has_locale_de_DE, reason="requires de_DE locale and working locale"
+)
def test_input_string_transform_factory_replaces_decimal_separator_with_LOCALE_example():
- load_locale('de_DE')
- x = '1543,753'
- assert _input_string_transform_factory(ns.LOCALE)(x) == '1543,753' # Does nothing without FLOAT
- assert _input_string_transform_factory(ns.LOCALE | ns.FLOAT)(x) == '1543.753'
- assert _input_string_transform_factory(ns.LOCALEALPHA)(x) == '1543,753' # LOCALEALPHA doesn't do anything... need LOCALENUM
- locale.setlocale(locale.LC_ALL, str(''))
+ load_locale("de_DE")
+ x = "1543,753"
+ assert (
+ _input_string_transform_factory(ns.LOCALE)(x) == "1543,753"
+ ) # Does nothing without FLOAT
+ assert _input_string_transform_factory(ns.LOCALE | ns.FLOAT)(x) == "1543.753"
+ assert (
+ _input_string_transform_factory(ns.LOCALEALPHA)(x) == "1543,753"
+ ) # LOCALEALPHA doesn't do anything... need LOCALENUM
+ locale.setlocale(locale.LC_ALL, str(""))
# @pytest.mark.skipif(not has_locale_de_DE or dumb_sort(), reason='requires de_DE locale and working locale')
-@pytest.mark.skipif(not has_locale_de_DE, reason='requires de_DE locale and working locale')
+@pytest.mark.skipif(
+ not has_locale_de_DE, reason="requires de_DE locale and working locale"
+)
def test_input_string_transform_factory_does_not_replace_invalid_decimal_separator_with_LOCALE_example():
- load_locale('de_DE')
- x = '154s,t53'
- assert _input_string_transform_factory(ns.LOCALE | ns.FLOAT)(x) == '154s,t53'
- locale.setlocale(locale.LC_ALL, str(''))
+ load_locale("de_DE")
+ x = "154s,t53"
+ assert _input_string_transform_factory(ns.LOCALE | ns.FLOAT)(x) == "154s,t53"
+ locale.setlocale(locale.LC_ALL, str(""))
diff --git a/test_natsort/test_main.py b/test_natsort/test_main.py
index 6455c69..85b7151 100644
--- a/test_natsort/test_main.py
+++ b/test_natsort/test_main.py
@@ -7,15 +7,8 @@ import re
import sys
from pytest import raises
from compat.mock import patch, call
-from hypothesis import (
- given,
-)
-from hypothesis.strategies import (
- integers,
- floats,
- lists,
- data,
-)
+from hypothesis import given
+from hypothesis.strategies import integers, floats, lists, data
from natsort.__main__ import (
main,
range_check,
@@ -27,8 +20,8 @@ from natsort.__main__ import (
def test_main_passes_default_arguments_with_no_command_line_options():
- with patch('natsort.__main__.sort_and_print_entries') as p:
- sys.argv[1:] = ['num-2', 'num-6', 'num-1']
+ with patch("natsort.__main__.sort_and_print_entries") as p:
+ sys.argv[1:] = ["num-2", "num-6", "num-1"]
main()
args = p.call_args[0][1]
assert not args.paths
@@ -36,20 +29,36 @@ def test_main_passes_default_arguments_with_no_command_line_options():
assert args.reverse_filter is None
assert args.exclude is None
assert not args.reverse
- assert args.number_type == 'int'
+ assert args.number_type == "int"
assert not args.signed
assert args.exp
assert not args.locale
def test_main_passes_arguments_with_all_command_line_options():
- with patch('natsort.__main__.sort_and_print_entries') as p:
- sys.argv[1:] = ['--paths', '--reverse', '--locale',
- '--filter', '4', '10',
- '--reverse-filter', '100', '110',
- '--number-type', 'float', '--noexp', '--sign',
- '--exclude', '34', '--exclude', '35',
- 'num-2', 'num-6', 'num-1']
+ with patch("natsort.__main__.sort_and_print_entries") as p:
+ sys.argv[1:] = [
+ "--paths",
+ "--reverse",
+ "--locale",
+ "--filter",
+ "4",
+ "10",
+ "--reverse-filter",
+ "100",
+ "110",
+ "--number-type",
+ "float",
+ "--noexp",
+ "--sign",
+ "--exclude",
+ "34",
+ "--exclude",
+ "35",
+ "num-2",
+ "num-6",
+ "num-1",
+ ]
main()
args = p.call_args[0][1]
assert args.paths
@@ -57,7 +66,7 @@ def test_main_passes_arguments_with_all_command_line_options():
assert args.reverse_filter == [(100.0, 110.0)]
assert args.exclude == [34, 35]
assert args.reverse
- assert args.number_type == 'float'
+ assert args.number_type == "float"
assert args.signed
assert not args.exp
assert args.locale
@@ -65,26 +74,30 @@ def test_main_passes_arguments_with_all_command_line_options():
class Args:
"""A dummy class to simulate the argparse Namespace object"""
+
def __init__(self, filt, reverse_filter, exclude, as_path, reverse):
self.filter = filt
self.reverse_filter = reverse_filter
self.exclude = exclude
self.reverse = reverse
- self.number_type = 'float'
+ self.number_type = "float"
self.signed = True
self.exp = True
self.paths = as_path
self.locale = 0
-entries = ['tmp/a57/path2',
- 'tmp/a23/path1',
- 'tmp/a1/path1',
- 'tmp/a1 (1)/path1',
- 'tmp/a130/path1',
- 'tmp/a64/path1',
- 'tmp/a64/path2']
-mock_print = '__builtin__.print' if sys.version[0] == '2' else 'builtins.print'
+entries = [
+ "tmp/a57/path2",
+ "tmp/a23/path1",
+ "tmp/a1/path1",
+ "tmp/a1 (1)/path1",
+ "tmp/a130/path1",
+ "tmp/a64/path1",
+ "tmp/a64/path2",
+]
+
+mock_print = "__builtin__.print" if sys.version[0] == "2" else "builtins.print"
def test_sort_and_print_entries_uses_default_algorithm_with_all_options_false():
@@ -165,20 +178,27 @@ def test_sort_and_print_entries_reverses_order_with_reverse_option():
# Each test has an "example" version for demonstrative purposes,
# and a test that uses the hypothesis module.
+
def test_range_check_returns_range_as_is_but_with_floats_if_first_is_less_than_second_example():
assert range_check(10, 11) == (10.0, 11.0)
assert range_check(6.4, 30) == (6.4, 30.0)
@given(x=integers(), data=data()) # Defer data selection for y till test is run.
-def test_range_check_returns_range_as_is_but_with_floats_if_first_is_less_than_second(x, data):
+def test_range_check_returns_range_as_is_but_with_floats_if_first_is_less_than_second(
+ x, data
+):
# Pull data such that the first is less than the second.
y = data.draw(integers(min_value=x + 1))
assert range_check(x, y) == (x, y)
-@given(x=floats(allow_nan=False, min_value=-1E8, max_value=1E8), data=data()) # Defer data selection for y till test is run.
-def test_range_check_returns_range_as_is_but_with_floats_if_first_is_less_than_second2(x, data):
+@given(
+ x=floats(allow_nan=False, min_value=-1E8, max_value=1E8), data=data()
+) # Defer data selection for y till test is run.
+def test_range_check_returns_range_as_is_but_with_floats_if_first_is_less_than_second2(
+ x, data
+):
# Pull data such that the first is less than the second.
y = data.draw(floats(min_value=x + 1.0, max_value=1E9, allow_nan=False))
assert range_check(x, y) == (x, y)
@@ -187,16 +207,18 @@ def test_range_check_returns_range_as_is_but_with_floats_if_first_is_less_than_s
def test_range_check_raises_ValueError_if_second_is_less_than_first_example():
with raises(ValueError) as err:
range_check(7, 2)
- assert str(err.value) == 'low >= high'
+ assert str(err.value) == "low >= high"
-@given(x=floats(allow_nan=False), data=data()) # Defer data selection for y till test is run.
+@given(
+ x=floats(allow_nan=False), data=data()
+) # Defer data selection for y till test is run.
def test_range_check_raises_ValueError_if_second_is_less_than_first(x, data):
# Pull data such that the first is greater than or equal to the second.
y = data.draw(floats(max_value=x, allow_nan=False))
with raises(ValueError) as err:
range_check(x, y)
- assert str(err.value) == 'low >= high'
+ assert str(err.value) == "low >= high"
def test_check_filter_returns_None_if_filter_evaluates_to_False():
@@ -210,41 +232,50 @@ def test_check_filter_returns_input_as_is_if_filter_is_valid_example():
assert check_filter([(6, 7), (2, 8)]) == [(6, 7), (2, 8)]
-@given(x=lists(integers(), min_size=1), data=data()) # Defer data selection for y till test is run.
+@given(
+ x=lists(integers(), min_size=1), data=data()
+) # Defer data selection for y till test is run.
def test_check_filter_returns_input_as_is_if_filter_is_valid(x, data):
- y = [data.draw(integers(min_value=val + 1)) for val in x] # ensure y is element-wise greater than x
+ y = [
+ data.draw(integers(min_value=val + 1)) for val in x
+ ] # ensure y is element-wise greater than x
assert check_filter(list(zip(x, y))) == [(i, j) for i, j in zip(x, y)]
def test_check_filter_raises_ValueError_if_filter_is_invalid_example():
with raises(ValueError) as err:
check_filter([(7, 2)])
- assert str(err.value) == 'Error in --filter: low >= high'
+ assert str(err.value) == "Error in --filter: low >= high"
-@given(x=lists(integers(), min_size=1), data=data()) # Defer data selection for y till test is run.
+@given(
+ x=lists(integers(), min_size=1), data=data()
+) # Defer data selection for y till test is run.
def test_check_filter_raises_ValueError_if_filter_is_invalid(x, data):
- y = [data.draw(integers(max_value=val)) for val in x] # ensure y is element-wise less than or equal to x
+ y = [
+ data.draw(integers(max_value=val)) for val in x
+ ] # ensure y is element-wise less than or equal to x
+
with raises(ValueError) as err:
check_filter(list(zip(x, y)))
- assert str(err.value) == 'Error in --filter: low >= high'
+ assert str(err.value) == "Error in --filter: low >= high"
def test_keep_entry_range_returns_True_if_any_portion_of_input_is_between_the_range_bounds_example():
- assert keep_entry_range('a56b23c89', [0], [100], int, re.compile(r'\d+'))
+ assert keep_entry_range("a56b23c89", [0], [100], int, re.compile(r"\d+"))
def test_keep_entry_range_returns_True_if_any_portion_of_input_is_between_any_range_bounds_example():
- assert keep_entry_range('a56b23c89', [1, 88], [20, 90], int, re.compile(r'\d+'))
+ assert keep_entry_range("a56b23c89", [1, 88], [20, 90], int, re.compile(r"\d+"))
def test_keep_entry_range_returns_False_if_no_portion_of_input_is_between_the_range_bounds_example():
- assert not keep_entry_range('a56b23c89', [1], [20], int, re.compile(r'\d+'))
+ assert not keep_entry_range("a56b23c89", [1], [20], int, re.compile(r"\d+"))
def test_exclude_entry_returns_True_if_exlcude_parameters_are_not_in_input_example():
- assert exclude_entry('a56b23c89', [100, 45], int, re.compile(r'\d+'))
+ assert exclude_entry("a56b23c89", [100, 45], int, re.compile(r"\d+"))
def test_exclude_entry_returns_False_if_exlcude_parameters_are_in_input_example():
- assert not exclude_entry('a56b23c89', [23], int, re.compile(r'\d+'))
+ assert not exclude_entry("a56b23c89", [23], int, re.compile(r"\d+"))
diff --git a/test_natsort/test_natsort_cmp.py b/test_natsort/test_natsort_cmp.py
index 6c6d87b..f7d5d8b 100644
--- a/test_natsort/test_natsort_cmp.py
+++ b/test_natsort/test_natsort_cmp.py
@@ -24,6 +24,7 @@ if PY_VERSION < 3:
class Comparable(object):
"""Stub class for testing natcmp functionality."""
+
def __init__(self, value):
self.value = value
@@ -31,7 +32,7 @@ class Comparable(object):
return natcmp(self.value, other.value)
-@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason="cmp() deprecated in Python 3")
def test__classes_can_be_compared():
one = Comparable("1")
two = Comparable("2")
@@ -41,7 +42,7 @@ def test__classes_can_be_compared():
assert ten > two == another_two > one
-@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason="cmp() deprecated in Python 3")
def test__keys_are_being_cached():
natcmp.cached_keys = {}
assert len(natcmp.cached_keys) == 0
@@ -50,20 +51,20 @@ def test__keys_are_being_cached():
natcmp(0, 0)
assert len(natcmp.cached_keys) == 1
- with patch('natsort.compat.locale.dumb_sort', return_value=False):
+ with patch("natsort.compat.locale.dumb_sort", return_value=False):
natcmp(0, 0, alg=ns.L)
assert len(natcmp.cached_keys) == 2
natcmp(0, 0, alg=ns.L)
assert len(natcmp.cached_keys) == 2
- with patch('natsort.compat.locale.dumb_sort', return_value=True):
+ with patch("natsort.compat.locale.dumb_sort", return_value=True):
natcmp(0, 0, alg=ns.L)
assert len(natcmp.cached_keys) == 3
natcmp(0, 0, alg=ns.L)
assert len(natcmp.cached_keys) == 3
-@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason="cmp() deprecated in Python 3")
def test__illegal_algorithm_raises_error():
try:
natcmp(0, 0, alg="Just random stuff")
@@ -76,7 +77,7 @@ def test__illegal_algorithm_raises_error():
assert False
-@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason="cmp() deprecated in Python 3")
def test__classes_can_utilize_max_or_min():
comparables = [Comparable(i) for i in range(10)]
@@ -84,19 +85,19 @@ def test__classes_can_utilize_max_or_min():
assert min(comparables) == comparables[0]
-@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason="cmp() deprecated in Python 3")
@given(integers(), integers())
def test__natcmp_works_the_same_for_integers_as_cmp(x, y):
assert py23_cmp(x, y) == natcmp(x, y)
-@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason="cmp() deprecated in Python 3")
@given(floats(allow_nan=False), floats(allow_nan=False))
def test__natcmp_works_the_same_for_floats_as_cmp(x, y):
assert py23_cmp(x, y) == natcmp(x, y)
-@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason="cmp() deprecated in Python 3")
@given(lists(elements=integers()))
def test_sort_strings_with_numbers(a_list):
strings = [str(var) for var in a_list]
diff --git a/test_natsort/test_natsort_key.py b/test_natsort/test_natsort_key.py
index 9aabd11..0d35d54 100644
--- a/test_natsort/test_natsort_key.py
+++ b/test_natsort/test_natsort_key.py
@@ -16,16 +16,8 @@ from natsort.utils import (
_string_component_transform_factory,
_final_data_transform_factory,
)
-from hypothesis import (
- given,
-)
-from hypothesis.strategies import (
- lists,
- text,
- floats,
- integers,
- binary,
-)
+from hypothesis import given
+from hypothesis.strategies import lists, text, floats, integers, binary
if PY_VERSION >= 3:
long = int
@@ -34,10 +26,10 @@ if PY_VERSION >= 3:
regex = _regex_chooser[ns.INT]
pre = _input_string_transform_factory(ns.INT)
post = _string_component_transform_factory(ns.INT)
-after = _final_data_transform_factory(ns.INT, '', '')
-string_func = _parse_string_factory(ns.INT, '', regex.split, pre, post, after)
+after = _final_data_transform_factory(ns.INT, "", "")
+string_func = _parse_string_factory(ns.INT, "", regex.split, pre, post, after)
bytes_func = _parse_bytes_factory(ns.INT)
-num_func = _parse_number_factory(ns.INT, '', '')
+num_func = _parse_number_factory(ns.INT, "", "")
def test__natsort_key_with_numeric_input_and_PATH_returns_number_in_nested_tuple():
@@ -45,26 +37,30 @@ def test__natsort_key_with_numeric_input_and_PATH_returns_number_in_nested_tuple
# so it will sort against the other as_path results.
sfunc = _parse_path_factory(string_func)
bytes_func = _parse_bytes_factory(ns.PATH)
- num_func = _parse_number_factory(ns.PATH, '', '')
- assert _natsort_key(10, None, sfunc, bytes_func, num_func) == (('', 10),)
+ num_func = _parse_number_factory(ns.PATH, "", "")
+ assert _natsort_key(10, None, sfunc, bytes_func, num_func) == (("", 10),)
-@pytest.mark.skipif(PY_VERSION < 3, reason='only valid on python3')
+@pytest.mark.skipif(PY_VERSION < 3, reason="only valid on python3")
def test__natsort_key_with_bytes_input_and_PATH_returns_number_in_nested_tuple():
# It gracefully handles as_path for numeric input by putting an extra tuple around it
# so it will sort against the other as_path results.
sfunc = _parse_path_factory(string_func)
bytes_func = _parse_bytes_factory(ns.PATH)
- num_func = _parse_number_factory(ns.PATH, '', '')
- assert _natsort_key(b'/hello/world', None, sfunc, bytes_func, num_func) == ((b'/hello/world',),)
+ num_func = _parse_number_factory(ns.PATH, "", "")
+ assert _natsort_key(b"/hello/world", None, sfunc, bytes_func, num_func) == (
+ (b"/hello/world",),
+ )
def test__natsort_key_with_tuple_of_paths_and_PATH_returns_triply_nested_tuple():
# PATH also handles recursion well.
sfunc = _parse_path_factory(string_func)
bytes_func = _parse_bytes_factory(ns.PATH)
- num_func = _parse_number_factory(ns.PATH, '', '')
- assert _natsort_key(('/Folder', '/Folder (1)'), None, sfunc, bytes_func, num_func) == ((('/',), ('Folder',)), (('/',), ('Folder (', 1, ')')))
+ num_func = _parse_number_factory(ns.PATH, "", "")
+ assert _natsort_key(
+ ("/Folder", "/Folder (1)"), None, sfunc, bytes_func, num_func
+ ) == ((("/",), ("Folder",)), (("/",), ("Folder (", 1, ")")))
# The remaining tests provide no examples, just hypothesis tests.
@@ -76,21 +72,27 @@ def test__natsort_key_with_numeric_input_takes_number_path(x):
assert _natsort_key(x, None, string_func, bytes_func, num_func) == num_func(x)
-@pytest.mark.skipif(PY_VERSION < 3, reason='only valid on python3')
+@pytest.mark.skipif(PY_VERSION < 3, reason="only valid on python3")
@given(binary().filter(bool))
def test__natsort_key_with_bytes_input_takes_bytes_path(x):
assert _natsort_key(x, None, string_func, bytes_func, num_func) == bytes_func(x)
-@given(lists(elements=floats(allow_nan=False) | text() | integers(), min_size=1, max_size=10))
+@given(
+ lists(
+ elements=floats(allow_nan=False) | text() | integers(), min_size=1, max_size=10
+ )
+)
def test__natsort_key_with_text_input_takes_string_path(x):
- s = ''.join(repr(y) if type(y) in (float, long, int) else y for y in x)
+ s = "".join(repr(y) if type(y) in (float, long, int) else y for y in x)
assert _natsort_key(s, None, string_func, bytes_func, num_func) == string_func(s)
@given(lists(elements=text(), min_size=1, max_size=10))
def test__natsort_key_with_nested_input_takes_nested_path(x):
- assert _natsort_key(x, None, string_func, bytes_func, num_func) == tuple(string_func(s) for s in x)
+ assert _natsort_key(x, None, string_func, bytes_func, num_func) == tuple(
+ string_func(s) for s in x
+ )
@given(text())
diff --git a/test_natsort/test_natsort_keygen.py b/test_natsort/test_natsort_keygen.py
index 9ea408a..5fc10d6 100644
--- a/test_natsort/test_natsort_keygen.py
+++ b/test_natsort/test_natsort_keygen.py
@@ -8,34 +8,29 @@ from __future__ import unicode_literals, print_function
import warnings
import locale
from pytest import raises
-from natsort import (
- natsorted,
- natsort_key,
- natsort_keygen,
- ns,
-)
+from natsort import natsorted, natsort_key, natsort_keygen, ns
from natsort.compat.py23 import PY_VERSION
-from natsort.compat.locale import (
- null_string_locale,
- get_strxfrm,
-)
+from natsort.compat.locale import null_string_locale, get_strxfrm
from compat.mock import patch
from compat.locale import load_locale
-INPUT = ['6A-5.034e+1', '/Folder (1)/Foo', 56.7]
+INPUT = ["6A-5.034e+1", "/Folder (1)/Foo", 56.7]
def test_natsort_key_public_raises_DeprecationWarning_when_called():
# But it raises a deprecation warning
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
- assert natsort_key('a-5.034e2') == ('a-', 5, '.', 34, 'e', 2)
+ assert natsort_key("a-5.034e2") == ("a-", 5, ".", 34, "e", 2)
assert len(w) == 1
- assert "natsort_key is deprecated as of 3.4.0, please use natsort_keygen" in str(w[-1].message)
+ assert (
+ "natsort_key is deprecated as of 3.4.0, please use natsort_keygen"
+ in str(w[-1].message)
+ )
# It is called for each element in a list when sorting
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
- a = ['a2', 'a5', 'a9', 'a1', 'a4', 'a10', 'a6']
+ a = ["a2", "a5", "a9", "a1", "a4", "a10", "a6"]
a.sort(key=natsort_key)
assert len(w) == 7
@@ -43,63 +38,137 @@ def test_natsort_key_public_raises_DeprecationWarning_when_called():
def test_natsort_keygen_with_invalid_alg_input_raises_ValueError():
# Invalid arguments give the correct response
with raises(ValueError) as err:
- natsort_keygen(None, '1')
- assert str(err.value) == "natsort_keygen: 'alg' argument must be from the enum 'ns', got 1"
+ natsort_keygen(None, "1")
+ assert (
+ str(err.value)
+ == "natsort_keygen: 'alg' argument must be from the enum 'ns', got 1"
+ )
def test_natsort_keygen_returns_natsort_key_that_parses_input():
- a = 'a-5.034e1'
- assert natsort_keygen()(a) == ('a-', 5, '.', 34, 'e', 1)
- assert natsort_keygen(alg=ns.F | ns.S)(a) == ('a', -50.34)
+ a = "a-5.034e1"
+ assert natsort_keygen()(a) == ("a-", 5, ".", 34, "e", 1)
+ assert natsort_keygen(alg=ns.F | ns.S)(a) == ("a", -50.34)
def test_natsort_keygen_returns_key_that_can_be_used_to_sort_list_in_place_with_same_result_as_natsorted():
- a = ['a50', 'a51.', 'a50.31', 'a50.4', 'a5.034e1', 'a50.300']
+ a = ["a50", "a51.", "a50.31", "a50.4", "a5.034e1", "a50.300"]
b = a[:]
a.sort(key=natsort_keygen(alg=ns.F))
assert a == natsorted(b, alg=ns.F)
def test_natsort_keygen_splits_input_with_defaults():
- assert natsort_keygen()(INPUT) == (('', 6, 'A-', 5, '.', 34, 'e+', 1), ('/Folder (', 1, ')/Foo'), ('', 56.7))
- if PY_VERSION >= 3: assert natsort_keygen()(b'6A-5.034e+1') == (b'6A-5.034e+1',)
+ assert natsort_keygen()(INPUT) == (
+ ("", 6, "A-", 5, ".", 34, "e+", 1),
+ ("/Folder (", 1, ")/Foo"),
+ ("", 56.7),
+ )
+ if PY_VERSION >= 3:
+ assert natsort_keygen()(b"6A-5.034e+1") == (b"6A-5.034e+1",)
def test_natsort_keygen_splits_input_with_real():
- assert natsort_keygen(alg=ns.R)(INPUT) == (('', 6.0, 'A', -50.34), ('/Folder (', 1.0, ')/Foo'), ('', 56.7))
- if PY_VERSION >= 3: assert natsort_keygen(alg=ns.R)(b'6A-5.034e+1') == (b'6A-5.034e+1',)
+ assert natsort_keygen(alg=ns.R)(INPUT) == (
+ ("", 6.0, "A", -50.34),
+ ("/Folder (", 1.0, ")/Foo"),
+ ("", 56.7),
+ )
+ if PY_VERSION >= 3:
+ assert natsort_keygen(alg=ns.R)(b"6A-5.034e+1") == (b"6A-5.034e+1",)
def test_natsort_keygen_splits_input_with_lowercasefirst_noexp_float():
- assert natsort_keygen(alg=ns.LF | ns.F | ns.N)(INPUT) == (('', 6.0, 'a-', 5.034, 'E+', 1.0), ('/fOLDER (', 1.0, ')/fOO'), ('', 56.7))
- if PY_VERSION >= 3: assert natsort_keygen(alg=ns.LF | ns.F | ns.N)(b'6A-5.034e+1') == (b'6A-5.034e+1',)
+ assert natsort_keygen(alg=ns.LF | ns.F | ns.N)(INPUT) == (
+ ("", 6.0, "a-", 5.034, "E+", 1.0),
+ ("/fOLDER (", 1.0, ")/fOO"),
+ ("", 56.7),
+ )
+ if PY_VERSION >= 3:
+ assert natsort_keygen(alg=ns.LF | ns.F | ns.N)(b"6A-5.034e+1") == (
+ b"6A-5.034e+1",
+ )
def test_natsort_keygen_splits_input_with_locale():
- load_locale('en_US')
+ load_locale("en_US")
strxfrm = get_strxfrm()
- with patch('natsort.compat.locale.dumb_sort', return_value=False):
- assert natsort_keygen(alg=ns.L)(INPUT) == ((null_string_locale, 6, strxfrm('A-'), 5, strxfrm('.'), 34, strxfrm('e+'), 1), (strxfrm('/Folder ('), 1, strxfrm(')/Foo')), (null_string_locale, 56.7))
- with patch('natsort.compat.locale.dumb_sort', return_value=True):
- assert natsort_keygen(alg=ns.L)(INPUT) == ((null_string_locale, 6, strxfrm('aa--'), 5, strxfrm('..'), 34, strxfrm('eE++'), 1), (strxfrm('//ffoOlLdDeErR (('), 1, strxfrm('))//ffoOoO')), (null_string_locale, 56.7))
- if PY_VERSION >= 3: assert natsort_keygen(alg=ns.LA)(b'6A-5.034e+1') == (b'6A-5.034e+1',)
- locale.setlocale(locale.LC_ALL, str(''))
+ with patch("natsort.compat.locale.dumb_sort", return_value=False):
+ assert natsort_keygen(alg=ns.L)(INPUT) == (
+ (
+ null_string_locale,
+ 6,
+ strxfrm("A-"),
+ 5,
+ strxfrm("."),
+ 34,
+ strxfrm("e+"),
+ 1,
+ ),
+ (strxfrm("/Folder ("), 1, strxfrm(")/Foo")),
+ (null_string_locale, 56.7),
+ )
+ with patch("natsort.compat.locale.dumb_sort", return_value=True):
+ assert natsort_keygen(alg=ns.L)(INPUT) == (
+ (
+ null_string_locale,
+ 6,
+ strxfrm("aa--"),
+ 5,
+ strxfrm(".."),
+ 34,
+ strxfrm("eE++"),
+ 1,
+ ),
+ (strxfrm("//ffoOlLdDeErR (("), 1, strxfrm("))//ffoOoO")),
+ (null_string_locale, 56.7),
+ )
+ if PY_VERSION >= 3:
+ assert natsort_keygen(alg=ns.LA)(b"6A-5.034e+1") == (b"6A-5.034e+1",)
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsort_keygen_splits_input_with_locale_and_capitalfirst():
- load_locale('en_US')
+ load_locale("en_US")
strxfrm = get_strxfrm()
- with patch('natsort.compat.locale.dumb_sort', return_value=False):
- assert natsort_keygen(alg=ns.LA | ns.C)(INPUT) == ((('',), (null_string_locale, 6, strxfrm('A-'), 5, strxfrm('.'), 34, strxfrm('e+'), 1)), (('/',), (strxfrm('/Folder ('), 1, strxfrm(')/Foo'))), (('',), (null_string_locale, 56.7)))
- if PY_VERSION >= 3: assert natsort_keygen(alg=ns.LA | ns.C)(b'6A-5.034e+1') == (b'6A-5.034e+1',)
- locale.setlocale(locale.LC_ALL, str(''))
+ with patch("natsort.compat.locale.dumb_sort", return_value=False):
+ assert natsort_keygen(alg=ns.LA | ns.C)(INPUT) == (
+ (
+ ("",),
+ (
+ null_string_locale,
+ 6,
+ strxfrm("A-"),
+ 5,
+ strxfrm("."),
+ 34,
+ strxfrm("e+"),
+ 1,
+ ),
+ ),
+ (("/",), (strxfrm("/Folder ("), 1, strxfrm(")/Foo"))),
+ (("",), (null_string_locale, 56.7)),
+ )
+ if PY_VERSION >= 3:
+ assert natsort_keygen(alg=ns.LA | ns.C)(b"6A-5.034e+1") == (b"6A-5.034e+1",)
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsort_keygen_splits_input_with_path():
- assert natsort_keygen(alg=ns.P | ns.G)(INPUT) == ((('', 6, 'aA--', 5, '..', 34, 'ee++', 1),), (('//',), ('fFoollddeerr ((', 1, '))'), ('fFoooo',)), (('', 56.7),))
- if PY_VERSION >= 3: assert natsort_keygen(alg=ns.P | ns.G)(b'6A-5.034e+1') == ((b'6A-5.034e+1',),)
+ assert natsort_keygen(alg=ns.P | ns.G)(INPUT) == (
+ (("", 6, "aA--", 5, "..", 34, "ee++", 1),),
+ (("//",), ("fFoollddeerr ((", 1, "))"), ("fFoooo",)),
+ (("", 56.7),),
+ )
+ if PY_VERSION >= 3:
+ assert natsort_keygen(alg=ns.P | ns.G)(b"6A-5.034e+1") == ((b"6A-5.034e+1",),)
def test_natsort_keygen_splits_input_with_ignorecase():
- assert natsort_keygen(alg=ns.IC)(INPUT) == (('', 6, 'a-', 5, '.', 34, 'e+', 1), ('/folder (', 1, ')/foo'), ('', 56.7))
- if PY_VERSION >= 3: assert natsort_keygen(alg=ns.IC)(b'6A-5.034e+1') == (b'6a-5.034e+1',)
+ assert natsort_keygen(alg=ns.IC)(INPUT) == (
+ ("", 6, "a-", 5, ".", 34, "e+", 1),
+ ("/folder (", 1, ")/foo"),
+ ("", 56.7),
+ )
+ if PY_VERSION >= 3:
+ assert natsort_keygen(alg=ns.IC)(b"6A-5.034e+1") == (b"6a-5.034e+1",)
diff --git a/test_natsort/test_natsorted.py b/test_natsort/test_natsorted.py
index ce6b879..b698595 100644
--- a/test_natsort/test_natsorted.py
+++ b/test_natsort/test_natsorted.py
@@ -9,102 +9,166 @@ import locale
from natsort.compat.py23 import PY_VERSION
from operator import itemgetter
from pytest import raises
-from natsort import (
- natsorted,
- ns,
-)
-from compat.locale import (
- load_locale,
- has_locale_de_DE,
-)
+from natsort import natsorted, ns
+from compat.locale import load_locale, has_locale_de_DE
def test_natsorted_returns_strings_with_numbers_in_ascending_order():
- a = ['a2', 'a5', 'a9', 'a1', 'a4', 'a10', 'a6']
- assert natsorted(a) == ['a1', 'a2', 'a4', 'a5', 'a6', 'a9', 'a10']
+ a = ["a2", "a5", "a9", "a1", "a4", "a10", "a6"]
+ assert natsorted(a) == ["a1", "a2", "a4", "a5", "a6", "a9", "a10"]
def test_natsorted_returns_list_of_numbers_sorted_as_signed_floats_with_exponents():
- a = ['a50', 'a51.', 'a50.31', 'a-50', 'a50.4', 'a5.034e1', 'a50.300']
- assert natsorted(a, alg=ns.REAL) == ['a-50', 'a50', 'a50.300', 'a50.31', 'a5.034e1', 'a50.4', 'a51.']
+ a = ["a50", "a51.", "a50.31", "a-50", "a50.4", "a5.034e1", "a50.300"]
+ assert natsorted(a, alg=ns.REAL) == [
+ "a-50",
+ "a50",
+ "a50.300",
+ "a50.31",
+ "a5.034e1",
+ "a50.4",
+ "a51.",
+ ]
def test_natsorted_returns_list_of_numbers_sorted_as_unsigned_floats_without_exponents_with_NOEXP_option():
- a = ['a50', 'a51.', 'a50.31', 'a-50', 'a50.4', 'a5.034e1', 'a50.300']
- assert natsorted(a, alg=ns.N | ns.F | ns.U) == ['a5.034e1', 'a50', 'a50.300', 'a50.31', 'a50.4', 'a51.', 'a-50']
+ a = ["a50", "a51.", "a50.31", "a-50", "a50.4", "a5.034e1", "a50.300"]
+ assert natsorted(a, alg=ns.N | ns.F | ns.U) == [
+ "a5.034e1",
+ "a50",
+ "a50.300",
+ "a50.31",
+ "a50.4",
+ "a51.",
+ "a-50",
+ ]
# UNSIGNED is default
- assert natsorted(a, alg=ns.NOEXP | ns.FLOAT) == ['a5.034e1', 'a50', 'a50.300', 'a50.31', 'a50.4', 'a51.', 'a-50']
+ assert natsorted(a, alg=ns.NOEXP | ns.FLOAT) == [
+ "a5.034e1",
+ "a50",
+ "a50.300",
+ "a50.31",
+ "a50.4",
+ "a51.",
+ "a-50",
+ ]
def test_natsorted_returns_list_of_numbers_sorted_as_unsigned_ints_with_INT_option():
- a = ['a50', 'a51.', 'a50.31', 'a-50', 'a50.4', 'a5.034e1', 'a50.300']
- assert natsorted(a, alg=ns.INT) == ['a5.034e1', 'a50', 'a50.4', 'a50.31', 'a50.300', 'a51.', 'a-50']
+ a = ["a50", "a51.", "a50.31", "a-50", "a50.4", "a5.034e1", "a50.300"]
+ assert natsorted(a, alg=ns.INT) == [
+ "a5.034e1",
+ "a50",
+ "a50.4",
+ "a50.31",
+ "a50.300",
+ "a51.",
+ "a-50",
+ ]
# INT is default
- assert natsorted(a) == ['a5.034e1', 'a50', 'a50.4', 'a50.31', 'a50.300', 'a51.', 'a-50']
+ assert natsorted(a) == [
+ "a5.034e1",
+ "a50",
+ "a50.4",
+ "a50.31",
+ "a50.300",
+ "a51.",
+ "a-50",
+ ]
def test_natsorted_returns_list_of_numbers_sorted_as_unsigned_ints_with_DIGIT_and_VERSION_option():
- a = ['a50', 'a51.', 'a50.31', 'a-50', 'a50.4', 'a5.034e1', 'a50.300']
- assert natsorted(a, alg=ns.DIGIT) == ['a5.034e1', 'a50', 'a50.4', 'a50.31', 'a50.300', 'a51.', 'a-50']
- assert natsorted(a, alg=ns.VERSION) == ['a5.034e1', 'a50', 'a50.4', 'a50.31', 'a50.300', 'a51.', 'a-50']
+ a = ["a50", "a51.", "a50.31", "a-50", "a50.4", "a5.034e1", "a50.300"]
+ assert natsorted(a, alg=ns.DIGIT) == [
+ "a5.034e1",
+ "a50",
+ "a50.4",
+ "a50.31",
+ "a50.300",
+ "a51.",
+ "a-50",
+ ]
+ assert natsorted(a, alg=ns.VERSION) == [
+ "a5.034e1",
+ "a50",
+ "a50.4",
+ "a50.31",
+ "a50.300",
+ "a51.",
+ "a-50",
+ ]
def test_natsorted_returns_list_of_numbers_sorted_as_signed_ints_with_SIGNED_option():
- a = ['a50', 'a51.', 'a50.31', 'a-50', 'a50.4', 'a5.034e1', 'a50.300']
- assert natsorted(a, alg=ns.SIGNED) == ['a-50', 'a5.034e1', 'a50', 'a50.4', 'a50.31', 'a50.300', 'a51.']
+ a = ["a50", "a51.", "a50.31", "a-50", "a50.4", "a5.034e1", "a50.300"]
+ assert natsorted(a, alg=ns.SIGNED) == [
+ "a-50",
+ "a5.034e1",
+ "a50",
+ "a50.4",
+ "a50.31",
+ "a50.300",
+ "a51.",
+ ]
def test_natsorted_returns_list_of_numbers_sorted_accounting_for_sign_with_SIGNED_option():
- a = ['a-5', 'a7', 'a+2']
- assert natsorted(a, alg=ns.SIGNED) == ['a-5', 'a+2', 'a7']
+ a = ["a-5", "a7", "a+2"]
+ assert natsorted(a, alg=ns.SIGNED) == ["a-5", "a+2", "a7"]
def test_natsorted_returns_list_of_numbers_sorted_not_accounting_for_sign_without_SIGNED_option():
- a = ['a-5', 'a7', 'a+2']
- assert natsorted(a) == ['a7', 'a+2', 'a-5']
+ a = ["a-5", "a7", "a+2"]
+ assert natsorted(a) == ["a7", "a+2", "a-5"]
def test_natsorted_returns_sorted_list_of_version_numbers_by_default_or_with_VERSION_option():
- a = ['1.9.9a', '1.11', '1.9.9b', '1.11.4', '1.10.1']
- assert natsorted(a) == ['1.9.9a', '1.9.9b', '1.10.1', '1.11', '1.11.4']
- assert natsorted(a, alg=ns.VERSION) == ['1.9.9a', '1.9.9b', '1.10.1', '1.11', '1.11.4']
+ a = ["1.9.9a", "1.11", "1.9.9b", "1.11.4", "1.10.1"]
+ assert natsorted(a) == ["1.9.9a", "1.9.9b", "1.10.1", "1.11", "1.11.4"]
+ assert natsorted(a, alg=ns.VERSION) == [
+ "1.9.9a",
+ "1.9.9b",
+ "1.10.1",
+ "1.11",
+ "1.11.4",
+ ]
def test_natsorted_returns_sorted_list_with_mixed_type_input_and_does_not_raise_TypeError_on_Python3():
# You can mix types with natsorted. This can get around the new
# 'unorderable types' issue with Python 3.
- a = [6, 4.5, '7', '2.5', 'a']
- assert natsorted(a) == ['2.5', 4.5, 6, '7', 'a']
- a = [46, '5a5b2', 'af5', '5a5-4']
- assert natsorted(a) == ['5a5-4', '5a5b2', 46, 'af5']
+ a = [6, 4.5, "7", "2.5", "a"]
+ assert natsorted(a) == ["2.5", 4.5, 6, "7", "a"]
+ a = [46, "5a5b2", "af5", "5a5-4"]
+ assert natsorted(a) == ["5a5-4", "5a5b2", 46, "af5"]
def test_natsorted_with_mixed_input_returns_sorted_results_without_error():
- a = ['0', 'Á', '2', 'Z']
- assert natsorted(a) == ['0', '2', 'Á', 'Z']
- assert natsorted(a, alg=ns.NUMAFTER) == ['Á', 'Z', '0', '2']
- a = ['2', 'ä', 'b', 1.5, 3]
- assert natsorted(a) == [1.5, '2', 3, 'ä', 'b']
- assert natsorted(a, alg=ns.NUMAFTER) == ['ä', 'b', 1.5, '2', 3]
+ a = ["0", "Á", "2", "Z"]
+ assert natsorted(a) == ["0", "2", "Á", "Z"]
+ assert natsorted(a, alg=ns.NUMAFTER) == ["Á", "Z", "0", "2"]
+ a = ["2", "ä", "b", 1.5, 3]
+ assert natsorted(a) == [1.5, "2", 3, "ä", "b"]
+ assert natsorted(a, alg=ns.NUMAFTER) == ["ä", "b", 1.5, "2", 3]
def test_natsorted_with_nan_input_returns_sorted_results_with_nan_last_with_NANLAST():
- a = ['25', 5, float('nan'), 1E40]
+ a = ["25", 5, float("nan"), 1E40]
# The slice is because NaN != NaN
- assert natsorted(a, alg=ns.NANLAST)[:3] == [5, '25', 1E40, float('nan')][:3]
+ assert natsorted(a, alg=ns.NANLAST)[:3] == [5, "25", 1E40, float("nan")][:3]
def test_natsorted_with_nan_input_returns_sorted_results_with_nan_first_without_NANLAST():
- a = ['25', 5, float('nan'), 1E40]
+ a = ["25", 5, float("nan"), 1E40]
# The slice is because NaN != NaN
- assert natsorted(a)[1:] == [float('nan'), 5, '25', 1E40][1:]
+ assert natsorted(a)[1:] == [float("nan"), 5, "25", 1E40][1:]
def test_natsorted_with_mixed_input_raises_TypeError_if_bytes_type_is_involved_on_Python3():
if PY_VERSION >= 3:
with raises(TypeError) as e:
- assert natsorted(['ä', b'b'])
- assert 'bytes' in str(e.value)
+ assert natsorted(["ä", b"b"])
+ assert "bytes" in str(e.value)
else:
assert True
@@ -116,177 +180,352 @@ def test_natsorted_raises_ValueError_for_non_iterable_input():
def test_natsorted_recursivley_applies_key_to_nested_lists_to_return_sorted_nested_list():
- data = [['a1', 'a5'], ['a1', 'a40'], ['a10', 'a1'], ['a2', 'a5']]
- assert natsorted(data) == [['a1', 'a5'], ['a1', 'a40'], ['a2', 'a5'], ['a10', 'a1']]
+ data = [["a1", "a5"], ["a1", "a40"], ["a10", "a1"], ["a2", "a5"]]
+ assert natsorted(data) == [["a1", "a5"], ["a1", "a40"], ["a2", "a5"], ["a10", "a1"]]
def test_natsorted_applies_key_to_each_list_element_before_sorting_list():
- b = [('a', 'num3'), ('b', 'num5'), ('c', 'num2')]
- assert natsorted(b, key=itemgetter(1)) == [('c', 'num2'), ('a', 'num3'), ('b', 'num5')]
+ b = [("a", "num3"), ("b", "num5"), ("c", "num2")]
+ assert natsorted(b, key=itemgetter(1)) == [
+ ("c", "num2"),
+ ("a", "num3"),
+ ("b", "num5"),
+ ]
def test_natsorted_returns_list_in_reversed_order_with_reverse_option():
- a = ['a50', 'a51.', 'a50.31', 'a50.4', 'a5.034e1', 'a50.300']
+ a = ["a50", "a51.", "a50.31", "a50.4", "a5.034e1", "a50.300"]
assert natsorted(a, reverse=True) == natsorted(a)[::-1]
def test_natsorted_sorts_OS_generated_paths_incorrectly_without_PATH_option():
- a = ['/p/Folder (10)/file.tar.gz',
- '/p/Folder/file.tar.gz',
- '/p/Folder (1)/file (1).tar.gz',
- '/p/Folder (1)/file.tar.gz']
- assert natsorted(a) == ['/p/Folder (1)/file (1).tar.gz',
- '/p/Folder (1)/file.tar.gz',
- '/p/Folder (10)/file.tar.gz',
- '/p/Folder/file.tar.gz']
+ a = [
+ "/p/Folder (10)/file.tar.gz",
+ "/p/Folder/file.tar.gz",
+ "/p/Folder (1)/file (1).tar.gz",
+ "/p/Folder (1)/file.tar.gz",
+ ]
+ assert natsorted(a) == [
+ "/p/Folder (1)/file (1).tar.gz",
+ "/p/Folder (1)/file.tar.gz",
+ "/p/Folder (10)/file.tar.gz",
+ "/p/Folder/file.tar.gz",
+ ]
def test_natsorted_sorts_OS_generated_paths_correctly_with_PATH_option():
- a = ['/p/Folder (10)/file.tar.gz',
- '/p/Folder/file.tar.gz',
- '/p/Folder (1)/file (1).tar.gz',
- '/p/Folder (1)/file.tar.gz']
- assert natsorted(a, alg=ns.PATH) == ['/p/Folder/file.tar.gz',
- '/p/Folder (1)/file.tar.gz',
- '/p/Folder (1)/file (1).tar.gz',
- '/p/Folder (10)/file.tar.gz']
+ a = [
+ "/p/Folder (10)/file.tar.gz",
+ "/p/Folder/file.tar.gz",
+ "/p/Folder (1)/file (1).tar.gz",
+ "/p/Folder (1)/file.tar.gz",
+ ]
+ assert natsorted(a, alg=ns.PATH) == [
+ "/p/Folder/file.tar.gz",
+ "/p/Folder (1)/file.tar.gz",
+ "/p/Folder (1)/file (1).tar.gz",
+ "/p/Folder (10)/file.tar.gz",
+ ]
def test_natsorted_can_handle_sorting_paths_and_numbers_with_PATH():
# You can sort paths and numbers, not that you'd want to
- a = ['/Folder (9)/file.exe', 43]
- assert natsorted(a, alg=ns.PATH) == [43, '/Folder (9)/file.exe']
+ a = ["/Folder (9)/file.exe", 43]
+ assert natsorted(a, alg=ns.PATH) == [43, "/Folder (9)/file.exe"]
def test_natsorted_returns_results_in_ASCII_order_with_no_case_options():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- assert natsorted(a) == ['Apple', 'Banana', 'Corn', 'apple', 'banana', 'corn']
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ assert natsorted(a) == ["Apple", "Banana", "Corn", "apple", "banana", "corn"]
def test_natsorted_returns_results_sorted_by_lowercase_ASCII_order_with_IGNORECASE():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- assert natsorted(a, alg=ns.IGNORECASE) == ['Apple', 'apple', 'Banana', 'banana', 'corn', 'Corn']
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ assert natsorted(a, alg=ns.IGNORECASE) == [
+ "Apple",
+ "apple",
+ "Banana",
+ "banana",
+ "corn",
+ "Corn",
+ ]
def test_natsorted_returns_results_in_ASCII_order_but_with_lowercase_letters_first_with_LOWERCASEFIRST():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- assert natsorted(a, alg=ns.LOWERCASEFIRST) == ['apple', 'banana', 'corn', 'Apple', 'Banana', 'Corn']
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ assert natsorted(a, alg=ns.LOWERCASEFIRST) == [
+ "apple",
+ "banana",
+ "corn",
+ "Apple",
+ "Banana",
+ "Corn",
+ ]
def test_natsorted_returns_results_with_uppercase_and_lowercase_letters_grouped_together_with_GROUPLETTERS():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- assert natsorted(a, alg=ns.GROUPLETTERS) == ['Apple', 'apple', 'Banana', 'banana', 'Corn', 'corn']
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ assert natsorted(a, alg=ns.GROUPLETTERS) == [
+ "Apple",
+ "apple",
+ "Banana",
+ "banana",
+ "Corn",
+ "corn",
+ ]
def test_natsorted_returns_results_in_natural_order_with_GROUPLETTERS_and_LOWERCASEFIRST():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- assert natsorted(a, alg=ns.G | ns.LF) == ['apple', 'Apple', 'banana', 'Banana', 'corn', 'Corn']
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ assert natsorted(a, alg=ns.G | ns.LF) == [
+ "apple",
+ "Apple",
+ "banana",
+ "Banana",
+ "corn",
+ "Corn",
+ ]
def test_natsorted_places_uppercase_letters_before_lowercase_letters_for_nested_input():
- b = [('A5', 'a6'), ('a3', 'a1')]
- assert natsorted(b) == [('A5', 'a6'), ('a3', 'a1')]
+ b = [("A5", "a6"), ("a3", "a1")]
+ assert natsorted(b) == [("A5", "a6"), ("a3", "a1")]
def test_natsorted_with_LOWERCASEFIRST_places_lowercase_letters_before_uppercase_letters_for_nested_input():
- b = [('A5', 'a6'), ('a3', 'a1')]
- assert natsorted(b, alg=ns.LOWERCASEFIRST) == [('a3', 'a1'), ('A5', 'a6')]
+ b = [("A5", "a6"), ("a3", "a1")]
+ assert natsorted(b, alg=ns.LOWERCASEFIRST) == [("a3", "a1"), ("A5", "a6")]
def test_natsorted_with_IGNORECASE_sorts_without_regard_to_case_for_nested_input():
- b = [('A5', 'a6'), ('a3', 'a1')]
- assert natsorted(b, alg=ns.IGNORECASE) == [('a3', 'a1'), ('A5', 'a6')]
+ b = [("A5", "a6"), ("a3", "a1")]
+ assert natsorted(b, alg=ns.IGNORECASE) == [("a3", "a1"), ("A5", "a6")]
def test_natsorted_with_LOCALE_returns_results_sorted_by_lowercase_first_and_grouped_letters():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- load_locale('en_US')
- assert natsorted(a, alg=ns.LOCALE) == ['apple', 'Apple', 'banana', 'Banana', 'corn', 'Corn']
- locale.setlocale(locale.LC_ALL, str(''))
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ load_locale("en_US")
+ assert natsorted(a, alg=ns.LOCALE) == [
+ "apple",
+ "Apple",
+ "banana",
+ "Banana",
+ "corn",
+ "Corn",
+ ]
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsorted_with_LOCALE_and_CAPITALFIRST_returns_results_sorted_by_capital_first_and_ungrouped():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- load_locale('en_US')
- assert natsorted(a, alg=ns.LOCALE | ns.CAPITALFIRST) == ['Apple', 'Banana', 'Corn', 'apple', 'banana', 'corn']
- locale.setlocale(locale.LC_ALL, str(''))
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ load_locale("en_US")
+ assert natsorted(a, alg=ns.LOCALE | ns.CAPITALFIRST) == [
+ "Apple",
+ "Banana",
+ "Corn",
+ "apple",
+ "banana",
+ "corn",
+ ]
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsorted_with_LOCALE_and_LOWERCASEFIRST_returns_results_sorted_by_uppercase_first_and_grouped_letters():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- load_locale('en_US')
- assert natsorted(a, alg=ns.LOCALE | ns.LOWERCASEFIRST) == ['Apple', 'apple', 'Banana', 'banana', 'Corn', 'corn']
- locale.setlocale(locale.LC_ALL, str(''))
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ load_locale("en_US")
+ assert natsorted(a, alg=ns.LOCALE | ns.LOWERCASEFIRST) == [
+ "Apple",
+ "apple",
+ "Banana",
+ "banana",
+ "Corn",
+ "corn",
+ ]
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsorted_with_LOCALE_and_CAPITALFIRST_and_LOWERCASE_returns_results_sorted_by_capital_last_and_ungrouped():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
- load_locale('en_US')
- assert natsorted(a, alg=ns.LOCALE | ns.CAPITALFIRST | ns.LOWERCASEFIRST) == ['apple', 'banana', 'corn', 'Apple', 'Banana', 'Corn']
- locale.setlocale(locale.LC_ALL, str(''))
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
+ load_locale("en_US")
+ assert natsorted(a, alg=ns.LOCALE | ns.CAPITALFIRST | ns.LOWERCASEFIRST) == [
+ "apple",
+ "banana",
+ "corn",
+ "Apple",
+ "Banana",
+ "Corn",
+ ]
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsorted_with_LOCALE_and_en_setting_returns_results_sorted_by_en_language():
- load_locale('en_US')
- a = ['c', 'a5,467.86', 'ä', 'b', 'a5367.86', 'a5,6', 'a5,50']
- assert natsorted(a, alg=ns.LOCALE | ns.F) == ['a5,6', 'a5,50', 'a5367.86', 'a5,467.86', 'ä', 'b', 'c']
- locale.setlocale(locale.LC_ALL, str(''))
-
-
-@pytest.mark.skipif(not has_locale_de_DE, reason='requires de_DE locale and working locale')
+ load_locale("en_US")
+ a = ["c", "a5,467.86", "ä", "b", "a5367.86", "a5,6", "a5,50"]
+ assert natsorted(a, alg=ns.LOCALE | ns.F) == [
+ "a5,6",
+ "a5,50",
+ "a5367.86",
+ "a5,467.86",
+ "ä",
+ "b",
+ "c",
+ ]
+ locale.setlocale(locale.LC_ALL, str(""))
+
+
+@pytest.mark.skipif(
+ not has_locale_de_DE, reason="requires de_DE locale and working locale"
+)
def test_natsorted_with_LOCALE_and_de_setting_returns_results_sorted_by_de_language():
- load_locale('de_DE')
- a = ['c', 'a5.467,86', 'ä', 'b', 'a5367.86', 'a5,6', 'a5,50']
- assert natsorted(a, alg=ns.LOCALE | ns.F) == ['a5,50', 'a5,6', 'a5367.86', 'a5.467,86', 'ä', 'b', 'c']
- locale.setlocale(locale.LC_ALL, str(''))
+ load_locale("de_DE")
+ a = ["c", "a5.467,86", "ä", "b", "a5367.86", "a5,6", "a5,50"]
+ assert natsorted(a, alg=ns.LOCALE | ns.F) == [
+ "a5,50",
+ "a5,6",
+ "a5367.86",
+ "a5.467,86",
+ "ä",
+ "b",
+ "c",
+ ]
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsorted_with_LOCALE_and_mixed_input_returns_sorted_results_without_error():
- load_locale('en_US')
- a = ['0', 'Á', '2', 'Z']
- assert natsorted(a, alg=ns.LOCALE) == ['0', '2', 'Á', 'Z']
- assert natsorted(a, alg=ns.LOCALE | ns.NUMAFTER) == ['Á', 'Z', '0', '2']
- a = ['2', 'ä', 'b', 1.5, 3]
- assert natsorted(a, alg=ns.LOCALE) == [1.5, '2', 3, 'ä', 'b']
- assert natsorted(a, alg=ns.LOCALE | ns.NUMAFTER) == ['ä', 'b', 1.5, '2', 3]
- locale.setlocale(locale.LC_ALL, str(''))
+ load_locale("en_US")
+ a = ["0", "Á", "2", "Z"]
+ assert natsorted(a, alg=ns.LOCALE) == ["0", "2", "Á", "Z"]
+ assert natsorted(a, alg=ns.LOCALE | ns.NUMAFTER) == ["Á", "Z", "0", "2"]
+ a = ["2", "ä", "b", 1.5, 3]
+ assert natsorted(a, alg=ns.LOCALE) == [1.5, "2", 3, "ä", "b"]
+ assert natsorted(a, alg=ns.LOCALE | ns.NUMAFTER) == ["ä", "b", 1.5, "2", 3]
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsorted_with_LOCALE_and_UNGROUPLETTERS_and_mixed_input_returns_sorted_results_without_error():
- load_locale('en_US')
- a = ['0', 'Á', '2', 'Z']
- assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS) == ['0', '2', 'Á', 'Z']
- assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == ['Á', 'Z', '0', '2']
- a = ['2', 'ä', 'b', 1.5, 3]
- assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS) == [1.5, '2', 3, 'ä', 'b']
- assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == ['ä', 'b', 1.5, '2', 3]
- locale.setlocale(locale.LC_ALL, str(''))
+ load_locale("en_US")
+ a = ["0", "Á", "2", "Z"]
+ assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS) == ["0", "2", "Á", "Z"]
+ assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == [
+ "Á",
+ "Z",
+ "0",
+ "2",
+ ]
+ a = ["2", "ä", "b", 1.5, 3]
+ assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS) == [1.5, "2", 3, "ä", "b"]
+ assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == [
+ "ä",
+ "b",
+ 1.5,
+ "2",
+ 3,
+ ]
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsorted_with_PATH_and_LOCALE_and_UNGROUPLETTERS_and_mixed_input_returns_sorted_results_without_error():
- load_locale('en_US')
- a = ['0', 'Á', '2', 'Z']
- assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS) == ['0', '2', 'Á', 'Z']
- assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == ['Á', 'Z', '0', '2']
- a = ['2', 'ä', 'b', 1.5, 3]
- assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS) == [1.5, '2', 3, 'ä', 'b']
- assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == ['ä', 'b', 1.5, '2', 3]
- locale.setlocale(locale.LC_ALL, str(''))
+ load_locale("en_US")
+ a = ["0", "Á", "2", "Z"]
+ assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS) == [
+ "0",
+ "2",
+ "Á",
+ "Z",
+ ]
+ assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == [
+ "Á",
+ "Z",
+ "0",
+ "2",
+ ]
+ a = ["2", "ä", "b", 1.5, 3]
+ assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS) == [
+ 1.5,
+ "2",
+ 3,
+ "ä",
+ "b",
+ ]
+ assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == [
+ "ä",
+ "b",
+ 1.5,
+ "2",
+ 3,
+ ]
+ locale.setlocale(locale.LC_ALL, str(""))
def test_natsorted_sorts_an_odd_collection_of_string():
- a = ['Corn', 'apple', 'Banana', '73', 'Apple', '5039', 'corn', '~~~~~~', 'banana']
- assert natsorted(a) == ['73', '5039', 'Apple', 'Banana', 'Corn',
- 'apple', 'banana', 'corn', '~~~~~~']
- assert natsorted(a, alg=ns.NUMAFTER) == ['Apple', 'Banana', 'Corn',
- 'apple', 'banana', 'corn', '~~~~~~', '73', '5039']
+ a = ["Corn", "apple", "Banana", "73", "Apple", "5039", "corn", "~~~~~~", "banana"]
+ assert natsorted(a) == [
+ "73",
+ "5039",
+ "Apple",
+ "Banana",
+ "Corn",
+ "apple",
+ "banana",
+ "corn",
+ "~~~~~~",
+ ]
+ assert natsorted(a, alg=ns.NUMAFTER) == [
+ "Apple",
+ "Banana",
+ "Corn",
+ "apple",
+ "banana",
+ "corn",
+ "~~~~~~",
+ "73",
+ "5039",
+ ]
def test_natsorted_sorts_mixed_ascii_and_non_ascii_numbers():
- a = ['1st street', '10th street', '2nd street', '2 street', '1 street', '1street',
- '11 street', 'street 2', 'street 1', 'Street 11', '۲ street', '۱ street', '۱street',
- '۱۲street', '۱۱ street', 'street ۲', 'street ۱', 'street ۱', 'street ۱۲', 'street ۱۱']
- expected = ['1 street', '۱ street', '1st street', '1street', '۱street', '2 street', '۲ street',
- '2nd street', '10th street', '11 street', '۱۱ street', '۱۲street', 'street 1',
- 'street ۱', 'street ۱', 'street 2', 'street ۲', 'Street 11', 'street ۱۱', 'street ۱۲']
+ a = [
+ "1st street",
+ "10th street",
+ "2nd street",
+ "2 street",
+ "1 street",
+ "1street",
+ "11 street",
+ "street 2",
+ "street 1",
+ "Street 11",
+ "۲ street",
+ "۱ street",
+ "۱street",
+ "۱۲street",
+ "۱۱ street",
+ "street ۲",
+ "street ۱",
+ "street ۱",
+ "street ۱۲",
+ "street ۱۱",
+ ]
+ expected = [
+ "1 street",
+ "۱ street",
+ "1st street",
+ "1street",
+ "۱street",
+ "2 street",
+ "۲ street",
+ "2nd street",
+ "10th street",
+ "11 street",
+ "۱۱ street",
+ "۱۲street",
+ "street 1",
+ "street ۱",
+ "street ۱",
+ "street 2",
+ "street ۲",
+ "Street 11",
+ "street ۱۱",
+ "street ۱۲",
+ ]
assert natsorted(a, alg=ns.IGNORECASE) == expected
diff --git a/test_natsort/test_natsorted_convenience.py b/test_natsort/test_natsorted_convenience.py
index 9e04493..850b6ff 100644
--- a/test_natsort/test_natsorted_convenience.py
+++ b/test_natsort/test_natsorted_convenience.py
@@ -24,10 +24,10 @@ from natsort import (
def test_decoder_returns_function_that_can_decode_bytes_but_return_non_bytes_as_is():
- f = decoder('latin1')
- a = 'bytes'
+ f = decoder("latin1")
+ a = "bytes"
b = 14
- assert f(b'bytes') == a
+ assert f(b"bytes") == a
assert f(b) is b # returns as-is, same object ID
if PY_VERSION >= 3:
assert f(a) is a # same object returned on Python3 b/c only bytes has decode
@@ -37,90 +37,88 @@ def test_decoder_returns_function_that_can_decode_bytes_but_return_non_bytes_as_
def test_as_ascii_returns_bytes_as_ascii():
- assert decoder('ascii')(b'bytes') == as_ascii(b'bytes')
+ assert decoder("ascii")(b"bytes") == as_ascii(b"bytes")
def test_as_utf8_returns_bytes_as_utf8():
- assert decoder('utf8')(b'bytes') == as_utf8(b'bytes')
+ assert decoder("utf8")(b"bytes") == as_utf8(b"bytes")
def test_versorted_returns_results_identical_to_natsorted():
- a = ['1.9.9a', '1.11', '1.9.9b', '1.11.4', '1.10.1']
+ a = ["1.9.9a", "1.11", "1.9.9b", "1.11.4", "1.10.1"]
# versorted is retained for backwards compatibility
assert versorted(a) == natsorted(a)
def test_realsorted_returns_results_identical_to_natsorted_with_REAL():
- a = ['a50', 'a51.', 'a50.31', 'a-50', 'a50.4', 'a5.034e1', 'a50.300']
+ a = ["a50", "a51.", "a50.31", "a-50", "a50.4", "a5.034e1", "a50.300"]
assert realsorted(a) == natsorted(a, alg=ns.REAL)
def test_humansorted_returns_results_identical_to_natsorted_with_LOCALE():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
assert humansorted(a) == natsorted(a, alg=ns.LOCALE)
def test_index_natsorted_returns_integer_list_of_sort_order_for_input_list():
- a = ['num3', 'num5', 'num2']
- b = ['foo', 'bar', 'baz']
+ a = ["num3", "num5", "num2"]
+ b = ["foo", "bar", "baz"]
index = index_natsorted(a)
assert index == [2, 0, 1]
- assert [a[i] for i in index] == ['num2', 'num3', 'num5']
- assert [b[i] for i in index] == ['baz', 'foo', 'bar']
+ assert [a[i] for i in index] == ["num2", "num3", "num5"]
+ assert [b[i] for i in index] == ["baz", "foo", "bar"]
def test_index_natsorted_returns_reversed_integer_list_of_sort_order_for_input_list_with_reverse_option():
- a = ['num3', 'num5', 'num2']
+ a = ["num3", "num5", "num2"]
assert index_natsorted(a, reverse=True) == [1, 0, 2]
def test_index_natsorted_applies_key_function_before_sorting():
- c = [('a', 'num3'), ('b', 'num5'), ('c', 'num2')]
+ c = [("a", "num3"), ("b", "num5"), ("c", "num2")]
assert index_natsorted(c, key=itemgetter(1)) == [2, 0, 1]
def test_index_natsorted_handles_unorderable_types_error_on_Python3():
- a = [46, '5a5b2', 'af5', '5a5-4']
+ a = [46, "5a5b2", "af5", "5a5-4"]
assert index_natsorted(a) == [3, 1, 0, 2]
def test_index_natsorted_returns_integer_list_of_nested_input_list():
- data = [['a1', 'a5'], ['a1', 'a40'], ['a10', 'a1'], ['a2', 'a5']]
+ data = [["a1", "a5"], ["a1", "a40"], ["a10", "a1"], ["a2", "a5"]]
assert index_natsorted(data) == [0, 1, 3, 2]
def test_index_natsorted_returns_integer_list_in_proper_order_for_input_paths_with_PATH():
- a = ['/p/Folder (10)/',
- '/p/Folder/',
- '/p/Folder (1)/']
+ a = ["/p/Folder (10)/", "/p/Folder/", "/p/Folder (1)/"]
assert index_natsorted(a, alg=ns.PATH) == [1, 2, 0]
def test_index_versorted_returns_results_identical_to_index_natsorted():
- a = ['1.9.9a', '1.11', '1.9.9b', '1.11.4', '1.10.1']
+ a = ["1.9.9a", "1.11", "1.9.9b", "1.11.4", "1.10.1"]
# index_versorted is retained for backwards compatibility
assert index_versorted(a) == index_natsorted(a)
def test_index_realsorted_returns_results_identical_to_index_natsorted_with_REAL():
- a = ['a50', 'a51.', 'a50.31', 'a-50', 'a50.4', 'a5.034e1', 'a50.300']
+ a = ["a50", "a51.", "a50.31", "a-50", "a50.4", "a5.034e1", "a50.300"]
assert index_realsorted(a) == index_natsorted(a, alg=ns.REAL)
def test_index_humansorted_returns_results_identical_to_index_natsorted_with_LOCALE():
- a = ['Apple', 'corn', 'Corn', 'Banana', 'apple', 'banana']
+ a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
assert index_humansorted(a) == index_natsorted(a, alg=ns.LOCALE)
def test_order_by_index_sorts_list_according_to_order_of_integer_list():
- a = ['num3', 'num5', 'num2']
+ a = ["num3", "num5", "num2"]
index = [2, 0, 1]
- assert order_by_index(a, index) == ['num2', 'num3', 'num5']
+ assert order_by_index(a, index) == ["num2", "num3", "num5"]
assert order_by_index(a, index) == [a[i] for i in index]
def test_order_by_index_returns_generator_with_iter_True():
- a = ['num3', 'num5', 'num2']
+ a = ["num3", "num5", "num2"]
index = [2, 0, 1]
assert order_by_index(a, index, True) != [a[i] for i in index]
assert list(order_by_index(a, index, True)) == [a[i] for i in index]
diff --git a/test_natsort/test_parse_bytes_function.py b/test_natsort/test_parse_bytes_function.py
index a0ab3f8..602aa80 100644
--- a/test_natsort/test_parse_bytes_function.py
+++ b/test_natsort/test_parse_bytes_function.py
@@ -13,7 +13,7 @@ from hypothesis.strategies import binary
def test_parse_bytes_factory_makes_function_that_returns_tuple_example():
- assert _parse_bytes_factory(0)(b'hello') == (b'hello',)
+ assert _parse_bytes_factory(0)(b"hello") == (b"hello",)
@given(binary())
@@ -22,16 +22,18 @@ def test_parse_bytes_factory_makes_function_that_returns_tuple(x):
def test_parse_bytes_factory_with_IGNORECASE_makes_function_that_returns_tuple_with_lowercase_example():
- assert _parse_bytes_factory(ns.IGNORECASE)(b'HelLo') == (b'hello',)
+ assert _parse_bytes_factory(ns.IGNORECASE)(b"HelLo") == (b"hello",)
@given(binary())
-def test_parse_bytes_factory_with_IGNORECASE_makes_function_that_returns_tuple_with_lowercase(x):
+def test_parse_bytes_factory_with_IGNORECASE_makes_function_that_returns_tuple_with_lowercase(
+ x
+):
assert _parse_bytes_factory(ns.IGNORECASE)(x) == (x.lower(),)
def test_parse_bytes_factory_with_PATH_makes_function_that_returns_nested_tuple_example():
- assert _parse_bytes_factory(ns.PATH)(b'hello') == ((b'hello',),)
+ assert _parse_bytes_factory(ns.PATH)(b"hello") == ((b"hello",),)
@given(binary())
@@ -40,9 +42,11 @@ def test_parse_bytes_factory_with_PATH_makes_function_that_returns_nested_tuple(
def test_parse_bytes_factory_with_PATH_and_IGNORECASE_makes_function_that_returns_nested_tuple_with_lowercase_example():
- assert _parse_bytes_factory(ns.PATH | ns.IGNORECASE)(b'HelLo') == ((b'hello',),)
+ assert _parse_bytes_factory(ns.PATH | ns.IGNORECASE)(b"HelLo") == ((b"hello",),)
@given(binary())
-def test_parse_bytes_factory_with_PATH_and_IGNORECASE_makes_function_that_returns_nested_tuple_with_lowercase(x):
+def test_parse_bytes_factory_with_PATH_and_IGNORECASE_makes_function_that_returns_nested_tuple_with_lowercase(
+ x
+):
assert _parse_bytes_factory(ns.PATH | ns.IGNORECASE)(x) == ((x.lower(),),)
diff --git a/test_natsort/test_parse_number_function.py b/test_natsort/test_parse_number_function.py
index 2e7a9fe..119b724 100644
--- a/test_natsort/test_parse_number_function.py
+++ b/test_natsort/test_parse_number_function.py
@@ -4,13 +4,8 @@ from __future__ import unicode_literals
from natsort.ns_enum import ns
from natsort.utils import _parse_number_factory
-from hypothesis import (
- given,
-)
-from hypothesis.strategies import (
- floats,
- integers,
-)
+from hypothesis import given
+from hypothesis.strategies import floats, integers
# Each test has an "example" version for demonstrative purposes,
@@ -18,38 +13,55 @@ from hypothesis.strategies import (
def test_parse_number_factory_makes_function_that_returns_tuple_example():
- assert _parse_number_factory(0, '', '')(57) == ('', 57)
- assert _parse_number_factory(0, '', '')(float('nan')) == ('', float('-inf'))
- assert _parse_number_factory(ns.NANLAST, '', '')(float('nan')) == ('', float('+inf'))
+ assert _parse_number_factory(0, "", "")(57) == ("", 57)
+ assert _parse_number_factory(0, "", "")(float("nan")) == ("", float("-inf"))
+ assert _parse_number_factory(ns.NANLAST, "", "")(float("nan")) == (
+ "",
+ float("+inf"),
+ )
@given(floats(allow_nan=False) | integers())
def test_parse_number_factory_makes_function_that_returns_tuple(x):
- assert _parse_number_factory(0, '', '')(x) == ('', x)
+ assert _parse_number_factory(0, "", "")(x) == ("", x)
def test_parse_number_factory_with_PATH_makes_function_that_returns_nested_tuple_example():
- assert _parse_number_factory(ns.PATH, '', '')(57) == (('', 57),)
+ assert _parse_number_factory(ns.PATH, "", "")(57) == (("", 57),)
@given(floats(allow_nan=False) | integers())
def test_parse_number_factory_with_PATH_makes_function_that_returns_nested_tuple(x):
- assert _parse_number_factory(ns.PATH, '', '')(x) == (('', x),)
+ assert _parse_number_factory(ns.PATH, "", "")(x) == (("", x),)
def test_parse_number_factory_with_UNGROUPLETTERS_LOCALE_makes_function_that_returns_nested_tuple_example():
- assert _parse_number_factory(ns.UNGROUPLETTERS | ns.LOCALE, '', 'xx')(57) == (('xx',), ('', 57))
+ assert _parse_number_factory(ns.UNGROUPLETTERS | ns.LOCALE, "", "xx")(57) == (
+ ("xx",),
+ ("", 57),
+ )
@given(floats(allow_nan=False) | integers())
-def test_parse_number_factory_with_UNGROUPLETTERS_LOCALE_makes_function_that_returns_nested_tuple(x):
- assert _parse_number_factory(ns.UNGROUPLETTERS | ns.LOCALE, '', 'xx')(x) == (('xx',), ('', x))
+def test_parse_number_factory_with_UNGROUPLETTERS_LOCALE_makes_function_that_returns_nested_tuple(
+ x
+):
+ assert _parse_number_factory(ns.UNGROUPLETTERS | ns.LOCALE, "", "xx")(x) == (
+ ("xx",),
+ ("", x),
+ )
def test_parse_number_factory_with_PATH_UNGROUPLETTERS_LOCALE_makes_function_that_returns_nested_tuple_example():
- assert _parse_number_factory(ns.PATH | ns.UNGROUPLETTERS | ns.LOCALE, '', 'xx')(57) == ((('xx',), ('', 57)),)
+ assert _parse_number_factory(ns.PATH | ns.UNGROUPLETTERS | ns.LOCALE, "", "xx")(
+ 57
+ ) == ((("xx",), ("", 57)),)
@given(floats(allow_nan=False) | integers())
-def test_parse_number_factory_with_PATH_UNGROUPLETTERS_LOCALE_makes_function_that_returns_nested_tuple(x):
- assert _parse_number_factory(ns.PATH | ns.UNGROUPLETTERS | ns.LOCALE, '', 'xx')(x) == ((('xx',), ('', x)),)
+def test_parse_number_factory_with_PATH_UNGROUPLETTERS_LOCALE_makes_function_that_returns_nested_tuple(
+ x
+):
+ assert _parse_number_factory(ns.PATH | ns.UNGROUPLETTERS | ns.LOCALE, "", "xx")(
+ x
+ ) == ((("xx",), ("", x)),)
diff --git a/test_natsort/test_parse_string_function.py b/test_natsort/test_parse_string_function.py
index 91dcf08..c8ea45b 100644
--- a/test_natsort/test_parse_string_function.py
+++ b/test_natsort/test_parse_string_function.py
@@ -15,24 +15,10 @@ from natsort.utils import (
_parse_path_factory,
)
from natsort.compat.py23 import py23_str, PY_VERSION
-from natsort.compat.fastnumbers import (
- fast_float,
- fast_int,
-)
-from slow_splitters import (
- int_splitter,
- float_splitter,
-)
-from hypothesis import (
- given,
- example,
-)
-from hypothesis.strategies import (
- lists,
- text,
- floats,
- integers,
-)
+from natsort.compat.fastnumbers import fast_float, fast_int
+from slow_splitters import int_splitter, float_splitter
+from hypothesis import given, example
+from hypothesis.strategies import lists, text, floats, integers
if PY_VERSION >= 3:
long = int
@@ -42,7 +28,7 @@ def whitespace_check(x):
"""Simplifies testing"""
try:
if x.isspace():
- return x in ' \t\n\r\f\v'
+ return x in " \t\n\r\f\v"
else:
return True
except (AttributeError, TypeError):
@@ -65,91 +51,195 @@ def tuple2(x, dummy):
def test_parse_string_factory_raises_TypeError_if_given_a_number_example():
with raises(TypeError):
- assert _parse_string_factory(0, '', _float_sign_exp_re.split, no_op, fast_float, tuple2)(50.0)
+ assert _parse_string_factory(
+ 0, "", _float_sign_exp_re.split, no_op, fast_float, tuple2
+ )(50.0)
@given(floats())
def test_parse_string_factory_raises_TypeError_if_given_a_number(x):
with raises(TypeError):
- assert _parse_string_factory(0, '', _float_sign_exp_re.split, no_op, fast_float, tuple2)(x)
+ assert _parse_string_factory(
+ 0, "", _float_sign_exp_re.split, no_op, fast_float, tuple2
+ )(x)
def test_parse_string_factory_only_parses_digits_with_nosign_int_example():
- assert _parse_string_factory(0, '', _int_nosign_re.split, no_op, fast_int, tuple2)('a5+5.034e-1') == ('a', 5, '+', 5, '.', 34, 'e-', 1)
+ assert _parse_string_factory(0, "", _int_nosign_re.split, no_op, fast_int, tuple2)(
+ "a5+5.034e-1"
+ ) == ("a", 5, "+", 5, ".", 34, "e-", 1)
-@given(lists(elements=floats() | text().filter(whitespace_check) | integers(), min_size=1, max_size=10))
-@example([10000000000000000000000000000000000000000000000000000000000000000000000000,
- 100000000000000000000000000000000000000000000000000000000000000000000000000,
- 100000000000000000000000000000000000000000000000000000000000000000000000000])
+@given(
+ lists(
+ elements=floats() | text().filter(whitespace_check) | integers(),
+ min_size=1,
+ max_size=10,
+ )
+)
+@example(
+ [
+ 10000000000000000000000000000000000000000000000000000000000000000000000000,
+ 100000000000000000000000000000000000000000000000000000000000000000000000000,
+ 100000000000000000000000000000000000000000000000000000000000000000000000000,
+ ]
+)
def test_parse_string_factory_only_parses_digits_with_nosign_int(x):
- s = ''.join(repr(y) if type(y) in (float, long, int) else y for y in x)
- assert _parse_string_factory(0, '', _int_nosign_re.split, no_op, fast_int, tuple2)(s) == int_splitter(s, False, '')
+ s = "".join(repr(y) if type(y) in (float, long, int) else y for y in x)
+ assert _parse_string_factory(0, "", _int_nosign_re.split, no_op, fast_int, tuple2)(
+ s
+ ) == int_splitter(s, False, "")
def test_parse_string_factory_parses_digit_with_sign_with_signed_int_example():
- assert _parse_string_factory(0, '', _int_sign_re.split, no_op, fast_int, tuple2)('a5+5.034e-1') == ('a', 5, '', 5, '.', 34, 'e', -1)
+ assert _parse_string_factory(0, "", _int_sign_re.split, no_op, fast_int, tuple2)(
+ "a5+5.034e-1"
+ ) == ("a", 5, "", 5, ".", 34, "e", -1)
-@given(lists(elements=floats() | text().filter(whitespace_check) | integers(), min_size=1, max_size=10))
+@given(
+ lists(
+ elements=floats() | text().filter(whitespace_check) | integers(),
+ min_size=1,
+ max_size=10,
+ )
+)
def test_parse_string_factory_parses_digit_with_sign_with_signed_int(x):
- s = ''.join(repr(y) if type(y) in (float, long, int) else y for y in x)
- assert _parse_string_factory(0, '', _int_sign_re.split, no_op, fast_int, tuple2)(s) == int_splitter(s, True, '')
+ s = "".join(repr(y) if type(y) in (float, long, int) else y for y in x)
+ assert _parse_string_factory(0, "", _int_sign_re.split, no_op, fast_int, tuple2)(
+ s
+ ) == int_splitter(s, True, "")
def test_parse_string_factory_only_parses_float_with_nosign_noexp_float_example():
- assert _parse_string_factory(0, '', _float_nosign_noexp_re.split, no_op, fast_float, tuple2)('a5+5.034e-1') == ('a', 5.0, '+', 5.034, 'e-', 1.0)
+ assert _parse_string_factory(
+ 0, "", _float_nosign_noexp_re.split, no_op, fast_float, tuple2
+ )("a5+5.034e-1") == ("a", 5.0, "+", 5.034, "e-", 1.0)
-@given(lists(elements=floats(allow_nan=False) | text().filter(whitespace_check) | integers(), min_size=1, max_size=10))
+@given(
+ lists(
+ elements=floats(allow_nan=False) | text().filter(whitespace_check) | integers(),
+ min_size=1,
+ max_size=10,
+ )
+)
def test_parse_string_factory_only_parses_float_with_nosign_noexp_float(x):
- s = ''.join(repr(y) if type(y) in (float, long, int) else y for y in x)
- assert _parse_string_factory(0, '', _float_nosign_noexp_re.split, no_op, fast_float, tuple2)(s) == float_splitter(s, False, False, '')
+ s = "".join(repr(y) if type(y) in (float, long, int) else y for y in x)
+ assert _parse_string_factory(
+ 0, "", _float_nosign_noexp_re.split, no_op, fast_float, tuple2
+ )(s) == float_splitter(s, False, False, "")
def test_parse_string_factory_only_parses_float_with_exponent_with_nosign_exp_float_example():
- assert _parse_string_factory(0, '', _float_nosign_exp_re.split, no_op, fast_float, tuple2)('a5+5.034e-1') == ('a', 5.0, '+', 0.5034)
+ assert _parse_string_factory(
+ 0, "", _float_nosign_exp_re.split, no_op, fast_float, tuple2
+ )("a5+5.034e-1") == ("a", 5.0, "+", 0.5034)
-@given(lists(elements=floats(allow_nan=False) | text().filter(whitespace_check) | integers(), min_size=1, max_size=10))
+@given(
+ lists(
+ elements=floats(allow_nan=False) | text().filter(whitespace_check) | integers(),
+ min_size=1,
+ max_size=10,
+ )
+)
def test_parse_string_factory_only_parses_float_with_exponent_with_nosign_exp_float(x):
- s = ''.join(repr(y) if type(y) in (float, long, int) else y for y in x)
- assert _parse_string_factory(0, '', _float_nosign_exp_re.split, no_op, fast_float, tuple2)(s) == float_splitter(s, False, True, '')
+ s = "".join(repr(y) if type(y) in (float, long, int) else y for y in x)
+ assert _parse_string_factory(
+ 0, "", _float_nosign_exp_re.split, no_op, fast_float, tuple2
+ )(s) == float_splitter(s, False, True, "")
def test_parse_string_factory_only_parses_float_with_sign_with_sign_noexp_float_example():
- assert _parse_string_factory(0, '', _float_sign_noexp_re.split, no_op, fast_float, tuple2)('a5+5.034e-1') == ('a', 5.0, '', 5.034, 'e', -1.0)
+ assert _parse_string_factory(
+ 0, "", _float_sign_noexp_re.split, no_op, fast_float, tuple2
+ )("a5+5.034e-1") == ("a", 5.0, "", 5.034, "e", -1.0)
-@given(lists(elements=floats(allow_nan=False) | text().filter(whitespace_check) | integers(), min_size=1, max_size=10))
+@given(
+ lists(
+ elements=floats(allow_nan=False) | text().filter(whitespace_check) | integers(),
+ min_size=1,
+ max_size=10,
+ )
+)
def test_parse_string_factory_only_parses_float_with_sign_with_sign_noexp_float(x):
- s = ''.join(repr(y) if type(y) in (float, long, int) else y for y in x)
- assert _parse_string_factory(0, '', _float_sign_noexp_re.split, no_op, fast_float, tuple2)(s) == float_splitter(s, True, False, '')
+ s = "".join(repr(y) if type(y) in (float, long, int) else y for y in x)
+ assert _parse_string_factory(
+ 0, "", _float_sign_noexp_re.split, no_op, fast_float, tuple2
+ )(s) == float_splitter(s, True, False, "")
def test_parse_string_factory_parses_float_with_sign_exp_float_example():
- assert _parse_string_factory(0, '', _float_sign_exp_re.split, no_op, fast_float, tuple2)('a5+5.034e-1') == ('a', 5.0, '', 0.5034)
- assert _parse_string_factory(0, '', _float_sign_exp_re.split, no_op, fast_float, tuple2)('6a5+5.034e-1') == ('', 6.0, 'a', 5.0, '', 0.5034)
-
-
-@given(lists(elements=floats(allow_nan=False) | text().filter(whitespace_check) | integers(), min_size=1, max_size=10))
+ assert _parse_string_factory(
+ 0, "", _float_sign_exp_re.split, no_op, fast_float, tuple2
+ )("a5+5.034e-1") == ("a", 5.0, "", 0.5034)
+ assert _parse_string_factory(
+ 0, "", _float_sign_exp_re.split, no_op, fast_float, tuple2
+ )("6a5+5.034e-1") == ("", 6.0, "a", 5.0, "", 0.5034)
+
+
+@given(
+ lists(
+ elements=floats(allow_nan=False) | text().filter(whitespace_check) | integers(),
+ min_size=1,
+ max_size=10,
+ )
+)
def test_parse_string_factory_parses_float_with_sign_exp_float(x):
- s = ''.join(repr(y) if type(y) in (float, long, int) else y for y in x)
- assert _parse_string_factory(0, '', _float_sign_exp_re.split, no_op, fast_float, tuple2)(s) == float_splitter(s, True, True, '')
+ s = "".join(repr(y) if type(y) in (float, long, int) else y for y in x)
+ assert _parse_string_factory(
+ 0, "", _float_sign_exp_re.split, no_op, fast_float, tuple2
+ )(s) == float_splitter(s, True, True, "")
def test_parse_string_factory_selects_pre_function_value_if_not_dumb():
def tuple2(x, orig):
"""Make the input a tuple."""
return (orig[0], tuple(x))
- assert _parse_string_factory(0, '', _int_nosign_re.split, py23_str.upper, fast_float, tuple2)('a5+5.034e-1') == ('A', ('A', 5, '+', 5, '.', 34, 'E-', 1))
- assert _parse_string_factory(ns._DUMB, '', _int_nosign_re.split, py23_str.upper, fast_float, tuple2)('a5+5.034e-1') == ('A', ('A', 5, '+', 5, '.', 34, 'E-', 1))
- assert _parse_string_factory(ns.LOCALE, '', _int_nosign_re.split, py23_str.upper, fast_float, tuple2)('a5+5.034e-1') == ('A', ('A', 5, '+', 5, '.', 34, 'E-', 1))
- assert _parse_string_factory(ns.LOCALE | ns._DUMB, '', _int_nosign_re.split, py23_str.upper, fast_float, tuple2)('a5+5.034e-1') == ('a', ('A', 5, '+', 5, '.', 34, 'E-', 1))
+
+ assert _parse_string_factory(
+ 0, "", _int_nosign_re.split, py23_str.upper, fast_float, tuple2
+ )("a5+5.034e-1") == ("A", ("A", 5, "+", 5, ".", 34, "E-", 1))
+ assert _parse_string_factory(
+ ns._DUMB, "", _int_nosign_re.split, py23_str.upper, fast_float, tuple2
+ )("a5+5.034e-1") == ("A", ("A", 5, "+", 5, ".", 34, "E-", 1))
+ assert _parse_string_factory(
+ ns.LOCALE, "", _int_nosign_re.split, py23_str.upper, fast_float, tuple2
+ )("a5+5.034e-1") == ("A", ("A", 5, "+", 5, ".", 34, "E-", 1))
+ assert _parse_string_factory(
+ ns.LOCALE | ns._DUMB,
+ "",
+ _int_nosign_re.split,
+ py23_str.upper,
+ fast_float,
+ tuple2,
+ )("a5+5.034e-1") == ("a", ("A", 5, "+", 5, ".", 34, "E-", 1))
def test_parse_path_function_parses_string_as_path_then_as_string():
- splt = _parse_string_factory(0, '', _float_sign_exp_re.split, no_op, fast_float, tuple2)
- assert _parse_path_factory(splt)('/p/Folder (10)/file34.5nm (2).tar.gz') == (('/',), ('p',), ('Folder (', 10.0, ')',), ('file', 34.5, 'nm (', 2.0, ')'), ('.tar',), ('.gz',))
- assert _parse_path_factory(splt)('../Folder (10)/file (2).tar.gz') == (('..',), ('Folder (', 10.0, ')',), ('file (', 2.0, ')'), ('.tar',), ('.gz',))
- assert _parse_path_factory(splt)('Folder (10)/file.f34.5nm (2).tar.gz') == (('Folder (', 10.0, ')',), ('file.f', 34.5, 'nm (', 2.0, ')'), ('.tar',), ('.gz',))
+ splt = _parse_string_factory(
+ 0, "", _float_sign_exp_re.split, no_op, fast_float, tuple2
+ )
+ assert _parse_path_factory(splt)("/p/Folder (10)/file34.5nm (2).tar.gz") == (
+ ("/",),
+ ("p",),
+ ("Folder (", 10.0, ")"),
+ ("file", 34.5, "nm (", 2.0, ")"),
+ (".tar",),
+ (".gz",),
+ )
+ assert _parse_path_factory(splt)("../Folder (10)/file (2).tar.gz") == (
+ ("..",),
+ ("Folder (", 10.0, ")"),
+ ("file (", 2.0, ")"),
+ (".tar",),
+ (".gz",),
+ )
+ assert _parse_path_factory(splt)("Folder (10)/file.f34.5nm (2).tar.gz") == (
+ ("Folder (", 10.0, ")"),
+ ("file.f", 34.5, "nm (", 2.0, ")"),
+ (".tar",),
+ (".gz",),
+ )
diff --git a/test_natsort/test_string_component_transform_factory.py b/test_natsort/test_string_component_transform_factory.py
index 4f419d7..41c7ecb 100644
--- a/test_natsort/test_string_component_transform_factory.py
+++ b/test_natsort/test_string_component_transform_factory.py
@@ -3,29 +3,17 @@
from __future__ import unicode_literals
from natsort.ns_enum import ns
-from natsort.utils import (
- _string_component_transform_factory,
- _groupletters,
-)
+from natsort.utils import _string_component_transform_factory, _groupletters
from natsort.compat.py23 import py23_str
from natsort.compat.locale import get_strxfrm
-from natsort.compat.fastnumbers import (
- fast_float,
- fast_int,
-)
-from hypothesis import (
- given,
-)
-from hypothesis.strategies import (
- text,
- floats,
- integers,
-)
+from natsort.compat.fastnumbers import fast_float, fast_int
+from hypothesis import given
+from hypothesis.strategies import text, floats, integers
from compat.locale import bad_uni_chars
def no_null(x):
- return '\0' not in x
+ return "\0" not in x
# Each test has an "example" version for demonstrative purposes,
@@ -33,9 +21,9 @@ def no_null(x):
def test_string_component_transform_factory_returns_fast_int_example():
- x = 'hello'
+ x = "hello"
assert _string_component_transform_factory(0)(x) is fast_int(x)
- assert _string_component_transform_factory(0)('5007') == fast_int('5007')
+ assert _string_component_transform_factory(0)("5007") == fast_int("5007")
@given(text().filter(bool) | floats() | integers())
@@ -44,67 +32,102 @@ def test_string_component_transform_factory_returns_fast_int(x):
def test_string_component_transform_factory_with_FLOAT_returns_fast_float_example():
- x = 'hello'
+ x = "hello"
assert _string_component_transform_factory(ns.FLOAT)(x) is fast_float(x)
- assert _string_component_transform_factory(ns.FLOAT)('5007') == fast_float('5007')
+ assert _string_component_transform_factory(ns.FLOAT)("5007") == fast_float("5007")
@given(text().filter(bool) | floats() | integers())
def test_string_component_transform_factory_with_FLOAT_returns_fast_float(x):
- assert _string_component_transform_factory(ns.FLOAT)(py23_str(x)) == fast_float(py23_str(x), nan=float('-inf'))
+ assert _string_component_transform_factory(ns.FLOAT)(py23_str(x)) == fast_float(
+ py23_str(x), nan=float("-inf")
+ )
def test_string_component_transform_factory_with_FLOAT_returns_fast_float_with_neg_inf_replacing_nan():
- assert _string_component_transform_factory(ns.FLOAT)('nan') == fast_float('nan', nan=float('-inf'))
+ assert _string_component_transform_factory(ns.FLOAT)("nan") == fast_float(
+ "nan", nan=float("-inf")
+ )
def test_string_component_transform_factory_with_FLOAT_and_NANLAST_returns_fast_float_with_pos_inf_replacing_nan():
- assert _string_component_transform_factory(ns.FLOAT | ns.NANLAST)('nan') == fast_float('nan', nan=float('+inf'))
+ assert _string_component_transform_factory(ns.FLOAT | ns.NANLAST)(
+ "nan"
+ ) == fast_float("nan", nan=float("+inf"))
def test_string_component_transform_factory_with_GROUPLETTERS_returns_fast_int_and_groupletters_example():
- x = 'hello'
- assert _string_component_transform_factory(ns.GROUPLETTERS)(x) == fast_int(x, key=_groupletters)
+ x = "hello"
+ assert _string_component_transform_factory(ns.GROUPLETTERS)(x) == fast_int(
+ x, key=_groupletters
+ )
@given(text().filter(bool))
-def test_string_component_transform_factory_with_GROUPLETTERS_returns_fast_int_and_groupletters(x):
- assert _string_component_transform_factory(ns.GROUPLETTERS)(x) == fast_int(x, key=_groupletters)
+def test_string_component_transform_factory_with_GROUPLETTERS_returns_fast_int_and_groupletters(
+ x
+):
+ assert _string_component_transform_factory(ns.GROUPLETTERS)(x) == fast_int(
+ x, key=_groupletters
+ )
def test_string_component_transform_factory_with_LOCALE_returns_fast_int_and_groupletters_example():
- x = 'hello'
- assert _string_component_transform_factory(ns.LOCALE)(x) == fast_int(x, key=get_strxfrm())
+ x = "hello"
+ assert _string_component_transform_factory(ns.LOCALE)(x) == fast_int(
+ x, key=get_strxfrm()
+ )
-@given(text().filter(bool).filter(lambda x: not any(y in bad_uni_chars for y in x)).filter(no_null))
-def test_string_component_transform_factory_with_LOCALE_returns_fast_int_and_groupletters(x):
- assert _string_component_transform_factory(ns.LOCALE)(x) == fast_int(x, key=get_strxfrm())
+@given(
+ text()
+ .filter(bool)
+ .filter(lambda x: not any(y in bad_uni_chars for y in x))
+ .filter(no_null)
+)
+def test_string_component_transform_factory_with_LOCALE_returns_fast_int_and_groupletters(
+ x
+):
+ assert _string_component_transform_factory(ns.LOCALE)(x) == fast_int(
+ x, key=get_strxfrm()
+ )
def test_string_component_transform_factory_with_LOCALE_and_GROUPLETTERS_returns_fast_int_and_groupletters_and_locale_convert_example():
- x = 'hello'
- assert _string_component_transform_factory(ns.GROUPLETTERS | ns.LOCALE)(x) == fast_int(x, key=lambda x: get_strxfrm()(_groupletters(x)))
+ x = "hello"
+ assert _string_component_transform_factory(ns.GROUPLETTERS | ns.LOCALE)(
+ x
+ ) == fast_int(x, key=lambda x: get_strxfrm()(_groupletters(x)))
@given(text().filter(bool).filter(no_null))
-def test_string_component_transform_factory_with_LOCALE_and_GROUPLETTERS_returns_fast_int_and_groupletters_and_locale_convert(x):
+def test_string_component_transform_factory_with_LOCALE_and_GROUPLETTERS_returns_fast_int_and_groupletters_and_locale_convert(
+ x
+):
try:
- assert _string_component_transform_factory(ns.GROUPLETTERS | ns.LOCALE)(x) == fast_int(x, key=lambda x: get_strxfrm()(_groupletters(x)))
+ assert _string_component_transform_factory(ns.GROUPLETTERS | ns.LOCALE)(
+ x
+ ) == fast_int(x, key=lambda x: get_strxfrm()(_groupletters(x)))
except ValueError as e: # handle broken locale lib on BSD.
- if 'is not in range' not in str(e):
+ if "is not in range" not in str(e):
raise
def test_string_component_transform_factory_with_LOCALE_and_DUMB_returns_fast_int_and_groupletters_and_locale_convert_example():
- x = 'hello'
- assert _string_component_transform_factory(ns._DUMB | ns.LOCALE)(x) == fast_int(x, key=lambda x: get_strxfrm()(_groupletters(x)))
+ x = "hello"
+ assert _string_component_transform_factory(ns._DUMB | ns.LOCALE)(x) == fast_int(
+ x, key=lambda x: get_strxfrm()(_groupletters(x))
+ )
@given(text().filter(bool).filter(no_null))
-def test_string_component_transform_factory_with_LOCALE_and_DUMB_returns_fast_int_and_groupletters_and_locale_convert(x):
+def test_string_component_transform_factory_with_LOCALE_and_DUMB_returns_fast_int_and_groupletters_and_locale_convert(
+ x
+):
try:
- assert _string_component_transform_factory(ns._DUMB | ns.LOCALE)(x) == fast_int(x, key=lambda x: get_strxfrm()(_groupletters(x)))
+ assert _string_component_transform_factory(ns._DUMB | ns.LOCALE)(x) == fast_int(
+ x, key=lambda x: get_strxfrm()(_groupletters(x))
+ )
except ValueError as e: # handle broken locale lib on BSD.
- if 'is not in range' not in str(e):
+ if "is not in range" not in str(e):
raise
diff --git a/test_natsort/test_unicode_numbers.py b/test_natsort/test_unicode_numbers.py
index e257914..68758e5 100644
--- a/test_natsort/test_unicode_numbers.py
+++ b/test_natsort/test_unicode_numbers.py
@@ -43,7 +43,7 @@ def test_numeric_chars_contains_all_valid_unicode_numeric_and_digit_characters()
a = py23_unichr(i)
except ValueError:
break
- if a in set('0123456789'):
+ if a in set("0123456789"):
continue
if unicodedata.numeric(a, None) is not None:
assert i in set_numeric_hex
@@ -63,6 +63,6 @@ def test_numeric_chars_contains_all_valid_unicode_numeric_and_digit_characters()
def test_combined_string_contains_all_characters_in_list():
- assert numeric == ''.join(numeric_chars)
- assert digits == ''.join(digit_chars)
- assert decimals == ''.join(decimal_chars)
+ assert numeric == "".join(numeric_chars)
+ assert digits == "".join(digit_chars)
+ assert decimals == "".join(decimal_chars)
diff --git a/test_natsort/test_utils.py b/test_natsort/test_utils.py
index 10ad0fa..3aebae5 100644
--- a/test_natsort/test_utils.py
+++ b/test_natsort/test_utils.py
@@ -25,88 +25,81 @@ from natsort.utils import (
)
from natsort.compat.py23 import py23_str, py23_cmp
from natsort.compat.locale import null_string_locale
-from slow_splitters import (
- sep_inserter,
- add_leading_space_if_first_is_num,
-)
+from slow_splitters import sep_inserter, add_leading_space_if_first_is_num
from compat.locale import low
-from hypothesis import (
- given,
-)
-from hypothesis.strategies import (
- sampled_from,
- lists,
- text,
- integers,
-)
+from hypothesis import given
+from hypothesis.strategies import sampled_from, lists, text, integers
def test_do_decoding_decodes_bytes_string_to_unicode():
- assert type(_do_decoding(b'bytes', 'ascii')) is py23_str
- assert _do_decoding(b'bytes', 'ascii') == 'bytes'
- assert _do_decoding(b'bytes', 'ascii') == b'bytes'.decode('ascii')
+ assert type(_do_decoding(b"bytes", "ascii")) is py23_str
+ assert _do_decoding(b"bytes", "ascii") == "bytes"
+ assert _do_decoding(b"bytes", "ascii") == b"bytes".decode("ascii")
def test_args_to_enum_raises_TypeError_for_invalid_argument():
with raises(TypeError):
- _args_to_enum(**{'alf': 0})
+ _args_to_enum(**{"alf": 0})
def test_args_to_enum_converts_signed_exp_float_to_ns_F():
# number_type, signed, exp, as_path, py3_safe
- assert _args_to_enum(**{'number_type': float,
- 'signed': True,
- 'exp': True}) == ns.F | ns.S
+ assert (
+ _args_to_enum(**{"number_type": float, "signed": True, "exp": True})
+ == ns.F | ns.S
+ )
def test_args_to_enum_converts_signed_noexp_float_to_ns_FN():
# number_type, signed, exp, as_path, py3_safe
- assert _args_to_enum(**{'number_type': float,
- 'signed': True,
- 'exp': False}) == ns.F | ns.N | ns.S
+ assert (
+ _args_to_enum(**{"number_type": float, "signed": True, "exp": False})
+ == ns.F | ns.N | ns.S
+ )
def test_args_to_enum_converts_unsigned_exp_float_to_ns_FU():
# number_type, signed, exp, as_path, py3_safe
- assert _args_to_enum(**{'number_type': float,
- 'signed': False,
- 'exp': True}) == ns.F | ns.U
+ assert (
+ _args_to_enum(**{"number_type": float, "signed": False, "exp": True})
+ == ns.F | ns.U
+ )
# unsigned is default
- assert _args_to_enum(**{'number_type': float,
- 'signed': False,
- 'exp': True}) == ns.F
+ assert _args_to_enum(**{"number_type": float, "signed": False, "exp": True}) == ns.F
def test_args_to_enum_converts_unsigned_unexp_float_to_ns_FNU():
# number_type, signed, exp, as_path, py3_safe
- assert _args_to_enum(**{'number_type': float,
- 'signed': False,
- 'exp': False}) == ns.F | ns.U | ns.N
+ assert (
+ _args_to_enum(**{"number_type": float, "signed": False, "exp": False})
+ == ns.F | ns.U | ns.N
+ )
def test_args_to_enum_converts_float_and_path_and_py3safe_to_ns_FPT():
# number_type, signed, exp, as_path, py3_safe
- assert _args_to_enum(**{'number_type': float,
- 'as_path': True,
- 'py3_safe': True}) == ns.F | ns.P | ns.T
+ assert (
+ _args_to_enum(**{"number_type": float, "as_path": True, "py3_safe": True})
+ == ns.F | ns.P | ns.T
+ )
def test_args_to_enum_converts_int_and_path_to_ns_IP():
# number_type, signed, exp, as_path, py3_safe
- assert _args_to_enum(**{'number_type': int, 'as_path': True}) == ns.I | ns.P
+ assert _args_to_enum(**{"number_type": int, "as_path": True}) == ns.I | ns.P
def test_args_to_enum_converts_unsigned_int_and_py3safe_to_ns_IUT():
# number_type, signed, exp, as_path, py3_safe
- assert _args_to_enum(**{'number_type': int,
- 'signed': False,
- 'py3_safe': True}) == ns.I | ns.U | ns.T
+ assert (
+ _args_to_enum(**{"number_type": int, "signed": False, "py3_safe": True})
+ == ns.I | ns.U | ns.T
+ )
def test_args_to_enum_converts_None_to_ns_IU():
# number_type, signed, exp, as_path, py3_safe
- assert _args_to_enum(**{'number_type': None,
- 'exp': True}) == ns.I | ns.U
+ assert _args_to_enum(**{"number_type": None, "exp": True}) == ns.I | ns.U
def test_regex_chooser_returns_correct_regular_expression_object():
@@ -163,7 +156,7 @@ def test_chain_functions_is_a_no_op_if_no_functions_are_given():
def test_chain_functions_does_one_function_if_one_function_is_given():
- x = '2345'
+ x = "2345"
assert chain_functions([len])(x) == 4
@@ -175,39 +168,47 @@ def test_chain_functions_combines_functions_in_given_order():
# Each test has an "example" version for demonstrative purposes,
# and a test that uses the hypothesis module.
+
def test_groupletters_returns_letters_with_lowercase_transform_of_letter_example():
- assert _groupletters('HELLO') == 'hHeElLlLoO'
- assert _groupletters('hello') == 'hheelllloo'
+ assert _groupletters("HELLO") == "hHeElLlLoO"
+ assert _groupletters("hello") == "hheelllloo"
@given(text().filter(bool))
def test_groupeletters_returns_letters_with_lowercase_transform_of_letter(x):
- assert _groupletters(x) == ''.join(chain.from_iterable([low(y), y] for y in x))
+ assert _groupletters(x) == "".join(chain.from_iterable([low(y), y] for y in x))
def test_sep_inserter_does_nothing_if_no_numbers_example():
- assert list(_sep_inserter(iter(['a', 'b', 'c']), '')) == ['a', 'b', 'c']
- assert list(_sep_inserter(iter(['a']), '')) == ['a']
+ assert list(_sep_inserter(iter(["a", "b", "c"]), "")) == ["a", "b", "c"]
+ assert list(_sep_inserter(iter(["a"]), "")) == ["a"]
def test_sep_inserter_does_nothing_if_only_one_number_example():
- assert list(_sep_inserter(iter(['a', 5]), '')) == ['a', 5]
+ assert list(_sep_inserter(iter(["a", 5]), "")) == ["a", 5]
def test_sep_inserter_inserts_separator_string_between_two_numbers_example():
- assert list(_sep_inserter(iter([5, 9]), '')) == ['', 5, '', 9]
- assert list(_sep_inserter(iter([5, 9]), null_string_locale)) == [null_string_locale, 5, null_string_locale, 9]
+ assert list(_sep_inserter(iter([5, 9]), "")) == ["", 5, "", 9]
+ assert list(_sep_inserter(iter([5, 9]), null_string_locale)) == [
+ null_string_locale,
+ 5,
+ null_string_locale,
+ 9,
+ ]
@given(lists(elements=text().filter(bool) | integers()))
def test_sep_inserter_inserts_separator_between_two_numbers(x):
- assert list(_sep_inserter(iter(x), '')) == list(add_leading_space_if_first_is_num(sep_inserter(x, ''), ''))
+ assert list(_sep_inserter(iter(x), "")) == list(
+ add_leading_space_if_first_is_num(sep_inserter(x, ""), "")
+ )
def test_path_splitter_splits_path_string_by_separator_example():
- z = '/this/is/a/path'
+ z = "/this/is/a/path"
assert tuple(_path_splitter(z)) == tuple(pathlib.Path(z).parts)
- z = pathlib.Path('/this/is/a/path')
+ z = pathlib.Path("/this/is/a/path")
assert tuple(_path_splitter(z)) == tuple(pathlib.Path(z).parts)
@@ -218,16 +219,22 @@ def test_path_splitter_splits_path_string_by_separator(x):
def test_path_splitter_splits_path_string_by_separator_and_removes_extension_example():
- z = '/this/is/a/path/file.exe'
+ z = "/this/is/a/path/file.exe"
y = tuple(pathlib.Path(z).parts)
- assert tuple(_path_splitter(z)) == y[:-1] + (pathlib.Path(z).stem, pathlib.Path(z).suffix)
+ assert tuple(_path_splitter(z)) == y[:-1] + (
+ pathlib.Path(z).stem,
+ pathlib.Path(z).suffix,
+ )
@given(lists(sampled_from(string.ascii_letters), min_size=3).filter(all))
def test_path_splitter_splits_path_string_by_separator_and_removes_extension(x):
- z = py23_str(pathlib.Path(*x[:-2])) + '.' + x[-1]
+ z = py23_str(pathlib.Path(*x[:-2])) + "." + x[-1]
y = tuple(pathlib.Path(z).parts)
- assert tuple(_path_splitter(z)) == y[:-1] + (pathlib.Path(z).stem, pathlib.Path(z).suffix)
+ assert tuple(_path_splitter(z)) == y[:-1] + (
+ pathlib.Path(z).stem,
+ pathlib.Path(z).suffix,
+ )
@given(integers())