0
# Utilities
1
2
Functional utilities for promise creation, modification, and composition. These utilities provide convenient ways to work with promises and enable advanced promise patterns.
3
4
## Capabilities
5
6
### Promise Creation Utilities
7
8
Utilities for creating and ensuring promises from various inputs.
9
10
```python { .api }
11
def maybe_promise(p):
12
"""
13
Return None if p is undefined, otherwise ensure it's a promise.
14
15
Parameters:
16
- p: any object that can be converted to a promise
17
18
Returns:
19
- None if p is falsy, otherwise a promise object
20
"""
21
22
def ensure_promise(p):
23
"""
24
Ensure p is a promise, create empty promise if None.
25
26
Parameters:
27
- p: object to convert to promise, or None
28
29
Returns:
30
- promise object (empty promise if p was None)
31
"""
32
33
def starpromise(fun, *args, **kwargs):
34
"""
35
Create promise using star arguments.
36
37
Parameters:
38
- fun: function for the promise
39
- *args: positional arguments tuple
40
- **kwargs: keyword arguments dict
41
42
Returns:
43
- promise object configured with the provided arguments
44
"""
45
```
46
47
**Usage Examples:**
48
49
```python
50
from vine import maybe_promise, ensure_promise, starpromise
51
52
# maybe_promise - conditional promise creation
53
def handle_input(value):
54
p = maybe_promise(value) # None if value is falsy, promise otherwise
55
if p:
56
p.then(process_value)
57
return p
58
59
# ensure_promise - guarantee promise object
60
def chain_operation(callback):
61
p = ensure_promise(callback) # Creates empty promise if None
62
return p.then(next_operation)
63
64
# Create pre-fulfilled promise manually
65
def get_cached_data():
66
if cache_hit:
67
p = promise(lambda: cached_value)
68
p() # Fulfill immediately
69
return p
70
else:
71
return promise(fetch_from_database)
72
73
# starpromise - promise with star args
74
def async_math_operation():
75
return starpromise(complex_calculation, 10, 20, method='fast')
76
```
77
78
### Promise Modification Utilities
79
80
Utilities for modifying promise arguments and behavior.
81
82
```python { .api }
83
def ppartial(p, *args, **kwargs):
84
"""
85
Create/modify promise with partial arguments.
86
87
Parameters:
88
- p: promise to modify (created if None)
89
- *args: positional arguments to prepend
90
- **kwargs: keyword arguments to update
91
92
Returns:
93
- modified promise with combined arguments
94
"""
95
96
def preplace(p, *args, **kwargs):
97
"""
98
Replace promise arguments completely.
99
100
Forces promise to ignore fulfillment arguments and use provided args instead.
101
102
Parameters:
103
- p: promise to wrap
104
- *args: replacement positional arguments
105
- **kwargs: replacement keyword arguments
106
107
Returns:
108
- new promise that calls original with replacement arguments
109
"""
110
```
111
112
**Usage Examples:**
113
114
```python
115
from vine import ppartial, preplace, promise
116
117
# ppartial - add arguments to existing promise
118
def log_with_prefix(message, prefix="INFO"):
119
print(f"{prefix}: {message}")
120
121
log_promise = promise(log_with_prefix)
122
123
# Add partial arguments
124
error_logger = ppartial(log_promise, prefix="ERROR")
125
error_logger("Something went wrong") # Prints: ERROR: Something went wrong
126
127
# preplace - completely replace arguments
128
def greet(name, greeting="Hello"):
129
return f"{greeting}, {name}!"
130
131
greet_promise = promise(greet)
132
133
# Force specific arguments regardless of how promise is called
134
spanish_greet = preplace(greet_promise, "Mundo", greeting="Hola")
135
result = spanish_greet("This will be ignored") # Returns: "Hola, Mundo!"
136
```
137
138
### Promise Transformation Utilities
139
140
Utilities for transforming promise results and chaining patterns.
141
142
```python { .api }
143
def transform(filter_, callback, *filter_args, **filter_kwargs):
144
"""
145
Filter/transform final argument to a promise through a transform function.
146
147
Parameters:
148
- filter_: function to transform the promise result
149
- callback: target callback to receive transformed result
150
- *filter_args: additional arguments for filter function
151
- **filter_kwargs: additional keyword arguments for filter function
152
153
Returns:
154
- promise that applies filter to result before passing to callback
155
"""
156
157
def wrap(p):
158
"""
159
Wrap promise to handle promise arguments specially.
160
161
If called with a promise as argument, chains to that promise instead
162
of treating it as a regular argument.
163
164
Parameters:
165
- p: promise to wrap
166
167
Returns:
168
- wrapped function that handles promise arguments
169
"""
170
```
171
172
**Usage Examples:**
173
174
```python
175
from vine import transform, wrap, promise
176
177
# transform - filter promise results
178
def get_user_age(user_id, callback):
179
# Transform the user object to extract just the age
180
return fetch_user(user_id, transform(
181
lambda user: user['age'], # Filter function
182
callback # Target callback
183
))
184
185
# More complex transform with additional arguments
186
def extract_and_convert(key, converter, data):
187
return converter(data[key])
188
189
def get_page_expires(url, callback):
190
return fetch_page_data(url, transform(
191
extract_and_convert, # Filter function
192
callback, # Target callback
193
'expires', # Additional arg: key to extract
194
converter=int # Additional kwarg: conversion function
195
))
196
197
# wrap - handle promise arguments specially
198
def processor(data):
199
return f"Processed: {data}"
200
201
wrapped_processor = wrap(promise(processor))
202
203
# Regular call
204
result1 = wrapped_processor("hello") # Normal processing
205
206
# Promise argument - chains instead of processing the promise object
207
input_promise = promise(lambda: "async data")
208
result2 = wrapped_processor(input_promise) # Chains to input_promise
209
input_promise() # Triggers chain
210
```
211
212
## Advanced Usage
213
214
### Complex Promise Composition
215
216
```python
217
from vine import *
218
219
def build_processing_pipeline():
220
# Create base operations
221
validate = promise(validate_data)
222
transform_op = promise(transform_data)
223
save = promise(save_to_database)
224
225
# Compose complex pipeline
226
def process_with_logging(data):
227
# Add logging to each step
228
logged_validate = ppartial(validate, logger=logger)
229
230
# Transform result before saving
231
filtered_save = transform(
232
lambda result: {'processed': result, 'timestamp': time.now()},
233
save
234
)
235
236
# Chain operations
237
return logged_validate(data).then(transform_op).then(filtered_save)
238
239
return process_with_logging
240
```
241
242
### Dynamic Promise Building
243
244
```python
245
def build_conditional_promise(condition, success_func, failure_func):
246
if condition:
247
return ensure_promise(success_func)
248
else:
249
# Create promise that immediately fails
250
p = promise()
251
p.throw(ValueError("Condition not met"))
252
return p
253
254
# Usage
255
def fetch_user_data(user_id, has_permission):
256
fetch_promise = build_conditional_promise(
257
has_permission,
258
lambda: fetch_from_database(user_id),
259
lambda: "Access denied"
260
)
261
262
return fetch_promise
263
```
264
265
### Promise Argument Manipulation
266
267
```python
268
# Create a promise that always gets the same arguments
269
def create_fixed_args_promise(func, *fixed_args, **fixed_kwargs):
270
base_promise = promise(func)
271
return preplace(base_promise, *fixed_args, **fixed_kwargs)
272
273
# Create a promise with dynamic argument modification
274
def create_enhanced_promise(func, enhancer):
275
def enhanced_func(*args, **kwargs):
276
enhanced_args, enhanced_kwargs = enhancer(args, kwargs)
277
return func(*enhanced_args, **enhanced_kwargs)
278
279
return promise(enhanced_func)
280
281
# Usage
282
def add_timestamp_to_args(args, kwargs):
283
return args + (time.now(),), kwargs
284
285
timestamped_logger = create_enhanced_promise(log_message, add_timestamp_to_args)
286
```