Skip to content

Commit 7f2e109

Browse files
committed
Fixes for proper flow of data and handling classes properly
1 parent 165ead8 commit 7f2e109

File tree

3 files changed

+90
-36
lines changed

3 files changed

+90
-36
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ from pypipeline import Pipeline
176176

177177
pipeline = Pipeline()
178178

179-
def custom_pipe(passable, next):
179+
def custom_pipe(passable, next_pipe):
180180
passable = passable.replace('hello', 'goodbye')
181-
return next(passable)
181+
return next_pipe(passable)
182182

183183
pipeline.through([
184184
custom_pipe,
@@ -202,15 +202,15 @@ optionally implement the `StellarWP\Pipeline\Contracts\Pipe` interface to enforc
202202
First class:
203203
```python
204204
class CapitalizePipe:
205-
def handle(self, passable, next):
206-
return next(passable.capitalize())
205+
def handle(self, passable, next_pipe):
206+
return next_pipe(passable.capitalize())
207207
```
208208

209209
Second class:
210210
```python
211211
class StripPipe:
212-
def handle(self, passable, next):
213-
return next(passable.strip())
212+
def handle(self, passable, next_pipe):
213+
return next_pipe(passable.strip())
214214
```
215215

216216
#### Example pipeline
@@ -444,7 +444,7 @@ pipeline.through([ str.capitalize, str.strip ])
444444
pipeline.pipes([ str.capitalize, str.strip ])
445445

446446
# Pass closures as pipes.
447-
pipeline.through([ str.capitalize, lambda passable, next: next(passable.strip)])
447+
pipeline.through([ str.capitalize, lambda passable, next: next_pipe(passable.strip)])
448448

449449
# Pass objects as pipes.
450450
pipeline.through([ CapitalizePipe(), StripPipe() ])

pypipeline/pipeline.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from typing import Any, Callable, List, Optional, Union
2+
from functools import reduce
23
from inspect import signature
34

45
class Pipeline:
@@ -39,17 +40,23 @@ def carry(self, next_pipe: Callable, current_pipe: Any) -> Callable:
3940
Callable: The callable for the pipe.
4041
"""
4142
def wrapper(passable):
42-
print(passable)
4343
try:
44-
# Determine how many parameters the current_pipe accepts
45-
params = signature(current_pipe).parameters
46-
if callable(current_pipe) and len(params) == 2 and 'next' in params:
44+
params = None
45+
if callable(current_pipe):
46+
params = signature(current_pipe).parameters
47+
48+
is_object = isinstance(current_pipe, object) and not isinstance(current_pipe, (int, float, str, bool, list, dict, tuple, set))
49+
if is_object == True and hasattr(current_pipe, self.method):
50+
method = getattr(current_pipe, self.method, None)
51+
return method(passable, next_pipe)
52+
elif callable(current_pipe) and 'next_pipe' in params:
4753
return current_pipe(passable, next_pipe)
4854
elif callable(current_pipe):
49-
result = current_pipe(passable)
50-
return next_pipe(result)
55+
passable = current_pipe(passable)
56+
return next_pipe(passable)
5157
else:
5258
raise TypeError("The pipe must be callable")
59+
5360
except Exception as e:
5461
return self.handle_exception(passable, e)
5562
return wrapper
@@ -146,11 +153,7 @@ def then(self, destination: Optional[Callable] = None):
146153
if destination is None:
147154
destination = lambda x: x
148155

149-
pipeline = self.prepare_destination(destination)
150-
151-
# We reverse the
152-
for pipe in reversed(self.pipes):
153-
pipeline = self.carry(pipeline, pipe)
156+
pipeline = reduce(self.carry, reversed(self.pipes), self.prepare_destination(destination))
154157

155158
return pipeline(self.passable)
156159

tests/test_pipeline.py

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,60 +4,111 @@
44
class TestPipeline(unittest.TestCase):
55

66

7+
def test_it_runs_a_pipeline_with_one_callable(self):
8+
pipeline = Pipeline()
9+
result = pipeline.send('hello ') \
10+
.through([str.strip]) \
11+
.then_return()
12+
self.assertEqual('hello', result)
13+
714
def test_it_runs_a_pipeline_with_callables(self):
815
pipeline = Pipeline()
9-
result = pipeline.send('a sample string that is passed through to all pipes. ') \
16+
result = pipeline.send('hello world ') \
1017
.through([str.title, str.strip]) \
1118
.then_return()
12-
self.assertEqual('A Sample String That Is Passed Through To All Pipes.', result)
19+
self.assertEqual('Hello World', result)
1320

1421
def test_it_runs_a_pipeline_with_callables_and_executes_the_destination(self):
1522
pipeline = Pipeline()
16-
result = pipeline.send('a sample string that is passed through to all pipes. ') \
23+
result = pipeline.send('hello world ') \
1724
.through([str.title, str.strip]) \
18-
.then(lambda x: x.replace('A Sample', 'A Nice Long'))
19-
self.assertEqual('A Nice Long String That Is Passed Through To All Pipes.', result)
25+
.then(lambda x: x.replace('Hello', 'Goodbye'))
26+
self.assertEqual('Goodbye World', result)
2027

2128
def test_it_runs_a_pipeline_with_callables_and_closures(self):
2229
pipeline = Pipeline()
23-
result = pipeline.send('a sample string that is passed through to all pipes. ') \
30+
result = pipeline.send('hello world ') \
2431
.through([
25-
lambda x, next: next(x.replace('all', 'all the')),
32+
lambda x, next_pipe: next_pipe(x.replace('hello', 'goodbye')),
2633
str.title,
2734
str.strip
2835
]) \
2936
.then_return()
30-
self.assertEqual('A Sample String That Is Passed Through To All The Pipes.', result)
37+
self.assertEqual('Goodbye World', result)
3138

3239
def test_it_runs_a_pipeline_with_closures(self):
3340
pipeline = Pipeline()
34-
result = pipeline.send('a sample string that is passed through to all pipes.') \
41+
result = pipeline.send('hello world') \
42+
.through([
43+
lambda x, next_pipe: next_pipe(x.title()),
44+
lambda x, next_pipe: next_pipe(x.replace('Hello', 'Goodbye'))
45+
]) \
46+
.then_return()
47+
self.assertEqual('Goodbye World', result)
48+
49+
def test_it_runs_a_pipeline_with_custom_pipes(self):
50+
def custom_pipe(passable, next_pipe):
51+
passable = passable.replace('Hello', 'Goodbye')
52+
return next_pipe(passable)
53+
54+
pipeline = Pipeline()
55+
result = pipeline.send(' hello world ') \
56+
.through([
57+
lambda x, next_pipe: next_pipe(x.title()),
58+
str.strip,
59+
custom_pipe
60+
]) \
61+
.then_return()
62+
self.assertEqual('Goodbye World', result)
63+
64+
def test_it_runs_a_pipeline_with_classes(self):
65+
class TitlePipe:
66+
def handle(self, passable, next_pipe):
67+
return next_pipe(passable.title())
68+
69+
pipeline = Pipeline()
70+
result = pipeline.send(' hello world ') \
71+
.through([
72+
TitlePipe(),
73+
str.strip
74+
]) \
75+
.then_return()
76+
self.assertEqual('Hello World', result)
77+
78+
def test_it_runs_a_pipeline_with_classes_and_custom_handler(self):
79+
class TitlePipe:
80+
def execute(self, passable, next_pipe):
81+
return next_pipe(passable.title())
82+
83+
pipeline = Pipeline()
84+
result = pipeline.send(' hello world ') \
85+
.via('execute') \
3586
.through([
36-
lambda x, next: next(x.title()),
37-
lambda x, next: next(x.replace('All', 'All The'))
87+
TitlePipe(),
88+
str.strip
3889
]) \
3990
.then_return()
40-
self.assertEqual('A Sample String That Is Passed Through To All The Pipes.', result)
91+
self.assertEqual('Hello World', result)
4192

4293
def test_it_runs_a_pipeline_by_sending_late(self):
4394
pipeline = Pipeline()
4495
pipeline.through([str.title, str.strip])
45-
result = pipeline.send('a sample string that is passed through to all pipes. ') \
96+
result = pipeline.send('hello ') \
4697
.then_return()
47-
self.assertEqual('A Sample String That Is Passed Through To All Pipes.', result)
98+
self.assertEqual('Hello', result)
4899

49100
def test_it_runs_a_pipeline_setup_via_pipe(self):
50101
pipeline = Pipeline()
51102
pipeline.pipe([str.title, str.strip])
52-
result = pipeline.send('a sample string that is passed through to all pipes. ') \
103+
result = pipeline.send('hello ') \
53104
.then_return()
54-
self.assertEqual('A Sample String That Is Passed Through To All Pipes.', result)
105+
self.assertEqual('Hello', result)
55106

56107
def test_it_bails_early(self):
57108
pipeline = Pipeline()
58109
result = pipeline.send('bork') \
59110
.through([
60-
lambda x, next: False,
111+
lambda x, next_pipe: False,
61112
str.strip
62113
]) \
63114
.then()
@@ -68,7 +119,7 @@ def test_it_bails_in_the_middle(self):
68119
result = pipeline.send('bork ') \
69120
.through([
70121
str.strip,
71-
lambda x, next: x,
122+
lambda x, next_pipe: x,
72123
str.title
73124
]) \
74125
.then()

0 commit comments

Comments
 (0)