1- '''
1+ """
22Utility functions for use in function pipelines.
3- '''
3+ """
44import functools
55import typing as tp
66
1515
1616
1717def node (_func = None , * , name = None ):
18- ''' Turn the decorated function into a MetaFunction.
18+ """ Turn the decorated function into a MetaFunction.
1919
2020 Args:
2121 _func: Internal use. This will be the decorated function if node is used as a decorator
@@ -26,10 +26,12 @@ def node(_func=None, *, name=None):
2626 @node
2727 def f(x):
2828 <do something cool>
29- '''
29+ """
30+
3031 def decorator (function ):
3132 newfunc = SimpleFunction (function , name = name )
3233 return newfunc
34+
3335 if not _func :
3436 return decorator
3537 return decorator (_func )
@@ -38,50 +40,60 @@ def decorator(function):
3840def bind_call_state (func ):
3941 @functools .wraps (func )
4042 def provides_call_state (* args , ** kwargs ):
41- call_state = kwargs .pop (' call_state' )
43+ call_state = kwargs .pop (" call_state" )
4244 return func (call_state , * args , ** kwargs )
45+
4346 provides_call_state ._receives_call_state = True
4447 return provides_call_state
4548
4649
4750def star (meta_function : MetaFunction ) -> MetaFunction :
48- '''
51+ """
4952 star calls its Metafunction with *x instead of x.
50- '''
53+ """
5154 fname = str (meta_function )
52- #This convoluted inline `if` just decides whether we should add brackets or not.
53- @node (name = 'star{}' .format (fname ) if fname .startswith ('(' ) else 'star({})' .format (fname ))
55+ # This convoluted inline `if` just decides whether we should add brackets or not.
56+ @node (
57+ name = "star{}" .format (fname )
58+ if fname .startswith ("(" )
59+ else "star({})" .format (fname )
60+ )
5461 @functools .wraps (meta_function )
5562 def wrapper (args , ** kwargs ):
5663 return meta_function (* args , ** kwargs )
64+
5765 return wrapper
5866
5967
6068def store (key ):
61- '''Store the received output in the meta data dictionary under the given key.'''
69+ """Store the received output in the meta data dictionary under the given key."""
70+
6271 @node (name = "store('{}')" .format (key ))
6372 @bind_call_state
6473 def storer (call_state , val ):
6574 call_state .data [key ] = val
6675 return val
76+
6777 return storer
6878
6979
70- def recall (key , from_call_state : CallState = None ):
71- ''' Retrieve the given key from the meta data dictionary. Optionally, use `from_call_state` to
80+ def recall (key , from_call_state : CallState = None ):
81+ """ Retrieve the given key from the meta data dictionary. Optionally, use `from_call_state` to
7282 specify a different call_state than the current one.
73- '''
83+ """
84+
7485 @node (name = "recall('{}')" .format (key ))
7586 @bind_call_state
7687 def recaller (call_state , * _ ):
7788 if from_call_state :
7889 return from_call_state .data [key ]
7990 return call_state .data [key ]
91+
8092 return recaller
8193
8294
8395def concurrent (function : FunctionMerge ) -> ConcurrentMerge :
84- '''
96+ """
8597 Upgrade the specified FunctionMerge object to a ConcurrentMerge, which runs each of its
8698 component functions in separate processes. See ConcurrentMerge documentation for more
8799 information.
@@ -90,46 +102,51 @@ def concurrent(function: FunctionMerge) -> ConcurrentMerge:
90102
91103 c = concurrent(long_running_function + other_long_running_function)
92104 c(input_data) # The two functions run in parallel
93- '''
105+ """
94106 return ConcurrentMerge (function )
95107
96108
97- def mmap (function : tp .Callable , operator : tp .Callable = operators .concat ) -> MergeMap :
98- '''
109+ def mmap (function : tp .Callable , operator : tp .Callable = operators .concat ) -> MergeMap :
110+ """
99111 Upgrade the specified function to a MergeMap, which calls its single function once per input,
100112 as per the builtin `map` (https://docs.python.org/3.6/library/functions.html#map).
101113
102114 Consider the name 'mmap' to be a placeholder for now.
103- '''
115+ """
104116 return MergeMap (MetaFunction .make_meta (function ), operator )
105117
106118
107- def locate_error (meta_function : MetaFunction ,
108- use_color = util .system_supports_color ()) -> SimpleFunction :
109- '''
119+ def locate_error (
120+ meta_function : MetaFunction , use_color = util .system_supports_color ()
121+ ) -> SimpleFunction :
122+ """
110123 Wrap the given MetaFunction with an error handler that adds location information to any
111124 exception raised therein.
112125
113126 Usage:
114127 cmp = locate_error(a | b | c)
115128 cmp()
116- '''
129+ """
130+
117131 def with_location (* args , call_state , ** kwargs ):
118132 new_e = None
119133 try :
120134 return meta_function (* args , call_state = call_state , ** kwargs )
121135 except Exception as e :
122- if hasattr (e , ' location' ) and e .location :
136+ if hasattr (e , " location" ) and e .location :
123137 # If the exception has location info attached
124138 location = e .location
125139 else :
126140 location = call_state .highlight_active_function ()
127141
128142 if use_color :
129143 location = util .color_highlights (location )
130- detailed_message = ("{0!s} \n \n Occured in the following function: {1}" .format (e , location ))
144+ detailed_message = (
145+ "{0!s} \n \n Occured in the following function: {1}" .format (e , location )
146+ )
131147 new_e = type (e )(detailed_message ).with_traceback (e .__traceback__ )
132148 new_e .__cause__ = e .__cause__
133149 raise new_e
150+
134151 with_location ._receives_call_state = True
135152 return node (with_location , name = str (meta_function ))
0 commit comments