Erotemic / ubelt

@@ -102,6 +102,7 @@
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))
@@ -109,6 +110,7 @@
Loading
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]

@@ -4,10 +4,10 @@
Loading
4 4
5 5
The :func:`identity` function simply returns its own inputs. This is useful for
6 6
bypassing print statements and many other cases. I also think it looks a little
7 -
nicer than `lambda x: x`.
7 +
nicer than ``lambda x: x``.
8 8
9 -
The :func:`inject` function "injects" another function into a class instance as a
10 -
method. This is useful for monkey patching.
9 +
The :func:`inject_method` function "injects" another function into a class
10 +
instance as a method. This is useful for monkey patching.
11 11
"""
12 12
13 13
@@ -55,6 +55,7 @@
Loading
55 55
            specified the name of the function is used.
56 56
57 57
    Example:
58 +
        >>> import ubelt as ub
58 59
        >>> class Foo(object):
59 60
        >>>     def bar(self):
60 61
        >>>         return 'bar'
@@ -63,10 +64,10 @@
Loading
63 64
        >>> self = Foo()
64 65
        >>> assert self.bar() == 'bar'
65 66
        >>> assert not hasattr(self, 'baz')
66 -
        >>> inject_method(self, baz)
67 +
        >>> ub.inject_method(self, baz)
67 68
        >>> assert not hasattr(Foo, 'baz'), 'should only change one instance'
68 69
        >>> assert self.baz() == 'baz'
69 -
        >>> inject_method(self, baz, 'bar')
70 +
        >>> ub.inject_method(self, baz, 'bar')
70 71
        >>> assert self.bar() == 'baz'
71 72
    """
72 73
    # TODO: if func is a bound method we should probably unbind it
@@ -78,7 +79,7 @@
Loading
78 79
79 80
def compatible(config, func, start=0):
80 81
    """
81 -
    Take only the items of a dict that can be passed to function as kwargs
82 +
    Take the subset of dict items that can be passed to function as kwargs
82 83
83 84
    Args:
84 85
        config (dict):
@@ -89,19 +90,17 @@
Loading
89 90
90 91
        start (int, default=0):
91 92
            Only take args after this position. Set to 1 if calling with an
92 -
            unbound method to avoid the "self" argument.
93 +
            unbound method to avoid the ``self`` argument.
93 94
94 95
    Returns:
95 -
        dict : a subset of ``config`` that only contains items compatible with
96 -
            the signature of ``func``.
97 -
98 -
    TODO:
99 -
        - [ ] Move to util_func
96 +
        dict :
97 +
            a subset of ``config`` that only contains items compatible with the
98 +
            signature of ``func``.
100 99
101 100
    Example:
102 101
        >>> # An example use case is to select a subset of of a config
103 102
        >>> # that can be passed to some function as kwargs
104 -
        >>> from ubelt.util_candidate import *  # NOQA
103 +
        >>> import ubelt as ub
105 104
        >>> # Define a function with args that match some keys in a config.
106 105
        >>> def func(a, e, f):
107 106
        >>>     return a * e * f
@@ -111,23 +110,24 @@
Loading
111 110
        ...   'd': 11, 'e': 13, 'f': 17,
112 111
        ... }
113 112
        >>> # Call the function only with keys that are compatible
114 -
        >>> func(**compatible(config, func))
113 +
        >>> func(**ub.compatible(config, func))
115 114
        442
116 115
117 116
    Example:
118 117
        >>> # Test case with kwargs
119 -
        >>> from ubelt.util_candidate import *  # NOQA
118 +
        >>> import ubelt as ub
120 119
        >>> def func(a, e, f, *args, **kwargs):
121 120
        >>>     return a * e * f
122 121
        >>> config = {
123 122
        ...   'a': 2, 'b': 3, 'c': 7,
124 123
        ...   'd': 11, 'e': 13, 'f': 17,
125 124
        ... }
126 -
        >>> func(**compatible(config, func))
125 +
        >>> func(**ub.compatible(config, func))
127 126
128 127
    Ignore:
129 128
        >>> # xdoctest: +REQUIRES(PY3)
130 129
        >>> # Test case with positional only 3.x +
130 +
        >>> import ubelt as ub
131 131
        >>> def func(a, e, /,  f):
132 132
        >>>     return a * e * f
133 133
        >>> config = {
@@ -136,7 +136,7 @@
Loading
136 136
        ... }
137 137
        >>> import pytest
138 138
        >>> with pytest.raises(ValueError):
139 -
        ...     func(**compatible(config, func))
139 +
        ...     func(**ub.compatible(config, func))
140 140
    """
