Erotemic / ubelt

Compare 92a633c ... +8 ... 9cb931b

No flags found

Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.

e.g., #unittest #integration

#production #enterprise

#frontend #backend

Learn more about Codecov Flags here.


@@ -102,13 +102,15 @@
Loading
102 102
        >>> assert len(list(ub.chunks([], 2, None, 'replicate'))) == 0
103 103
104 104
    Example:
105 +
        >>> from ubelt.util_list import *  # NOQA
105 106
        >>> def _check_len(self):
106 107
        ...     assert len(self) == len(list(self))
107 108
        >>> _check_len(chunks(list(range(3)), nchunks=2))
108 109
        >>> _check_len(chunks(list(range(2)), nchunks=2))
109 110
        >>> _check_len(chunks(list(range(2)), nchunks=3))
110 111
111 112
    Example:
113 +
        >>> from ubelt.util_list import *  # NOQA
112 114
        >>> import pytest
113 115
        >>> assert pytest.raises(ValueError, chunks, range(9))
114 116
        >>> assert pytest.raises(ValueError, chunks, range(9), chunksize=2, nchunks=2)
@@ -203,10 +205,11 @@
Loading
203 205
        bool: True if the input is iterable
204 206
205 207
    Example:
208 +
        >>> import ubelt as ub
206 209
        >>> obj_list = [3, [3], '3', (3,), [3, 4, 5], {}]
207 -
        >>> result = [iterable(obj) for obj in obj_list]
210 +
        >>> result = [ub.iterable(obj) for obj in obj_list]
208 211
        >>> assert result == [False, True, False, True, True, True]
209 -
        >>> result = [iterable(obj, strok=True) for obj in obj_list]
212 +
        >>> result = [ub.iterable(obj, strok=True) for obj in obj_list]
210 213
        >>> assert result == [False, True, True, True, True, True]
211 214
    """
212 215
    try:
@@ -238,7 +241,7 @@
Loading
238 241
        V: a selected item within the list
239 242
240 243
    SeeAlso:
241 -
        :func:`ub.dict_subset`
244 +
        :func:`ubelt.dict_subset`
242 245
243 246
    Notes:
244 247
        ``ub.take(items, indices)`` is equivalent to
@@ -378,10 +381,11 @@
Loading
378 381
        Iterator[int] : indices of the unique items
379 382
380 383
    Example:
384 +
        >>> import ubelt as ub
381 385
        >>> items = [0, 2, 5, 1, 1, 0, 2, 4]
382 -
        >>> indices = list(argunique(items))
386 +
        >>> indices = list(ub.argunique(items))
383 387
        >>> assert indices == [0, 1, 2, 3, 7]
384 -
        >>> indices = list(argunique(items, key=lambda x: x % 2 == 0))
388 +
        >>> indices = list(ub.argunique(items, key=lambda x: x % 2 == 0))
385 389
        >>> assert indices == [0, 2]
386 390
    """
387 391
    if key is None:
@@ -407,9 +411,9 @@
Loading
407 411
    Example:
408 412
        >>> import ubelt as ub
409 413
        >>> items = [0, 2, 1, 1, 0, 9, 2]
410 -
        >>> flags = unique_flags(items)
414 +
        >>> flags = ub.unique_flags(items)
411 415
        >>> assert flags == [True, True, True, False, False, True, False]
412 -
        >>> flags = unique_flags(items, key=lambda x: x % 2 == 0)
416 +
        >>> flags = ub.unique_flags(items, key=lambda x: x % 2 == 0)
413 417
        >>> assert flags == [True, False, True, False, False, False, False]
