diff --git a/warg/__init__.py b/warg/__init__.py index 9c8e965..20af4f2 100644 --- a/warg/__init__.py +++ b/warg/__init__.py @@ -7,7 +7,7 @@ __project__ = "Warg" __author__ = "Christian Heider Nielsen" -__version__ = "1.2.3" +__version__ = "1.2.5" __doc__ = r""" Created on 27/04/2019 diff --git a/warg/business.py b/warg/business.py index d7361b4..d2320cc 100644 --- a/warg/business.py +++ b/warg/business.py @@ -16,7 +16,7 @@ def busy_indicator( stream: Callable = print, indicator_interval: int = 1, phases: Iterable[str] = ("◑", "◒", "◐", "◓"), -) -> int: +) -> Iterable[int]: """ You can choose arbitrary phases like ['|','/','-','\\'] diff --git a/warg/exceptions.py b/warg/exceptions.py index b32e251..2c46ee0 100644 --- a/warg/exceptions.py +++ b/warg/exceptions.py @@ -10,6 +10,8 @@ __all__ = ["NoData", "IncompatiblePackageVersions"] import types +import typing +from importlib.resources import Package from typing import Iterable, MutableMapping, Union @@ -23,7 +25,7 @@ def __init__(self, msg: str = "No Data Available"): class IncompatiblePackageVersions(Exception): """description""" - def __init__(self, *packages: Iterable[Union[str, object]], **versions: MutableMapping): + def __init__(self, *packages: Iterable[Union[str, types.ModuleType]], **versions): str_o = ", " str_l = [] @@ -69,4 +71,5 @@ def main2() -> None: raise IncompatiblePackageVersions(numpy, scipy) - main() + # main() + main2() diff --git a/warg/functions.py b/warg/functions.py index 7d584c2..6033d2b 100644 --- a/warg/functions.py +++ b/warg/functions.py @@ -23,6 +23,8 @@ "list_keys", "first_key", "last_key", + "to_list", + "to_tuple", ] import operator @@ -39,6 +41,7 @@ Sequence, Tuple, List, + Union, ) from warg import Number, drop_unused_kws @@ -117,7 +120,7 @@ def sink(*args, **kwargs) -> None: def prod(iterable: Iterable[Number]) -> Number: """ - Calculate the product of the a Iterable of int or floats + Calculate the product of an Iterable, of int or floats :param iterable: :return:""" return reduce(operator.mul, iterable, 1) @@ -244,6 +247,34 @@ def chain_apply(it: Iterable, *callables: Callable) -> Iterable[Any]: return it +def to_list(x: Union[Iterable, Any]) -> Union[List, Any]: + if False: + if x is None: + return [] + if not isinstance(x, Iterable): + return x + i = iter(x) + try: + val = next(i) + except StopIteration: + return [] + return [to_list(val)] + to_list(i) + + +def to_tuple(x: Union[Iterable, Any]) -> Union[Tuple, Any]: + if False: + if x is None: + return () + if not isinstance(x, Iterable): + return x + i = iter(x) + try: + val = next(i) + except StopIteration: + return () + return (to_tuple(val), *to_tuple(i)) + + if __name__ == "__main__": def asud() -> None: @@ -274,6 +305,16 @@ def asidj() -> None: result = swap_mapping_order(test_dict, [2, 0, 1]) print(result) + def i8jsadij(): + ij = ([10, 29], [(2, 3, 4), [[12, 4, 5]], ((2, 92, 90))], []) + print(to_list(ij)) + + def i8jsadi2j(): + ij = ([10, 29], [(2, 3, 4), [[12, 4, 5]], ((2, 92, 90))], []) + print(to_tuple(ij)) + + i8jsadij() + i8jsadi2j() # asud() - asidj() + # asidj() # asjdnasid() diff --git a/warg/generators/__init__.py b/warg/generators/__init__.py index e65132b..94c3388 100644 --- a/warg/generators/__init__.py +++ b/warg/generators/__init__.py @@ -18,3 +18,4 @@ from .mapping_generator import * from .zipping_generator import * from .numbers import * +from .testing import * diff --git a/warg/generators/numbers.py b/warg/generators/numbers.py index 14e8bc8..976a17f 100644 --- a/warg/generators/numbers.py +++ b/warg/generators/numbers.py @@ -1,12 +1,12 @@ import random -from typing import Iterable, Tuple, Callable +from typing import Iterable, Tuple, Callable, List from warg import Number __all__ = ["n_uint_mix", "n_uint_mix_generator_builder", "n_uint_mix_generator"] -def n_uint_mix(mix: Iterable[Number]) -> Tuple[Number, ...]: +def n_uint_mix(mix: Iterable[Number]) -> List[Number]: return [random.randrange(0, m) for m in mix] diff --git a/warg/generators/testing.py b/warg/generators/testing.py new file mode 100644 index 0000000..5114f93 --- /dev/null +++ b/warg/generators/testing.py @@ -0,0 +1,16 @@ +import itertools +from typing import Optional, Iterator + +__all__ = ["peek"] + + +def peek(generator: Iterator) -> Optional[itertools.chain]: + try: + return itertools.chain((next(generator),), generator) + except StopIteration: + return None + + +if __name__ == "__main__": + print(peek(iter(range(0)))) + print(peek(iter(range(1)))) diff --git a/warg/generators/zipping_generator.py b/warg/generators/zipping_generator.py index 57c05fd..79abbce 100644 --- a/warg/generators/zipping_generator.py +++ b/warg/generators/zipping_generator.py @@ -31,9 +31,9 @@ def check_next_iter(iterable_: Any) -> Any: """description""" if isinstance(iterable_, Iterable): try: - a = next(iter(iterable_)) - if isinstance(a, Iterable): - return a + a_ = next(iter(iterable_)) + if isinstance(a_, Iterable): + return a_ except StopIteration: pass diff --git a/warg/iteration.py b/warg/iteration.py index 20b7229..bbc5abf 100644 --- a/warg/iteration.py +++ b/warg/iteration.py @@ -11,7 +11,7 @@ def pairs(s: Sequence) -> Tuple[Any, Any]: lst = [4, 7, 11, 2] pairs(lst) yields (4, 7), (7, 11), (11, 2) - http://stackoverflow.com/questions/1257413/1257446#1257446 + https://stackoverflow.com/questions/1257413/1257446#1257446 :param s: An iterable/list diff --git a/warg/manipulation.py b/warg/manipulation.py index 3b06ba3..60509f3 100644 --- a/warg/manipulation.py +++ b/warg/manipulation.py @@ -9,10 +9,10 @@ __all__ = ["recursive_flatten"] -from typing import Sequence +from typing import Sequence, Iterable -def recursive_flatten(seq: Sequence) -> Sequence: +def recursive_flatten_seq(seq: Sequence) -> Sequence: """Depth first flatten""" if not seq: # is empty Sequence return seq @@ -21,6 +21,26 @@ def recursive_flatten(seq: Sequence) -> Sequence: return (*seq[:1], *recursive_flatten(seq[1:])) +def recursive_flatten(sequence: Iterable) -> Iterable: + """ + Depth first flatten iterable + + >>> list(recursive_flatten([1, [2], 3])) + [1, 2, 3] + >>> list(recursive_flatten([1, [2], [3, [4]]])) + [1, 2, 3, 4] + >>> list(recursive_flatten((([[None]], 2), (2,), 2))) + [None, 2, 2, 2] + """ + for element in sequence: + if isinstance(element, Iterable): + yield from recursive_flatten(element) + else: + yield element + + if __name__ == "__main__": - print(recursive_flatten((((2,), 2), (2,), 2))) - print(recursive_flatten((([[None]], 2), (2,), 2))) + print(list(recursive_flatten((((2,), 2), (2,), 2)))) + print(list(recursive_flatten((([[None]], 2), (2,), 2)))) + + print(list(recursive_flatten((([[None]], 2), (2,), 2)))) diff --git a/warg/packages/editable.py b/warg/packages/editable.py index 5df457f..3e68d8f 100644 --- a/warg/packages/editable.py +++ b/warg/packages/editable.py @@ -1,4 +1,6 @@ import json + +# noinspection PyProtectedMember from importlib.metadata import Distribution, PackageNotFoundError, PathDistribution __all__ = [ @@ -9,8 +11,10 @@ ] from pathlib import Path +from typing import Optional +# noinspection PyProtectedMember def dist_is_editable(dist: Distribution) -> bool: """ Return True if given Distribution is an editable installation. @@ -70,7 +74,8 @@ def get_package_location(package_name: str) -> Path: print(p) -def get_dist_package_location(dist: Distribution) -> Path: +# noinspection PyProtectedMember +def get_dist_package_location(dist: Distribution) -> Optional[Path]: """ FULL OF ASSUMPTIONS! diff --git a/warg/packages/pip_parsing.py b/warg/packages/pip_parsing.py index b7c1dff..1c8e938 100644 --- a/warg/packages/pip_parsing.py +++ b/warg/packages/pip_parsing.py @@ -2,9 +2,17 @@ from typing import List, Union from packaging.requirements import Requirement + +# noinspection PyProtectedMember from pip._internal.network.session import PipSession + +# noinspection PyProtectedMember from pip._internal.req import parse_requirements + +# noinspection PyProtectedMember from pip._internal.req.req_file import ParsedRequirement + +# noinspection PyProtectedMember from pip._internal.utils.packaging import get_requirement diff --git a/warg/plugin.py b/warg/plugin.py index 68071af..6ab8742 100644 --- a/warg/plugin.py +++ b/warg/plugin.py @@ -11,8 +11,10 @@ if sys.version_info[:2] >= (3, 10): # pylint: disable=no-name-in-module + # noinspection PyProtectedMember from importlib.metadata import entry_points, EntryPoint else: + # noinspection PyProtectedMember from importlib_metadata import entry_points, EntryPoint from typing import Tuple, Generator, Any