141 141
    import inspect
142 142
    if hasattr(inspect, 'signature'):  # pragma :nobranch

@@ -70,6 +70,7 @@
Loading
70 70
    Transforms function args into a key that can be used by the cache
71 71
72 72
    Example:
73 +
        >>> from ubelt.util_memoize import _make_signature_key
73 74
        >>> args = (4, [1, 2])
74 75
        >>> kwargs = {'a': 'b'}
75 76
        >>> key = _make_signature_key(args, kwargs)
@@ -119,7 +120,7 @@
Loading
119 120
        Callable: memoized wrapper
120 121
121 122
    References:
122 -
        https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
123 +
        .. [1] https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
123 124
124 125
    Example:
125 126
        >>> import ubelt as ub
@@ -160,7 +161,7 @@
Loading
160 161
    memoization decorator for a method that respects args and kwargs
161 162
162 163
    References:
163 -
        http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/
164 +
        .. [2] http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods
164 165
165 166
    Example:
166 167
        >>> import ubelt as ub
@@ -240,21 +241,22 @@
Loading
240 241
    This decorator can either be used by itself or by decorating another
241 242
    property. In either case the method will always become a property.
242 243
243 -
    Notes:
244 -
        implementation is a modified version of [1].
244 +
    Note:
245 +
        implementation is a modified version of [3]_.
245 246
246 247
    References:
247 -
        ..[1] https://github.com/estebistec/python-memoized-property
248 +
        .. [3] https://github.com/estebistec/python-memoized-property
248 249
249 250
    Example:
251 +
        >>> import ubelt as ub
250 252
        >>> class C(object):
251 253
        ...     load_name_count = 0
252 -
        ...     @memoize_property
254 +
        ...     @ub.memoize_property
253 255
        ...     def name(self):
254 256
        ...         "name's docstring"
255 257
        ...         self.load_name_count += 1
256 258
        ...         return "the name"
257 -
        ...     @memoize_property
259 +
        ...     @ub.memoize_property
258 260
        ...     @property
259 261
        ...     def another_name(self):
260 262
        ...         "name's docstring"

@@ -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

@@ -237,12 +237,13 @@
Loading
237 237
        **kwargs: only used to support deprecated arguments
238 238
239 239
    Returns:
240 -
        dict: info - information about command status.
240 +
        dict:
241 +
            info - information about command status.
241 242
            if detach is False ``info`` contains captured standard out,
242 243
            standard error, and the return code
243 244
            if detach is False ``info`` contains a reference to the process.
244 245
245 -
    Notes:
246 +
    Note:
246 247
        Inputs can either be text or tuple based. On UNIX we ensure conversion
247 248
        to text if shell=True, and to tuple if shell=False. On windows, the
248 249
        input is always text based.  See [3]_ for a potential cross-platform
@@ -259,36 +260,42 @@
Loading
259 260
        .. [3] https://stackoverflow.com/questions/33560364/python-windows-parsing-command-lines-with-shlex
260 261
261 262
    Example:
262 -
        >>> info = cmd(('echo', 'simple cmdline interface'), verbose=1)
263 +
        >>> import ubelt as ub
264 +
        >>> info = ub.cmd(('echo', 'simple cmdline interface'), verbose=1)
263 265
        simple cmdline interface
264 266
        >>> assert info['ret'] == 0
265 267
        >>> assert info['out'].strip() == 'simple cmdline interface'
266 268
        >>> assert info['err'].strip() == ''
267 269
268 270
    Example:
269 -
        >>> info = cmd('echo str noshell', verbose=0)
271 +
        >>> import ubelt as ub
272 +
        >>> info = ub.cmd('echo str noshell', verbose=0)
270 273
        >>> assert info['out'].strip() == 'str noshell'
271 274
272 275
    Example:
273 276
        >>> # windows echo will output extra single quotes
274 -
        >>> info = cmd(('echo', 'tuple noshell'), verbose=0)
277 +
        >>> import ubelt as ub
278 +
        >>> info = ub.cmd(('echo', 'tuple noshell'), verbose=0)
275 279
        >>> assert info['out'].strip().strip("'") == 'tuple noshell'
276 280
277 281
    Example:
278 282
        >>> # Note this command is formatted to work on win32 and unix
279 -
        >>> info = cmd('echo str&&echo shell', verbose=0, shell=True)
283 +
        >>> import ubelt as ub
284 +
        >>> info = ub.cmd('echo str&&echo shell', verbose=0, shell=True)
280 285
        >>> assert info['out'].strip() == 'str' + chr(10) + 'shell'
