def test_pre_split_function_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 _pre_split_function(ns.LOCALE)(x) == '12543642642.534534980' x = '12,543,642,642.534,534,980' # LOCALEALPHA doesn't do anything... need LOCALENUM assert _pre_split_function(ns.LOCALEALPHA)(x) == '12,543,642,642.534,534,980' locale.setlocale(locale.LC_ALL, str(''))
def test_pre_split_function_replaces_decimal_separator_with_LOCALE_example(): load_locale('de_DE') x = '1543,753' assert _pre_split_function(ns.LOCALE)(x) == '1543,753' # Does nothing without FLOAT assert _pre_split_function(ns.LOCALE | ns.FLOAT)(x) == '1543.753' assert _pre_split_function(ns.LOCALEALPHA)(x) == '1543,753' # LOCALEALPHA doesn't do anything... need LOCALENUM locale.setlocale(locale.LC_ALL, str(''))
def test_pre_split_function_leaves_invalid_thousands_separator_with_LOCALE_example(): load_locale('en_US') x = '12,543,642642.5345,34980' assert _pre_split_function(ns.LOCALE)(x) == '12543,642642.5345,34980' x = '12,59443,642,642.53,4534980' assert _pre_split_function(ns.LOCALE)(x) == '12,59443,642642.53,4534980' x = '12543,642,642.5,34534980' assert _pre_split_function(ns.LOCALE)(x) == '12543,642642.5,34534980' locale.setlocale(locale.LC_ALL, str(''))
def test_pre_split_function_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 = '' for i, y in enumerate(reversed(t), 1): s = y + s if i % 3 == 0 and i != len(t): s = ',' + s assert _pre_split_function(ns.LOCALE)(s) == t locale.setlocale(locale.LC_ALL, str(''))
def test_pre_split_function_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 = '' for i, z in enumerate(reversed(u), 1): v = z + v if i % 3 == 0 and i != len(u): v = ',' + v # Remove all but first comma. a = v.split(',', 1) p = a[0] + ',' + a[1].replace(',', '') assert _pre_split_function(ns.LOCALE)('.'.join([s, v])) == '.'.join([t, u]) assert _pre_split_function(ns.LOCALE | ns.FLOAT)('.'.join([s, v])) == '.'.join([t, p]) locale.setlocale(locale.LC_ALL, str(''))
def test_pre_split_function_performs_swapcase_with_DUMB(x): assert _pre_split_function(ns._DUMB)(x) == x.swapcase()
def test_pre_split_function_performs_swapcase_with_DUMB_examples(): x = 'feijGGAd' assert _pre_split_function(ns._DUMB)(x) == x.swapcase()
def test_pre_split_function_performs_casefold_with_IGNORECASE(x): if NEWPY: assert _pre_split_function(ns.IGNORECASE)(x) == x.casefold() else: assert _pre_split_function(ns.IGNORECASE)(x) == x.lower()
def test_pre_split_function_performs_casefold_with_IGNORECASE_examples(): x = 'feijGGAd' if NEWPY: assert _pre_split_function(ns.IGNORECASE)(x) == x.casefold() else: assert _pre_split_function(ns.IGNORECASE)(x) == x.lower()
def test_pre_split_function_is_no_op_for_no_alg_options(x): assert _pre_split_function(0)(x) is x
def natsort_keygen(key=None, alg=0, **_kwargs): """\ Generate a key to sort strings and numbers naturally. Generate a key to sort strings and numbers naturally, not lexicographically. This key is designed for use as the `key` argument to functions such as the `sorted` builtin. The user may customize the generated function with the arguments to `natsort_keygen`, including an optional `key` function which will be called before the `natsort_key`. Parameters ---------- key : callable, optional A key used to manipulate the input value before parsing for numbers. It is **not** applied recursively. It should accept a single argument and return a single value. alg : ns enum, optional This option is used to control which algorithm `natsort` uses when sorting. For details into these options, please see the :class:`ns` class documentation. The default is `ns.INT`. Returns ------- out : function A wrapped version of the `natsort_key` function that is suitable for passing as the `key` argument to functions such as `sorted`. See Also -------- natsorted Examples -------- `natsort_keygen` is a convenient way to create a custom key to sort lists in-place (for example). Calling with no objects will return a plain `natsort_key` instance:: >>> a = ['num5.10', 'num-3', 'num5.3', 'num2'] >>> a.sort(key=natsort_keygen(alg=ns.REAL)) >>> a [{u}'num-3', {u}'num2', {u}'num5.10', {u}'num5.3'] """ # Transform old arguments to the ns enum. 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))) # Add the _DUMB option if the locale library is broken. if alg & ns.LOCALEALPHA and natsort.compat.locale.dumb_sort(): alg |= ns._DUMB # Set some variable that will be passed to the factory functions sep = natsort.compat.locale.null_string if alg & ns.LOCALEALPHA else '' regex = _regex_chooser[alg & ns._NUMERIC_ONLY] # Create the functions that will be used to split strings. pre = _pre_split_function(alg) post = _post_split_function(alg) after = _post_string_parse_function(alg, sep) # Create the high-level parsing functions for strings, bytes, and numbers. string_func = _parse_string_function(alg, sep, regex.split, pre, post, after) if alg & ns.PATH: string_func = _parse_path_function(string_func) bytes_func = _parse_bytes_function(alg) num_func = _parse_number_function(alg, sep) # Return the natsort key with the parsing path pre-chosen. return partial(_natsort_key, key=key, string_func=string_func, bytes_func=bytes_func, num_func=num_func)
def test_pre_split_function_is_no_op_with_both_LOWERCASEFIRST_AND_DUMB(x): assert _pre_split_function(ns._DUMB | ns.LOWERCASEFIRST)(x) is x
def test_pre_split_function_removes_thousands_separator_and_is_float_aware_with_LOCALE_and_FLOAT_example(): x = '12,543,642,642.534,534,980' assert _pre_split_function(ns.LOCALE | ns.FLOAT)(x) == '12543642642.534,534980'
assume, given, lists, text, floats, integers, binary, use_hypothesis, ) if PY_VERSION >= 3: long = int regex = _regex_chooser[ns.INT] pre = _pre_split_function(ns.INT) post = _post_split_function(ns.INT) after = _post_string_parse_function(ns.INT, '') string_func = _parse_string_function(ns.INT, '', regex.split, pre, post, after) bytes_func = _parse_bytes_function(ns.INT) num_func = _parse_number_function(ns.INT, '') def test__natsort_key_with_numeric_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_function(string_func) bytes_func = _parse_bytes_function(ns.PATH) num_func = _parse_number_function(ns.PATH, '') assert _natsort_key(10, None, sfunc, bytes_func, num_func) == (('', 10),)
def test_pre_split_function_performs_swapcase_with_LOWERCASEFIRST(x): x = 'feijGGAd' assert _pre_split_function(ns.LOWERCASEFIRST)(x) == x.swapcase()
def test_pre_split_function_does_not_replace_invalid_decimal_separator_with_LOCALE_example(): load_locale('de_DE') x = '154s,t53' assert _pre_split_function(ns.LOCALE | ns.FLOAT)(x) == '154s,t53' locale.setlocale(locale.LC_ALL, str(''))
def test_pre_split_function_is_no_op_with_both_LOWERCASEFIRST_AND_DUMB_example(): x = 'feijGGAd' assert _pre_split_function(ns._DUMB | ns.LOWERCASEFIRST)(x) is x
def test_pre_split_function_is_no_op_for_no_alg_options_examples(): x = 'feijGGAd' assert _pre_split_function(0)(x) is x
def test_pre_split_function_performs_swapcase_and_casefold_both_LOWERCASEFIRST_AND_IGNORECASE(x): if NEWPY: assert _pre_split_function(ns.IGNORECASE | ns.LOWERCASEFIRST)(x) == x.swapcase().casefold() else: assert _pre_split_function(ns.IGNORECASE | ns.LOWERCASEFIRST)(x) == x.swapcase().lower()
def natsort_keygen(key=None, alg=0, **_kwargs): """\ Generate a key to sort strings and numbers naturally. Generate a key to sort strings and numbers naturally, not lexicographically. This key is designed for use as the `key` argument to functions such as the `sorted` builtin. The user may customize the generated function with the arguments to `natsort_keygen`, including an optional `key` function which will be called before the `natsort_key`. Parameters ---------- key : callable, optional A key used to manipulate the input value before parsing for numbers. It is **not** applied recursively. It should accept a single argument and return a single value. alg : ns enum, optional This option is used to control which algorithm `natsort` uses when sorting. For details into these options, please see the :class:`ns` class documentation. The default is `ns.INT`. Returns ------- out : function A wrapped version of the `natsort_key` function that is suitable for passing as the `key` argument to functions such as `sorted`. See Also -------- natsorted Examples -------- `natsort_keygen` is a convenient way to create a custom key to sort lists in-place (for example). Calling with no objects will return a plain `natsort_key` instance:: >>> a = ['num5.10', 'num-3', 'num5.3', 'num2'] >>> a.sort(key=natsort_keygen(alg=ns.REAL)) >>> a [{u}'num-3', {u}'num2', {u}'num5.10', {u}'num5.3'] """ # Transform old arguments to the ns enum. 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))) # Add the _DUMB option if the locale library is broken. if alg & ns.LOCALEALPHA and natsort.compat.locale.dumb_sort(): alg |= ns._DUMB # Set some variable that will be passed to the factory functions sep = natsort.compat.locale.null_string if alg & ns.LOCALEALPHA else '' regex = _regex_chooser[alg & ns._NUMERIC_ONLY] # Create the functions that will be used to split strings. pre = _pre_split_function(alg) post = _post_split_function(alg) after = _post_string_parse_function(alg, sep) # Create the high-level parsing functions for strings, bytes, and numbers. string_func = _parse_string_function( alg, sep, regex.split, pre, post, after ) if alg & ns.PATH: string_func = _parse_path_function(string_func) bytes_func = _parse_bytes_function(alg) num_func = _parse_number_function(alg, sep) # Return the natsort key with the parsing path pre-chosen. return partial( _natsort_key, key=key, string_func=string_func, bytes_func=bytes_func, num_func=num_func )