414 418
    """
415 419
    len_ = len(items)
@@ -475,33 +479,37 @@
Loading
475 479
        Iterable[T]: returns a possibly overlaping windows in a sequence
476 480
477 481
    Example:
482 +
        >>> import ubelt as ub
478 483
        >>> iterable = [1, 2, 3, 4, 5, 6]
479 484
        >>> size, step, wrap = 3, 1, True
480 -
        >>> window_iter = iter_window(iterable, size, step, wrap)
485 +
        >>> window_iter = ub.iter_window(iterable, size, step, wrap)
481 486
        >>> window_list = list(window_iter)
482 487
        >>> print('window_list = %r' % (window_list,))
483 488
        window_list = [(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 1), (6, 1, 2)]
484 489
485 490
    Example:
491 +
        >>> import ubelt as ub
486 492
        >>> iterable = [1, 2, 3, 4, 5, 6]
487 493
        >>> size, step, wrap = 3, 2, True
488 -
        >>> window_iter = iter_window(iterable, size, step, wrap)
494 +
        >>> window_iter = ub.iter_window(iterable, size, step, wrap)
489 495
        >>> window_list = list(window_iter)
490 496
        >>> print('window_list = {!r}'.format(window_list))
491 497
        window_list = [(1, 2, 3), (3, 4, 5), (5, 6, 1)]
492 498
493 499
    Example:
500 +
        >>> import ubelt as ub
494 501
        >>> iterable = [1, 2, 3, 4, 5, 6]
495 502
        >>> size, step, wrap = 3, 2, False
496 -
        >>> window_iter = iter_window(iterable, size, step, wrap)
503 +
        >>> window_iter = ub.iter_window(iterable, size, step, wrap)
497 504
        >>> window_list = list(window_iter)
498 505
        >>> print('window_list = {!r}'.format(window_list))
499 506
        window_list = [(1, 2, 3), (3, 4, 5)]
500 507
501 508
    Example:
509 +
        >>> import ubelt as ub
502 510
        >>> iterable = []
503 511
        >>> size, step, wrap = 3, 2, False
504 -
        >>> window_iter = iter_window(iterable, size, step, wrap)
512 +
        >>> window_iter = ub.iter_window(iterable, size, step, wrap)
505 513
        >>> window_list = list(window_iter)
506 514
        >>> print('window_list = {!r}'.format(window_list))
507 515
        window_list = []
@@ -540,19 +548,20 @@
Loading
540 548
        bool: True if all items are equal, otherwise False
541 549
542 550
    Example:
543 -
        >>> allsame([1, 1, 1, 1])
551 +
        >>> import ubelt as ub
552 +
        >>> ub.allsame([1, 1, 1, 1])
544 553
        True
545 -
        >>> allsame([])
554 +
        >>> ub.allsame([])
546 555
        True
547 -
        >>> allsame([0, 1])
556 +
        >>> ub.allsame([0, 1])
548 557
        False
549 558
        >>> iterable = iter([0, 1, 1, 1])
550 559
        >>> next(iterable)
551 -
        >>> allsame(iterable)
560 +
        >>> ub.allsame(iterable)
552 561
        True
553 -
        >>> allsame(range(10))
562 +
        >>> ub.allsame(range(10))
554 563
        False
555 -
        >>> allsame(range(10), lambda a, b: True)
564 +
        >>> ub.allsame(range(10), lambda a, b: True)
556 565
        True
557 566
    """
558 567
    iter_ = iter(iterable)
@@ -636,11 +645,12 @@
Loading
636 645
        int: the index of the item with the maximum value.
637 646
638 647
    Example:
639 -
        >>> assert argmax({'a': 3, 'b': 2, 'c': 100}) == 'c'
640 -
        >>> assert argmax(['a', 'c', 'b', 'z', 'f']) == 3
641 -
        >>> assert argmax([[0, 1], [2, 3, 4], [5]], key=len) == 1
642 -
        >>> assert argmax({'a': 3, 'b': 2, 3: 100, 4: 4}) == 3
643 -
        >>> assert argmax(iter(['a', 'c', 'b', 'z', 'f'])) == 3
648 +
        >>> import ubelt as ub
649 +
        >>> assert ub.argmax({'a': 3, 'b': 2, 'c': 100}) == 'c'
650 +
        >>> assert ub.argmax(['a', 'c', 'b', 'z', 'f']) == 3
651 +
        >>> assert ub.argmax([[0, 1], [2, 3, 4], [5]], key=len) == 1
652 +
        >>> assert ub.argmax({'a': 3, 'b': 2, 3: 100, 4: 4}) == 3
653 +
        >>> assert ub.argmax(iter(['a', 'c', 'b', 'z', 'f'])) == 3
644 654
    """
645 655
    if key is None and isinstance(indexable, collections_abc.Mapping):
646 656
        return max(indexable.items(), key=operator.itemgetter(1))[0]
@@ -671,11 +681,12 @@
Loading
671 681
        int: the index of the item with the minimum value.
672 682
673 683
    Example:
674 -
        >>> assert argmin({'a': 3, 'b': 2, 'c': 100}) == 'b'
675 -
        >>> assert argmin(['a', 'c', 'b', 'z', 'f']) == 0
676 -
        >>> assert argmin([[0, 1], [2, 3, 4], [5]], key=len) == 2
677 -
        >>> assert argmin({'a': 3, 'b': 2, 3: 100, 4: 4}) == 'b'
678 -
        >>> assert argmin(iter(['a', 'c', 'A', 'z', 'f'])) == 2
684 +
        >>> import ubelt as ub
685 +
        >>> assert ub.argmin({'a': 3, 'b': 2, 'c': 100}) == 'b'
686 +
        >>> assert ub.argmin(['a', 'c', 'b', 'z', 'f']) == 0
687 +
        >>> assert ub.argmin([[0, 1], [2, 3, 4], [5]], key=len) == 2
688 +
        >>> assert ub.argmin({'a': 3, 'b': 2, 3: 100, 4: 4}) == 'b'
689 +
        >>> assert ub.argmin(iter(['a', 'c', 'A', 'z', 'f'])) == 2
679 690
    """