281 286
282 287
    Example:
283 -
        >>> info = cmd(('echo', 'tuple shell'), verbose=0, shell=True)
288 +
        >>> import ubelt as ub
289 +
        >>> info = ub.cmd(('echo', 'tuple shell'), verbose=0, shell=True)
284 290
        >>> assert info['out'].strip().strip("'") == 'tuple shell'
285 291
286 292
    Example:
287 293
        >>> import pytest
288 -
        >>> info = cmd('echo hi', check=True)
294 +
        >>> import ubelt as ub
295 +
        >>> info = ub.cmd('echo hi', check=True)
289 296
        >>> import subprocess
290 297
        >>> with pytest.raises(subprocess.CalledProcessError):
291 -
        >>>     cmd('exit 1', check=True, shell=True)
298 +
        >>>     ub.cmd('exit 1', check=True, shell=True)
292 299
293 300
    Example:
294 301
        >>> import ubelt as ub

@@ -164,9 +164,10 @@
Loading
164 164
        Dict[A, B]: similar to ``dict(zip(items1, items2))``.
165 165
166 166
    Example:
167 -
        >>> assert dzip([1, 2, 3], [4]) == {1: 4, 2: 4, 3: 4}
168 -
        >>> assert dzip([1, 2, 3], [4, 4, 4]) == {1: 4, 2: 4, 3: 4}
169 -
        >>> assert dzip([], [4]) == {}
167 +
        >>> import ubelt as ub
168 +
        >>> assert ub.dzip([1, 2, 3], [4]) == {1: 4, 2: 4, 3: 4}
169 +
        >>> assert ub.dzip([1, 2, 3], [4, 4, 4]) == {1: 4, 2: 4, 3: 4}
170 +
        >>> assert ub.dzip([], [4]) == {}
170 171
    """
171 172
    try:
172 173
        len(items1)
@@ -319,7 +320,7 @@
Loading
319 320
            least k times.
320 321
321 322
    Returns:
322 -
        dict[T: List[int]]:
323 +
        dict[T, List[int]] :
323 324
            maps each duplicate item to the indices at which it appears
324 325
325 326
    Example:
@@ -414,14 +415,17 @@
Loading
414 415
    SeeAlso:
415 416
        :func:`collections.ChainMap` - a standard python builtin data structure
416 417
        that provides a view that treats multiple dicts as a single dict.
417 -
        `https://docs.python.org/3/library/collections.html#chainmap-objects`
418 +
        `<https://docs.python.org/3/library/collections.html#chainmap-objects>`_
418 419
419 420
    Example:
420 -
        >>> result = dict_union({'a': 1, 'b': 1}, {'b': 2, 'c': 2})
421 +
        >>> import ubelt as ub
422 +
        >>> result = ub.dict_union({'a': 1, 'b': 1}, {'b': 2, 'c': 2})
421 423
        >>> assert result == {'a': 1, 'b': 2, 'c': 2}
422 -
        >>> dict_union(odict([('a', 1), ('b', 2)]), odict([('c', 3), ('d', 4)]))
424 +
        >>> ub.dict_union(
425 +
        >>>     ub.odict([('a', 1), ('b', 2)]),
426 +
        >>>     ub.odict([('c', 3), ('d', 4)]))
423 427
        OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
424 -
        >>> dict_union()
428 +
        >>> ub.dict_union()
425 429
        {}
426 430
    """
427 431
    if not args:
@@ -433,7 +437,7 @@
Loading
433 437
434 438
def dict_diff(*args):
435 439
    """
436 -
    Dictionary set extension for ``set.difference``
440 +
    Dictionary set extension for :func:`set.difference`
437 441
438 442
    Constructs a dictionary that contains any of the keys in the first arg,
439 443
    which are not in any of the following args.
@@ -450,13 +454,14 @@
Loading
450 454
          inplace.
451 455
452 456
    Example:
453 -
        >>> dict_diff({'a': 1, 'b': 1}, {'a'}, {'c'})
457 +
        >>> import ubelt as ub
458 +
        >>> ub.dict_diff({'a': 1, 'b': 1}, {'a'}, {'c'})
454 459
        {'b': 1}
455 -
        >>> dict_diff(odict([('a', 1), ('b', 2)]), odict([('c', 3)]))
460 +
        >>> ub.dict_diff(odict([('a', 1), ('b', 2)]), odict([('c', 3)]))
456 461
        OrderedDict([('a', 1), ('b', 2)])
457 -
        >>> dict_diff()
462 +
        >>> ub.dict_diff()
458 463
        {}
459 -
        >>> dict_diff({'a': 1, 'b': 2}, {'c'})
464 +
        >>> ub.dict_diff({'a': 1, 'b': 2}, {'c'})
460 465
    """
