Source code for lz.sorting

import functools
from collections import ChainMap
from typing import (Callable,
                    Iterable,
                    Optional,
                    Union)

from .hints import (Domain,
                    Map,
                    Operator,
                    Sortable)

Key = Map[Domain, Sortable]
Implementation = Callable[..., Iterable[Domain]]

stable_implementations = {}
unstable_implementations = {}
implementations = ChainMap(stable_implementations,
                           unstable_implementations)


def search_implementation(algorithm: str) -> Implementation:
    try:
        return implementations[algorithm]
    except KeyError as error:
        algorithms_str = ', '.join(map(repr, implementations))
        error_message = ('Algorithm is not found: {algorithm}. '
                         'Available algorithms are: {algorithms}.'
                         .format(algorithm=algorithm,
                                 algorithms=algorithms_str))
        raise LookupError(error_message) from error


[docs]def register_implementation(algorithm: str, implementation: Optional[Implementation] = None, *, stable: bool = False, overwrite: bool = False ) -> Union[Operator[Implementation], Implementation]: """ Registers implementation of sorting algorithm. >>> from typing import Any >>> @register_implementation('CUSTOMSORTING') ... def custom_sorting(iterable: Iterable[Domain], ... *, ... key: Optional[Map[Domain, Any]] = None ... ) -> Iterable[Domain]: ... ... """ if implementation is None: return functools.partial(register_implementation, algorithm, stable=stable) if algorithm in implementations: if overwrite: del implementations[algorithm] else: raise ValueError('Algorithm "{algorithm}" ' 'has been already registered.' .format(algorithm=algorithm)) if stable: stable_implementations[algorithm] = implementation else: unstable_implementations[algorithm] = implementation return implementation
DEFAULT_ALGORITHM = 'TIMSORT' register_implementation(DEFAULT_ALGORITHM, sorted, stable=True)
[docs]def sorter(*, algorithm: str = DEFAULT_ALGORITHM, key: Optional[Key] = None) -> Operator[Iterable[Domain]]: """ Returns function that generates sorted iterable by given key with specified algorithm. >>> sort = sorter() >>> sort('Hello World!') [' ', '!', 'H', 'W', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r'] """ implementation = search_implementation(algorithm) return functools.partial(implementation, key=key)