Skip to content

Commit 9593194

Browse files
Copilotpwwang
andcommitted
Make pipe() tests use Python builtin types instead of pandas
Co-authored-by: pwwang <[email protected]>
1 parent bc7f9f1 commit 9593194

File tree

2 files changed

+92
-94
lines changed

2 files changed

+92
-94
lines changed

datar/apis/dplyr.py

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,10 +2485,10 @@ def pipe(_data: T, func: _Callable, *args, **kwargs) -> Any:
24852485
"""Apply a function to the data
24862486
24872487
This function is similar to pandas.DataFrame.pipe() and allows you to
2488-
apply custom functions in a piping workflow.
2488+
apply custom functions in a piping workflow. Works with any data type.
24892489
24902490
Args:
2491-
_data: The data object (typically a DataFrame)
2491+
_data: The data object (can be any type)
24922492
func: Function to apply to the data. ``args`` and ``kwargs`` are
24932493
passed into ``func``.
24942494
*args: Positional arguments passed into ``func``
@@ -2498,30 +2498,23 @@ def pipe(_data: T, func: _Callable, *args, **kwargs) -> Any:
24982498
The return value of ``func``
24992499
25002500
Examples:
2501-
>>> import pandas as pd
25022501
>>> import datar.all as dr
2503-
>>> from datar import f
2504-
>>> df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
2505-
>>> df >> dr.pipe(lambda x: x * 2)
2506-
a b
2507-
0 2 8
2508-
1 4 10
2509-
2 6 12
2502+
>>> # Works with lists
2503+
>>> [1, 2, 3] >> dr.pipe(lambda x: [i * 2 for i in x])
2504+
[2, 4, 6]
2505+
2506+
>>> # Works with dicts
2507+
>>> {'a': 1, 'b': 2} >> dr.pipe(lambda x: {k: v * 2 for k, v in x.items()})
2508+
{'a': 2, 'b': 4}
25102509
25112510
>>> # With additional arguments
2512-
>>> def add_value(df, value):
2513-
... return df + value
2514-
>>> df >> dr.pipe(add_value, 10)
2515-
a b
2516-
0 11 14
2517-
1 12 15
2518-
2 13 16
2519-
2520-
>>> # Combined with other datar functions
2521-
>>> df >> dr.select(f.a) >> dr.pipe(lambda x: x * 2)
2522-
a
2523-
0 2
2524-
1 4
2525-
2 6
2511+
>>> def add_value(data, value):
2512+
... return [x + value for x in data]
2513+
>>> [1, 2, 3] >> dr.pipe(add_value, 10)
2514+
[11, 12, 13]
2515+
2516+
>>> # Chain multiple operations
2517+
>>> [1, 2, 3] >> dr.pipe(lambda x: [i * 2 for i in x]) >> dr.pipe(sum)
2518+
12
25262519
"""
25272520
return func(_data, *args, **kwargs)

tests/test_pipe.py

Lines changed: 75 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,108 @@
11
import pytest
2-
import pandas as pd
32
from datar.all import pipe
43

54

6-
def test_pipe_basic_lambda():
7-
"""Test pipe with a basic lambda function"""
8-
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
9-
result = df >> pipe(lambda x: x * 2)
10-
expected = pd.DataFrame({'a': [2, 4, 6], 'b': [8, 10, 12]})
11-
pd.testing.assert_frame_equal(result, expected)
5+
def test_pipe_with_list():
6+
"""Test pipe with a list"""
7+
data = [1, 2, 3, 4, 5]
8+
result = data >> pipe(lambda x: [i * 2 for i in x])
9+
expected = [2, 4, 6, 8, 10]
10+
assert result == expected
11+
12+
13+
def test_pipe_with_dict():
14+
"""Test pipe with a dictionary"""
15+
data = {'a': 1, 'b': 2, 'c': 3}
16+
result = data >> pipe(lambda x: {k: v * 2 for k, v in x.items()})
17+
expected = {'a': 2, 'b': 4, 'c': 6}
18+
assert result == expected
1219

1320

1421
def test_pipe_with_args():
1522
"""Test pipe with additional positional arguments"""
16-
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
23+
data = [1, 2, 3]
1724

18-
def add_value(df, value):
19-
return df + value
25+
def add_value(data, value):
26+
return [x + value for x in data]
2027

21-
result = df >> pipe(add_value, 10)
22-
expected = pd.DataFrame({'a': [11, 12, 13], 'b': [14, 15, 16]})
23-
pd.testing.assert_frame_equal(result, expected)
28+
result = data >> pipe(add_value, 10)
29+
expected = [11, 12, 13]
30+
assert result == expected
2431

2532

2633
def test_pipe_with_kwargs():
2734
"""Test pipe with keyword arguments"""
28-
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
35+
data = [1, 2, 3]
2936