461 466
    if not args:
462 467
        return {}
@@ -475,7 +480,7 @@
Loading
475 480
476 481
def dict_isect(*args):
477 482
    """
478 -
    Dictionary set extension for ``set.intersection``
483 +
    Dictionary set extension for :func:`set.intersection`
479 484
480 485
    Constructs a dictionary that contains keys common between all inputs.
481 486
    The returned values will only belong to the first dictionary.
@@ -487,20 +492,22 @@
Loading
487 492
        Dict | OrderedDict :
488 493
            OrderedDict if the first argument is an OrderedDict, otherwise dict
489 494
490 -
    Notes:
495 +
    Note:
491 496
        This function can be used as an alternative to :func:`dict_subset`
492 497
        where any key not in the dictionary is ignored. See the following
493 498
        example:
494 499
495 -
        >>> dict_isect({'a': 1, 'b': 2, 'c': 3}, ['a', 'c', 'd'])
500 +
        >>> import ubelt as ub
501 +
        >>> ub.dict_isect({'a': 1, 'b': 2, 'c': 3}, ['a', 'c', 'd'])
496 502
        {'a': 1, 'c': 3}
497 503
498 504
    Example:
499 -
        >>> dict_isect({'a': 1, 'b': 1}, {'b': 2, 'c': 2})
505 +
        >>> import ubelt as ub
506 +
        >>> ub.dict_isect({'a': 1, 'b': 1}, {'b': 2, 'c': 2})
500 507
        {'b': 1}
501 -
        >>> dict_isect(odict([('a', 1), ('b', 2)]), odict([('c', 3)]))
508 +
        >>> ub.dict_isect(odict([('a', 1), ('b', 2)]), odict([('c', 3)]))
502 509
        OrderedDict()
503 -
        >>> dict_isect()
510 +
        >>> ub.dict_isect()
504 511
        {}
505 512
    """
506 513
    if not args:
@@ -527,15 +534,17 @@
Loading
527 534
        Dict[A, C]: transformed dictionary
528 535
529 536
    Example:
537 +
        >>> import ubelt as ub
530 538
        >>> dict_ = {'a': [1, 2, 3], 'b': []}
531 -
        >>> newdict = map_vals(len, dict_)
539 +
        >>> newdict = ub.map_vals(len, dict_)
532 540
        >>> assert newdict ==  {'a': 3, 'b': 0}
533 541
534 542
    Example:
535 543
        >>> # Can also use an indexable as ``func``
544 +
        >>> import ubelt as ub
536 545
        >>> dict_ = {'a': 0, 'b': 1}
537 546
        >>> func = [42, 21]
538 -
        >>> newdict = map_vals(func, dict_)
547 +
        >>> newdict = ub.map_vals(func, dict_)
539 548
        >>> assert newdict ==  {'a': 42, 'b': 21}
540 549
        >>> print(newdict)
541 550
    """
@@ -565,14 +574,15 @@
Loading
565 574
        Exception : if multiple keys map to the same value
566 575
567 576
    Example:
577 +
        >>> import ubelt as ub
568 578
        >>> dict_ = {'a': [1, 2, 3], 'b': []}
569 579
        >>> func = ord
570 -
        >>> newdict = map_keys(func, dict_)
580 +
        >>> newdict = ub.map_keys(func, dict_)
571 581
        >>> print(newdict)
572 582
        >>> assert newdict == {97: [1, 2, 3], 98: []}
573 583
        >>> dict_ = {0: [1, 2, 3], 1: []}
574 584
        >>> func = ['a', 'b']
575 -
        >>> newdict = map_keys(func, dict_)
585 +
        >>> newdict = ub.map_keys(func, dict_)
576 586
        >>> print(newdict)
577 587
        >>> assert newdict == {'a': [1, 2, 3], 'b': []}
578 588
    """
@@ -681,7 +691,7 @@
Loading
681 691
        Dict[B, A] | Dict[B, Set[A]]:
682 692
            the inverted dictionary
683 693
684 -
    Notes:
694 +
    Note:
685 695
        The must values be hashable.
686 696
687 697
        If the original dictionary contains duplicate values, then only one of
@@ -748,10 +758,11 @@
Loading
748 758
            possible values for that "axes".
749 759
750 760
    Yields:
751 -
        Dict[K, T] - a "row" in the "longform" data containing a point in the