680 691
    if key is None and isinstance(indexable, collections_abc.Mapping):
681 692
        return min(indexable.items(), key=operator.itemgetter(1))[0]

@@ -8,17 +8,17 @@
Loading
8 8
9 9
Use Case #1: You have data that you want to hash. If we assume the data is in
10 10
standard python scalars or ordered sequences: e.g.  tuple, list, odict, oset,
11 -
int, str, etc..., then the solution is `:func:hash_data`.
11 +
int, str, etc..., then the solution is :func:`hash_data`.
12 12
13 13
Use Case #2: You have a file you want to hash, but your system doesn't have a
14 14
sha1sum executable (or you dont want to use Popen). The solution is
15 -
`:func:hash_file`
15 +
:func:`hash_file`
16 16
17 -
The :func:`ub.hash_data` function recursively hashes most builtin python data
18 -
structures.
17 +
The :func:`ubelt.util_hash.hash_data` function recursively hashes most builtin
18 +
python data structures.
19 19
20 -
The :func:`ub.hash_file` function hashes data on disk.  Both of the
21 -
aformentioned functions have options for different hashers and alphabets.
20 +
The :func:`ubelt.util_hash.hash_file` function hashes data on disk.  Both of
21 +
the aformentioned functions have options for different hashers and alphabets.
22 22
23 23
24 24
Example:
@@ -273,7 +273,7 @@
Loading
273 273
    """
274 274
    Convert a string-based key into a hasher class
275 275
276 -
    Notes:
276 +
    Note:
277 277
        In terms of speed on 64bit systems, sha1 is the fastest followed by md5
278 278
        and sha512. The slowest algorithm is sha256. If xxhash is installed
279 279
        the fastest algorithm is xxh64.
@@ -366,7 +366,7 @@
Loading
366 366
    def __init__(self):
367 367
        self.keyed_extensions = {}
368 368
        self.iterable_checks = []
369 -
        self._lazy_queue = []         # type: List[Callable]
369 +
        self._lazy_queue = []  # type: List[Callable]  # NOQA
370 370
371 371
    def register(self, hash_types):
372 372
        """
@@ -961,8 +961,8 @@
Loading
961 961
962 962
        hasher (str | hashlib.HASH, default='sha512'):
963 963
            string code or a hash algorithm from hashlib. Valid hashing
964 -
            algorithms are defined by ``hashlib.algorithms_guaranteed`` (e.g.
965 -
            'sha1', 'sha512', 'md5') as well as 'xxh32' and 'xxh64' if
964 +
            algorithms are defined by :py:obj:`hashlib.algorithms_guaranteed`
965 +
            (e.g.  'sha1', 'sha512', 'md5') as well as 'xxh32' and 'xxh64' if
966 966
            :mod:`xxhash` is installed.
967 967
968 968
        base (List[str] | str, default='hex'):
@@ -986,7 +986,7 @@
Loading
986 986
            a custom :class:`HashableExtensions` instance that can overwrite or
987 987
            define how different types of objects are hashed.
988 988
989 -
    Notes:
989 +
    Note:
990 990
        The types allowed are specified by the  HashableExtensions object. By
991 991
        default ubelt will register:
992 992
@@ -998,7 +998,7 @@
Loading
998 998
    Returns:
999 999
        str: text representing the hashed data
1000 1000
1001 -
    Notes:
1001 +
    Note:
1002 1002
        The alphabet26 base is a pretty nice base, I recommend it.
1003 1003
        However we default to ``base='hex'`` because it is standard.
1004 1004
        You can try the alphabet26 base by setting ``base='abc'``.
@@ -1057,8 +1057,8 @@
Loading
1057 1057
1058 1058
        hasher (str | hashlib.HASH, default='sha512'):
1059 1059
            string code or a hash algorithm from hashlib. Valid hashing
1060 -
            algorithms are defined by ``hashlib.algorithms_guaranteed`` (e.g.
1061 -
            'sha1', 'sha512', 'md5') as well as 'xxh32' and 'xxh64' if
1060 +
            algorithms are defined by :py:obj:`hashlib.algorithms_guaranteed`
1061 +
            (e.g.  'sha1', 'sha512', 'md5') as well as 'xxh32' and 'xxh64' if
1062 1062
            :mod:`xxhash` is installed.
1063 1063
1064 1064
            TODO: add logic such that you can update an existing hasher