30-
def multiply_col(df, col, factor=1):
31-
df = df.copy()
32-
df[col] = df[col] * factor
33-
return df
37+
def multiply_data(data, factor=1):
38+
return [x * factor for x in data]
3439

35-
result = df >> pipe(multiply_col, 'a', factor=10)
36-
expected = pd.DataFrame({'a': [10, 20, 30], 'b': [4, 5, 6]})
37-
pd.testing.assert_frame_equal(result, expected)
40+
result = data >> pipe(multiply_data, factor=10)
41+
expected = [10, 20, 30]
42+
assert result == expected
3843

3944

40-
def test_pipe_with_column_selection():
41-
"""Test pipe with column operations"""
42-
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
43-
44-
# Select a column and then multiply it
45-
result = df >> pipe(lambda df: df[['a']]) >> pipe(lambda x: x * 2)
46-
expected = pd.DataFrame({'a': [2, 4, 6]})
47-
pd.testing.assert_frame_equal(result, expected)
45+
def test_pipe_with_string():
46+
"""Test pipe with string operations"""
47+
data = "hello"
48+
result = data >> pipe(lambda x: x.upper())
49+
assert result == "HELLO"
4850

4951

50-
def test_pipe_with_column_rename():
51-
"""Test pipe with column renaming (similar to issue example)"""
52-
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
53-
54-
# Select a column and rename it
55-
result = df >> pipe(lambda df: df[['a']]) >> pipe(lambda df: df.rename(columns=str.upper))
56-
expected = pd.DataFrame({'A': [1, 2, 3]})
57-
pd.testing.assert_frame_equal(result, expected)
52+
def test_pipe_with_tuple():
53+
"""Test pipe with tuple"""
54+
data = (1, 2, 3)
55+
result = data >> pipe(lambda x: tuple(i * 2 for i in x))
56+
expected = (2, 4, 6)
57+
assert result == expected
5858

5959

60-
def test_pipe_with_custom_function():
61-
"""Test pipe with a custom function that modifies the dataframe"""
62-
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
63-
64-
def custom_transform(df, new_col_name, value):
65-
df = df.copy()
66-
df[new_col_name] = df['a'] + value
67-
return df
68-
69-
result = df >> pipe(custom_transform, 'c', 100)
70-
expected = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [101, 102, 103]})
71-
pd.testing.assert_frame_equal(result, expected)
72-
73-
74-
def test_pipe_returns_non_dataframe():
75-
"""Test that pipe can return non-DataFrame objects"""
76-
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
77-
78-
result = df >> pipe(lambda x: x['a'].sum())
79-
assert result == 6
60+
def test_pipe_returns_different_type():
61+
"""Test that pipe can return different types"""
62+
data = [1, 2, 3, 4, 5]
63+
result = data >> pipe(sum)
64+
assert result == 15
8065

8166

8267
def test_pipe_chain_multiple():
8368
"""Test chaining multiple pipe operations"""
84-
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
69+
data = [1, 2, 3]
8570

8671
result = (
87-
df
88-
>> pipe(lambda x: x * 2)
89-
>> pipe(lambda x: x + 1)
72+
data
73+
>> pipe(lambda x: [i * 2 for i in x])
74+
>> pipe(lambda x: [i + 1 for i in x])
9075
)
91-
expected = pd.DataFrame({'a': [3, 5, 7], 'b': [9, 11, 13]})
92-
pd.testing.assert_frame_equal(result, expected)
76+
expected = [3, 5, 7]
77+
assert result == expected
78+
79+
80+
def test_pipe_with_custom_class():
81+
"""Test pipe with a custom class"""
82+
class Counter:
83+
def __init__(self, value):
84+
self.value = value
85+
86+
def increment(self, amount):
87+
return Counter(self.value + amount)
88+
89+
def __eq__(self, other):
90+
return self.value == other.value
91+
92+
counter = Counter(5)
93+
result = counter >> pipe(lambda x: x.increment(10))
94+
expected = Counter(15)
95+
assert result == expected
9396

9497

95-
def test_pipe_with_set_axis_like_issue():
96-
"""Test pipe similar to the issue example with set_axis"""
97-
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
98+
def test_pipe_with_multiple_args_and_kwargs():
99+
"""Test pipe with both args and kwargs"""
100+
data = [1, 2, 3]
101+
102+
def transform(data, multiplier, offset=0):
103+
return [x * multiplier + offset for x in data]
98104

99-
# Simulate the issue example: convert column names to lowercase
100-
result = df >> pipe(lambda df: df.set_axis(df.columns.str.lower(), axis=1))
101-
expected = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
102-
pd.testing.assert_frame_equal(result, expected)
105+
result = data >> pipe(transform, 2, offset=5)
106+
expected = [7, 9, 11]
107+
assert result == expected
103108

0 commit comments

Comments
 (0)