752 -
            Cartesian product.
761 +
        Dict[K, T] -
762 +
            a "row" in the "longform" data containing a point in the Cartesian
763 +
            product.
753 764
754 -
    Notes:
765 +
    Note:
755 766
        This function is similar to :func:`itertools.product`, the only
756 767
        difference is that the generated items are a dictionary that retains
757 768
        the input keys instead of an tuple.

@@ -86,6 +86,7 @@
Loading
86 86
        newpath = pref_bar_suff.baz
87 87
88 88
    Example:
89 +
        >>> from ubelt.util_path import *  # NOQA
89 90
        >>> augpath('foo.bar')
90 91
        'foo.bar'
91 92
        >>> augpath('foo.bar', ext='.BAZ')
@@ -153,6 +154,7 @@
Loading
153 154
            inferred
154 155
155 156
    Example:
157 +
        >>> from ubelt.util_path import *  # NOQA
156 158
        >>> import getpass
157 159
        >>> username = getpass.getuser()
158 160
        >>> assert userhome() == expanduser('~')
@@ -208,6 +210,7 @@
Loading
208 210
        str: path - shortened path replacing the home directory with a tilde
209 211
210 212
    Example:
213 +
        >>> from ubelt.util_path import *  # NOQA
211 214
        >>> path = expanduser('~')
212 215
        >>> assert path != '~'
213 216
        >>> assert shrinkuser(path) == '~'
@@ -240,6 +243,7 @@
Loading
240 243
        str : expanded path
241 244
242 245
    Example:
246 +
        >>> from ubelt.util_path import *  # NOQA
243 247
        >>> import ubelt as ub
244 248
        >>> assert normpath(ub.expandpath('~/foo')) == join(ub.userhome(), 'foo')
245 249
        >>> assert ub.expandpath('foo') == 'foo'
@@ -270,7 +274,7 @@
Loading
270 274
        This function is not thread-safe in Python2
271 275
272 276
    Example:
273 -
        >>> from ubelt.util_platform import *  # NOQA
277 +
        >>> from ubelt.util_path import *  # NOQA
274 278
        >>> import ubelt as ub
275 279
        >>> cache_dpath = ub.ensure_app_cache_dir('ubelt')
276 280
        >>> dpath = join(cache_dpath, 'ensuredir')
@@ -308,12 +312,14 @@
Loading
308 312
    Context for creating and cleaning up temporary directories.
309 313
310 314
    Example:
315 +
        >>> from ubelt.util_path import *  # NOQA
311 316
        >>> with TempDir() as self:
312 317
        >>>     dpath = self.dpath
313 318
        >>>     assert exists(dpath)
314 319
        >>> assert not exists(dpath)
315 320
316 321
    Example:
322 +
        >>> from ubelt.util_path import *  # NOQA
317 323
        >>> self = TempDir()
318 324
        >>> dpath = self.ensure()
319 325
        >>> assert exists(dpath)

@@ -26,7 +26,7 @@
Loading
26 26
References:
27 27
    .. [1] https://no-color.org/
28 28
29 -
Notes:
29 +
Note:
30 30
    In the future we may rename this module to ``util_ansi``.
31 31
32 32
Requirements:
@@ -54,8 +54,9 @@
Loading
54 54
        **kwargs: passed to pygments.lexers.get_lexer_by_name
55 55
56 56
    Returns:
57 -
        str: text - highlighted text
58 -
            If pygments is not installed, the plain text is returned.
57 +
        str:
58 +
            text - highlighted text If pygments is not installed, the plain
59 +
            text is returned.
59 60
60 61
    Example:
61 62
        >>> import ubelt as ub
@@ -113,8 +114,9 @@
Loading
113 114
            'blue', 'black', and 'white'.
114 115
115 116
    Returns:
116 -
        str: text - colorized text.
117 -
            If pygments is not installed plain text is returned.
117 +
        str:
118 +
            text - colorized text.  If pygments is not installed plain text is
119 +
            returned.
118 120
119 121
    Example:
120 122
        >>> text = 'raw text'

@@ -27,7 +27,8 @@
Loading
27 27
        method (str, default='iso8601'): type of timestamp
28 28
29 29
    Example:
30 -
        >>> stamp = timestamp()
30 +
        >>> import ubelt as ub
31 +
        >>> stamp = ub.timestamp()
31 32
        >>> print('stamp = {!r}'.format(stamp))
32 33
        stamp = ...-...-...T...