@@ -1071,10 +1071,10 @@
Loading
1071 1071
            list of symbols or shorthand key.
1072 1072
            Valid keys are 'abc', 'hex', and 'dec'.
1073 1073
1074 -
    Notes:
1075 -
        For better hashes keep stride = 1
1076 -
        For faster hashes set stride > 1
1077 -
        blocksize matters when stride > 1
1074 +
    Note:
1075 +
        For better hashes keep stride = 1.
1076 +
        For faster hashes set stride > 1.
1077 +
        Blocksize matters when stride > 1.
1078 1078
1079 1079
    References:
1080 1080
        http://stackoverflow.com/questions/3431825/md5-checksum-of-a-file

@@ -43,8 +43,9 @@
Loading
43 43
            uses ``sys.argv`` if unspecified
44 44
45 45
    Returns:
46 -
        str: value - the value specified after the key. It they key is
47 -
            specified multiple times, then the first value is returned.
46 +
        str:
47 +
            value - the value specified after the key. It they key is specified
48 +
            multiple times, then the first value is returned.
48 49
49 50
    TODO:
50 51
        - [ ] Can we handle the case where the value is a list of long paths?

@@ -35,12 +35,12 @@
Loading
35 35
        verbose (bool): verbosity flag
36 36
37 37
    Note:
38 -
        You probably should use `open(<fpath>).write(<to_write>)` instead.
39 -
        This function exists as a convenience for writing in Python2. After
40 -
        2020-01-01, we may consider deprecating the function.
38 +
        In CPython you may wan to use `open(<fpath>).write(<to_write>)`
39 +
        instead.  This function exists as a convenience for writing in Python2.
40 +
        After 2020-01-01, we may consider deprecating the function.
41 41
42 -
        NOTE: It turns out that `open(<fpath>).write(<to_write>)` does not work
43 -
        in pypy. See `https://pypy.org/compat.html`. This is a strong argument
42 +
        NOTE: In PyPy `open(<fpath>).write(<to_write>)` does not work. See
43 +
        `https://pypy.org/compat.html`. This is a strong argument
44 44
        for keeping this function.
45 45
46 46
    Example:
@@ -182,9 +182,9 @@
Loading
182 182
        verbose (bool): if True prints what is being done
183 183
184 184
    SeeAlso:
185 -
        :mod:`send2trash` - A cross-platform Python package for sending files
186 -
            to the trash instead of irreversibly deleting them.
187 -
            https://github.com/hsoft/send2trash
185 +
        `send2trash <https://github.com/hsoft/send2trash>`_ -
186 +
            A cross-platform Python package for sending files to the trash
187 +
            instead of irreversibly deleting them.
188 188
189 189
    Example:
190 190
        >>> import ubelt as ub

@@ -6,14 +6,15 @@
Loading
6 6
can be done either via an iterable interface or using the manual API. Using the
7 7
iterable inferface is most common.
8 8
9 -
ProgIter was originally developed independantly of ``tqdm``, but the newer
10 -
versions of this library have been designed to be compatible with tqdm-API.
11 -
``ProgIter`` is now a (mostly) drop-in alternative to tqdm_. The ``tqdm``
12 -
library may be more appropriate in some cases. *The main advantage of ``ProgIter``
13 -
is that it does not use any python threading*, and therefore can be safer with
14 -
code that makes heavy use of multiprocessing. `The reason`_ for this is that
15 -
threading before forking may cause locks to be duplicated across processes,
16 -
which may lead to deadlocks.
9 +
ProgIter was originally developed independantly of tqdm, but the newer versions
10 +
of this library have been designed to be compatible with tqdm-API.
11 +
:class:`ProgIter` is now a (mostly) drop-in alternative to :func:`tqdm.tqdm`. The
12 +
:mod:`tqdm` library may be more appropriate in some cases. *The main advantage of
13 +
:class:`ProgIter` is that it does not use any python threading*, and therefore can
14 +
be safer with code that makes heavy use of multiprocessing.
15 +
`The reason <https://pybay.com/site_media/slides/raymond2017-keynote/combo.html>`_
16 +
for this is that threading before forking may cause locks to be duplicated
17 +
across processes, which may lead to deadlocks.
17 18
18 19
ProgIter is simpler than tqdm, which may be desirable for some applications.
19 20
However, this also means ProgIter is not as extensible as tqdm.

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Everything is accounted for!

No changes detected that need to be reviewed.
What changes does Codecov check for?
Lines, not adjusted in diff, that have changed coverage data.
Files that introduced coverage data that had none before.
Files that have missing coverage data that once were tracked.
Files Coverage
ubelt 100.00%
Project Totals (29 files) 100.00%
Loading