Example #1
0
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 = (
        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 = (
            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)
            ]
        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)
            ]
        if args.exclude:
            exclude = set(args.exclude)
            entries = [
                entry
                for entry in entries
                if keep_entry_value(entry, exclude, float, regex)
            ]

    # Print off the sorted results
    for entry in natsort.natsorted(entries, reverse=args.reverse, alg=alg):
        print(entry)
Example #2
0
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 = (
        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 = (
            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)
            ]
        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)
            ]
        if args.exclude:
            exclude = set(args.exclude)
            entries = [
                entry
                for entry in entries
                if keep_entry_value(entry, exclude, float, regex)
            ]

    # Print off the sorted results
    for entry in natsort.natsorted(entries, reverse=args.reverse, alg=alg):
        print(entry)
Example #3
0
def numeric_regex_chooser(alg):
    """
    Select an appropriate regex for the type of number of interest.

    Parameters
    ----------
    alg : ns enum
        Used to indicate the regular expression to select.

    Returns
    -------
    regex : str
        Regular expression string that matches the desired number type.

    """
    # Remove the leading and trailing parens
    return utils.regex_chooser(alg).pattern[1:-1]
Example #4
0
def test_regex_chooser_returns_correct_regular_expression_object(
        alg, expected):
    assert utils.regex_chooser(alg).pattern == expected.pattern
Example #5
0
def natsort_keygen(key=None, alg=ns.DEFAULT):
    """
    Generate a key to sort strings and numbers naturally.

    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.

    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 function that parses input for natural sorting that is
        suitable for passing as the `key` argument to functions
        such as `sorted`.

    See Also
    --------
    natsorted
    natsort_key

    Examples
    --------
    `natsort_keygen` is a convenient way to create a custom key
    to sort lists in-place (for example).::

        >>> 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']

    """
    try:
        ns.DEFAULT | alg
    except TypeError:
        msg = "natsort_keygen: 'alg' argument must be from the enum 'ns'"
        raise ValueError(msg + ", got {}".format(py23_str(alg)))

    # Add the NS_DUMB option if the locale library is broken.
    if alg & ns.LOCALEALPHA and natsort.compat.locale.dumb_sort():
        alg |= NS_DUMB

    # Set some variables that will be passed to the factory functions
    if alg & ns.NUMAFTER:
        if alg & ns.LOCALEALPHA:
            sep = natsort.compat.locale.null_string_locale_max
        else:
            sep = natsort.compat.locale.null_string_max
        pre_sep = natsort.compat.locale.null_string_max
    else:
        if alg & ns.LOCALEALPHA:
            sep = natsort.compat.locale.null_string_locale
        else:
            sep = natsort.compat.locale.null_string
        pre_sep = natsort.compat.locale.null_string
    regex = utils.regex_chooser(alg)

    # Create the functions that will be used to split strings.
    input_transform = utils.input_string_transform_factory(alg)
    component_transform = utils.string_component_transform_factory(alg)
    final_transform = utils.final_data_transform_factory(alg, sep, pre_sep)

    # Create the high-level parsing functions for strings, bytes, and numbers.
    string_func = utils.parse_string_factory(alg, sep, regex.split,
                                             input_transform,
                                             component_transform,
                                             final_transform)
    if alg & ns.PATH:
        string_func = utils.parse_path_factory(string_func)
    bytes_func = utils.parse_bytes_factory(alg)
    num_func = utils.parse_number_factory(alg, sep, pre_sep)

    # Return the natsort key with the parsing path pre-chosen.
    return partial(
        utils.natsort_key,
        key=key,
        string_func=string_func,
        bytes_func=bytes_func,
        num_func=num_func,
    )
Example #6
0
def test_regex_chooser_returns_correct_regular_expression_object(alg, expected):
    assert utils.regex_chooser(alg).pattern == expected.pattern
Example #7
0
def natsort_keygen(key=None, alg=ns.DEFAULT):
    """
    Generate a key to sort strings and numbers naturally.

    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.

    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 function that parses input for natural sorting that is
        suitable for passing as the `key` argument to functions
        such as `sorted`.

    See Also
    --------
    natsorted
    natsort_key

    Examples
    --------
    `natsort_keygen` is a convenient way to create a custom key
    to sort lists in-place (for example).::

        >>> 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']

    """
    try:
        ns.DEFAULT | alg
    except TypeError:
        msg = "natsort_keygen: 'alg' argument must be from the enum 'ns'"
        raise ValueError(msg + ", got {}".format(py23_str(alg)))

    # Add the NS_DUMB option if the locale library is broken.
    if alg & ns.LOCALEALPHA and natsort.compat.locale.dumb_sort():
        alg |= NS_DUMB

    # Set some variables that will be passed to the factory functions
    if alg & ns.NUMAFTER:
        if alg & ns.LOCALEALPHA:
            sep = natsort.compat.locale.null_string_locale_max
        else:
            sep = natsort.compat.locale.null_string_max
        pre_sep = natsort.compat.locale.null_string_max
    else:
        if alg & ns.LOCALEALPHA:
            sep = natsort.compat.locale.null_string_locale
        else:
            sep = natsort.compat.locale.null_string
        pre_sep = natsort.compat.locale.null_string
    regex = utils.regex_chooser(alg)

    # Create the functions that will be used to split strings.
    input_transform = utils.input_string_transform_factory(alg)
    component_transform = utils.string_component_transform_factory(alg)
    final_transform = utils.final_data_transform_factory(alg, sep, pre_sep)

    # Create the high-level parsing functions for strings, bytes, and numbers.
    string_func = utils.parse_string_factory(
        alg, sep, regex.split, input_transform, component_transform, final_transform
    )
    if alg & ns.PATH:
        string_func = utils.parse_path_factory(string_func)
    bytes_func = utils.parse_bytes_factory(alg)
    num_func = utils.parse_number_factory(alg, sep, pre_sep)

    # Return the natsort key with the parsing path pre-chosen.
    return partial(
        utils.natsort_key,
        key=key,
        string_func=string_func,
        bytes_func=bytes_func,
        num_func=num_func,
    )