33 34
    """

@@ -261,32 +261,47 @@
Loading
261 261
        self.executor.__exit__(a, b, c)
262 262
263 263
    def as_completed(self):
264 -
        for job in as_completed(self.jobs):
265 -
            yield job
266 -
267 -
    def __iter__(self):
268 264
        """
265 +
        Generates completed jobs in an arbitrary order
266 +
267 +
        Yields:
268 +
            concurrent.futures.Future
269 +
269 270
        CommandLine:
270 -
            xdoctest -m /home/joncrall/code/ubelt/ubelt/util_futures.py JobPool.__iter__
271 +
            xdoctest -m ubelt.util_futures JobPool.as_completed
271 272
272 273
        Example:
273 274
            >>> import ubelt as ub
274 275
            >>> pool = ub.JobPool('thread', max_workers=8)
275 276
            >>> text = ub.paragraph(
276 -
                '''
277 -
                UDP is a cool protocol, check out the wiki:
278 -
279 -
                UDP-based Data Transfer Protocol (UDT), is a high-performance
280 -
                data transfer protocol designed for transferring large
281 -
                volumetric datasets over high-speed wide area networks. Such
282 -
                settings are typically disadvantageous for the more common TCP
283 -
                protocol.
284 -
                ''')
277 +
            ...     '''
278 +
            ...     UDP is a cool protocol, check out the wiki:
279 +
            ...
280 +
            ...     UDP-based Data Transfer Protocol (UDT), is a high-performance
281 +
            ...     data transfer protocol designed for transferring large
282 +
            ...     volumetric datasets over high-speed wide area networks. Such
283 +
            ...     settings are typically disadvantageous for the more common TCP
284 +
            ...     protocol.
285 +
            ...     ''')
285 286
            >>> for word in text.split(' '):
286 287
            ...     pool.submit(print, word)
287 -
            >>> for _ in pool:
288 +
            >>> for _ in pool.as_completed():
288 289
            ...     pass
289 290
            >>> pool.shutdown()
290 291
        """
292 +
        for job in as_completed(self.jobs):
293 +
            yield job
294 +
295 +
    def __iter__(self):
296 +
        """
297 +
        An alternative to as completed
298 +
299 +
        Example:
300 +
            >>> import ubelt as ub
301 +
            >>> pool = ub.JobPool('serial')
302 +
            >>> assert len(list(iter(pool))) == 0
303 +
            >>> pool.submit(print, 'hi')
304 +
            >>> assert len(list(iter(pool))) == 1
305 +
        """
291 306
        for job in self.as_completed():
292 307
            yield job

@@ -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?

@@ -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.

@@ -2,7 +2,7 @@
Loading
2 2
"""
3 3
Functions for working with text and strings.
4 4
5 -
The :func:`ensure_unicode` function does its best to coerce python 2/3 bytes
5 +
The :func:`ensure_unicode` function does its best to coerce Python 2/3 bytes
6 6
and text into a consistent unicode text representation.
7 7
8 8
The :func:`codeblock` and :func:`paragraph` wrap multiline strings to help
@@ -47,11 +47,11 @@
Loading
47 47
        str: indented text
48 48
49 49
    Example:
50 -
        >>> from ubelt.util_str import *  # NOQA
50 +
        >>> import ubelt as ub
51 51
        >>> NL = chr(10)  # newline character
52 52
        >>> text = 'Lorem ipsum' + NL + 'dolor sit amet'
53 53
        >>> prefix = '    '
54 -
        >>> result = indent(text, prefix)
54 +
        >>> result = ub.indent(text, prefix)
55 55
        >>> assert all(t.startswith(prefix) for t in result.split(NL))
