Skip to content

Commit ba2ffd7

Browse files
authored
Merge pull request #18 from lschr/pipeline_doc
Pipeline decorator: Add option not to modify the doc string
2 parents c78f09a + c1d7769 commit ba2ffd7

File tree

1 file changed

+51
-11
lines changed

1 file changed

+51
-11
lines changed

slicerator.py

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ def key_to_indices(key, length):
328328

329329
def _index_generator(new_indices, old_indices):
330330
"""Find locations of new_indicies in the ref. frame of the old_indices.
331-
331+
332332
Example: (1, 3), (1, 3, 5, 10) -> (3, 10)
333333
334334
The point of all this trouble is that this is done lazily, returning
@@ -452,7 +452,7 @@ def __setstate__(self, data_as_list):
452452
return self.__init__(data_as_list, lambda x: x)
453453

454454

455-
def pipeline(func):
455+
def pipeline(func=None, **kwargs):
456456
"""Decorator to enable lazy evaluation of a function.
457457
458458
When the function is applied to a Slicerator or Pipeline object, it
@@ -469,22 +469,35 @@ def pipeline(func):
469469
--------
470470
Pipeline
471471
472-
Example
473-
-------
472+
Examples
473+
--------
474474
Apply the pipeline decorator to your image processing function.
475+
475476
>>> @pipeline
476477
... def color_channel(image, channel):
477478
... return image[channel, :, :]
478479
...
479480
481+
482+
In order to preserve the original function's doc string (i. e. do not add
483+
a note saying that it was made lazy), use the decorator like so:
484+
485+
>>> @pipeline(retain_doc=True)
486+
... def color_channel(image, channel):
487+
... '''This doc string will not be changed'''
488+
... return image[channel, :, :]
489+
490+
480491
Passing a Slicerator the function returns a Pipeline
481492
that "lazily" applies the function when the images come out. Different
482493
functions can be applied to the same underlying images, creating
483494
independent objects.
495+
484496
>>> red_images = color_channel(images, 0)
485497
>>> green_images = color_channel(images, 1)
486498
487499
Pipeline functions can also be composed.
500+
488501
>>> @pipeline
489502
... def rescale(image):
490503
... return (image - image.min())/image.ptp()
@@ -493,9 +506,35 @@ def pipeline(func):
493506
494507
The function can still be applied to ordinary images. The decorator
495508
only takes affect when a Slicerator object is passed.
509+
496510
>>> single_img = images[0]
497511
>>> red_img = red_channel(single_img) # normal behavior
498512
"""
513+
def wrapper(f):
514+
return _pipeline(f, **kwargs)
515+
516+
if func is None:
517+
return wrapper
518+
else:
519+
return wrapper(func)
520+
521+
522+
def _pipeline(func, retain_doc=False):
523+
"""Actual `pipeline` implementation
524+
525+
Parameters
526+
----------
527+
func : callable
528+
Function for lazy evaluation
529+
retain_doc : bool
530+
If True, don't modify `func`'s doc string to say that it has been
531+
made lazy
532+
533+
Returns
534+
-------
535+
Pipeline
536+
Lazy function evaluation :py:class:`Pipeline` for `func`.
537+
"""
499538
@wraps(func)
500539
def process(obj, *args, **kwargs):
501540
if hasattr(obj, '_slicerator_flag') or isinstance(obj, Slicerator) \
@@ -508,13 +547,14 @@ def proc_func(x):
508547
# as a single image.
509548
return func(obj, *args, **kwargs)
510549

511-
if process.__doc__ is None:
512-
process.__doc__ = ''
513-
process.__doc__ = ("This function has been made lazy. When passed\n"
514-
"a Slicerator, it will return a \n"
515-
"Pipeline of the results. When passed \n"
516-
"any other objects, its behavior is "
517-
"unchanged.\n\n") + process.__doc__
550+
if not retain_doc:
551+
if process.__doc__ is None:
552+
process.__doc__ = ''
553+
process.__doc__ = ("This function has been made lazy. When passed\n"
554+
"a Slicerator, it will return a \n"
555+
"Pipeline of the results. When passed \n"
556+
"any other objects, its behavior is "
557+
"unchanged.\n\n") + process.__doc__
518558
process.__name__ = func.__name__
519559
return process
520560

0 commit comments

Comments
 (0)