56 56
    """
57 57
    return prefix + text.replace('\n', '\n' + prefix)
@@ -71,11 +71,11 @@
Loading
71 71
        str: the unindented string
72 72
73 73
    Example:
74 -
        >>> from ubelt.util_str import *  # NOQA
74 +
        >>> import ubelt as ub
75 75
        >>> # Simulate an indented part of code
76 76
        >>> if True:
77 77
        >>>     # notice the indentation on this will be normal
78 -
        >>>     codeblock_version = codeblock(
78 +
        >>>     codeblock_version = ub.codeblock(
79 79
        ...             '''
80 80
        ...             def foo():
81 81
        ...                 return 'bar'
@@ -110,14 +110,14 @@
Loading
110 110
        str: the reduced text block
111 111
112 112
    Example:
113 -
        >>> from ubelt.util_str import *  # NOQA
113 +
        >>> import ubelt as ub
114 114
        >>> text = (
115 115
        >>>     '''
116 116
        >>>     Lorem ipsum dolor sit amet, consectetur adipiscing
117 117
        >>>     elit, sed do eiusmod tempor incididunt ut labore et
118 118
        >>>     dolore magna aliqua.
119 119
        >>>     ''')
120 -
        >>> out = paragraph(text)
120 +
        >>> out = ub.paragraph(text)
121 121
        >>> assert chr(10) in text
122 122
        >>> assert chr(10) not in out
123 123
        >>> print('text = {!r}'.format(text))
@@ -149,7 +149,6 @@
Loading
149 149
             [3, 457]]    [7, 8]]
150 150
151 151
    Example2:
152 -
        >>> from ubelt.util_str import *
153 152
        >>> import ubelt as ub
154 153
        >>> import unicodedata
155 154
        >>> aa = unicodedata.normalize('NFD', 'á')  # a unicode char with len2

@@ -11,7 +11,7 @@
Loading
11 11
12 12
    Attributes:
13 13
        download_root (PathLike): default download location
14 -
        jobs (List[DownloadFuture]): list of jobs
14 +
        jobs (List[concurrent.futures.Future]): list of jobs
15 15
16 16
    Example:
17 17
        >>> # xdoctest: +REQUIRES(--network)
@@ -93,6 +93,10 @@
Loading
93 93
               If specified, verifies that the hash of the downloaded file starts with this.
94 94
            hasher (str, default='sha256'):
95 95
                hashing algorithm to use if hash_prefix is specified.
96 +
97 +
        Returns:
98 +
            concurrent.futures.Future :
99 +
                a Future object that will point to the downloaded location.
96 100
        """
97 101
        job = self.pool.submit(
98 102
            self.dl_func, url, fname=dst, dpath=self.download_root,

@@ -2,15 +2,15 @@
Loading
2 2
r"""
3 3
Expose functions to simplify importing from module names and paths.
4 4
5 -
The :func:`ub.import_module_from_path` function does its best to load a python file
6 -
into th current set of global modules.
5 +
The :func:`ubelt.import_module_from_path` function does its best to load a
6 +
python file into th current set of global modules.
7 7
8 -
The :func:`ub.import_module_from_name` works similarly.
8 +
The :func:`ubelt.import_module_from_name` works similarly.
9 9
10 -
The :func:`ub.modname_to_modpath` and :func:`ub.modname_to_modpath` work
10 +
The :func:`ubelt.modname_to_modpath` and :func:`ubelt.modname_to_modpath` work
11 11
statically and convert between module names and file paths on disk.
12 12
13 -
The :func:`ub.split_modpath` function separates modules into a root and base
13 +
The :func:`ubelt.split_modpath` function separates modules into a root and base
14 14
path depending on where the first ``__init__.py`` file is.
15 15
"""
16 16
from __future__ import absolute_import, division, print_function, unicode_literals
@@ -152,12 +152,15 @@
Loading
152 152
153 153
        For example if you try to import '/foo/bar/pkg/mod.py' from the folder
154 154
        structure:
155 -
          - foo/
156 -
            +- bar/
157 -
               +- pkg/
158 -
                  +  __init__.py
159 -
                  |- mod.py
160 -
                  |- helper.py
155 +
156 +
        .. code::
157 +
158 +
            - foo/
159 +
              +- bar/
160 +
                 +- pkg/
161 +
                    +  __init__.py
162 +
                    |- mod.py
163 +
                    |- helper.py
161 164
162 165
       If there exists another module named ``pkg`` already in sys.modules
163 166
       and mod.py does something like ``from . import helper``, Python will
@@ -231,7 +234,7 @@
Loading
231 234
232 235
def import_module_from_name(modname):
233 236
    """
234 -
    Imports a module from its string name (__name__)
237 +
    Imports a module from its string name (i.e. ``__name__``)
235 238
236 239
    Args:
237 240
        modname (str):  module name

@@ -6,14 +6,15 @@
Loading
6 6
7 7
Two main goals of repr2 are to provide nice string representations of nested
8 8
data structures and make those "eval-able" whenever possible. As an example
9 -
take the value `float('inf')`, which normaly has a non-evalable repr of `inf`:
9 +
take the value ``float('inf')``, which normaly has a non-evalable repr of
10 +
``inf``:
10 11
11 12
>>> import ubelt as ub
12 13
>>> ub.repr2(float('inf'))
13 14
"float('inf')"
14 15
15 -
The `newline` (or `nl`) keyword argument can control how deep in the nesting
16 -
newlines are allowed.
16 +
The ``newline`` (or ``nl``) keyword argument can control how deep in the
17 +
nesting newlines are allowed.
17 18
18 19
>>> print(ub.repr2({1: float('nan'), 2: float('inf'), 3: 3.0}))
19 20
{
@@ -73,7 +74,7 @@
Loading
73 74
    produce strings that are consistent, compact, and executable.  This makes
74 75
    them great for doctests.
75 76
76 -
    Notes:
77 +
    Note:
77 78
        This function has many keyword arguments that can be used to customize
78 79
        the final representation. For convinience some of the more frequently
79 80
        used kwargs have short aliases. See "Kwargs" for more details.
@@ -173,7 +174,7 @@
Loading
173 174
    Returns:
174 175
        str: outstr - output string
175 176
176 -
    Notes:
177 +
    Note:
177 178
        There are also internal kwargs, which should not be used:
178 179
179 180
            _return_info (bool):  return information about child context

@@ -29,7 +29,7 @@
Loading
29 29
    xdoctest ubelt
30 30
"""
31 31
32 -
__version__ = '0.10.0'
32 +
__version__ = '0.10.1'
33 33
34 34
__submodules__ = [
35 35
    'util_arg',

@@ -31,8 +31,9 @@
Loading
31 31
        redirect (io.IOBase): The other stream to write to.
32 32
33 33
    Example:
34 +
        >>> import ubelt as ub
34 35
        >>> redirect = io.StringIO()
35 -
        >>> self = TeeStringIO(redirect)
36 +
        >>> self = ub.TeeStringIO(redirect)
36 37
    """
37 38
    def __init__(self, redirect=None):
38 39
        self.redirect = redirect  # type: io.IOBase
@@ -84,12 +85,13 @@
Loading
84 85
        Gets the encoding of the `redirect` IO object
85 86
86 87
        Example:
88 +
            >>> import ubelt as ub
87 89
            >>> redirect = io.StringIO()
88 -
            >>> assert TeeStringIO(redirect).encoding is None
89 -
            >>> assert TeeStringIO(None).encoding is None
90 -
            >>> assert TeeStringIO(sys.stdout).encoding is sys.stdout.encoding
90 +
            >>> assert ub.TeeStringIO(redirect).encoding is None
91 +
            >>> assert ub.TeeStringIO(None).encoding is None
92 +
            >>> assert ub.TeeStringIO(sys.stdout).encoding is sys.stdout.encoding
91 93
            >>> redirect = io.TextIOWrapper(io.StringIO())
92 -
            >>> assert TeeStringIO(redirect).encoding is redirect.encoding
94 +
            >>> assert ub.TeeStringIO(redirect).encoding is redirect.encoding
93 95
        """
94 96
        if self.redirect is not None:
95 97
            return self.redirect.encoding
@@ -133,7 +135,8 @@
Loading
133 135
            does nothing if this is False
134 136
135 137
    Example:
136 -
        >>> self = CaptureStdout(supress=True)
138 +
        >>> import ubelt as ub
139 +
        >>> self = ub.CaptureStdout(supress=True)
137 140
        >>> print('dont capture the table flip (╯°□°)╯︵ ┻━┻')
138 141
        >>> with self:
139 142
        ...     text = 'capture the heart ♥'
@@ -144,13 +147,15 @@
Loading
144 147
        >>> assert self.text == text + '\n', 'failed capture text'
145 148
146 149
    Example:
147 -
        >>> self = CaptureStdout(supress=False)
150 +
        >>> import ubelt as ub
151 +
        >>> self = ub.CaptureStdout(supress=False)
148 152
        >>> with self:
149 153
        ...     print('I am captured and printed in stdout')
150 154
        >>> assert self.text.strip() == 'I am captured and printed in stdout'
151 155
152 156
    Example:
153 -
        >>> self = CaptureStdout(supress=True, enabled=False)
157 +
        >>> import ubelt as ub
158 +
        >>> self = ub.CaptureStdout(supress=True, enabled=False)
154 159
        >>> with self:
155 160
        ...     print('dont capture')
156 161
        >>> assert self.text is None
@@ -187,8 +192,9 @@
Loading
187 192
    def stop(self):
188 193
        """
189 194
        Example:
190 -
            >>> CaptureStdout(enabled=False).stop()
191 -
            >>> CaptureStdout(enabled=True).stop()
195 +
            >>> import ubelt as ub
196 +
            >>> ub.CaptureStdout(enabled=False).stop()
197 +
            >>> ub.CaptureStdout(enabled=True).stop()
192 198
        """
193 199
        if self.enabled:
194 200
            self.started = False
Files Coverage
ubelt 100.00%
Project Totals (29 files) 100.00%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading