Skip to content

Commit 27b8d1c

Browse files
authored
Merge pull request #420 from datacamp/remove-reliance-on-numpy-and-pandas
[CP-4659] feat: drop direct dependency on numpy and pandas
2 parents f0bfbe3 + 26f8576 commit 27b8d1c

File tree

4 files changed

+62
-26
lines changed

4 files changed

+62
-26
lines changed

pythonwhat/Test.py

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,14 @@ def test(self):
9494
"""
9595
Perform the actual test. result is set to False if the objects differ, True otherwise.
9696
"""
97-
import numpy as np
98-
self.result = np.array(self.func(self.obj1, self.obj2)).all()
97+
result = self.func(self.obj1, self.obj2)
98+
99+
try:
100+
import numpy as np
101+
102+
self.result = np.array(result).all()
103+
except ImportError:
104+
self.result = result
99105

100106

101107
# Helpers for testing equality
@@ -117,34 +123,64 @@ def is_equal(x, y):
117123
try:
118124
if areinstance(x, y, (str, int, float, bool, type(None))):
119125
return x == y
126+
120127
if is_collection_of_primitives(x):
121128
return x == y
129+
122130
if areinstance(x, y, (Exception,)):
123131
# Types of errors don't matter (this is debatable)
124132
return str(x) == str(y)
125133

134+
if areinstance(x, y, (list, tuple,)):
135+
if len(x) != len(y):
136+
return False
137+
return all(is_equal(x_element, y_element) for x_element, y_element in zip(x, y))
138+
139+
if areinstance(x, y, (map, filter,)):
140+
x_list, y_list = list(x), list(y)
141+
if len(x_list) != len(y_list):
142+
return False
143+
return all(is_equal(x_element, y_element) for x_element, y_element in zip(x_list, y_list))
144+
145+
if areinstance(x, y, (set,)):
146+
return is_equal(sorted(x), sorted(y))
147+
148+
if areinstance(x, y, (dict,)):
149+
if x.keys() != y.keys():
150+
return False
151+
return all(is_equal(x[key], y[key]) for key in x)
152+
126153
# Delay importing pandas / numpy until absolutely necessary. This is important for performance in Pyodide.
127-
import pandas as pd
128-
from pandas.testing import assert_frame_equal, assert_series_equal
129-
import numpy as np
130-
131-
if areinstance(x, y, (np.ndarray, dict, list, tuple)):
132-
np.testing.assert_equal(x, y)
133-
return True
134-
elif areinstance(x, y, (map, filter)):
135-
return np.array_equal(list(x), list(y))
136-
elif areinstance(x, y, (pd.DataFrame,)):
137-
if x.equals(y):
154+
# Also, assume they may not be available, as Pyodide won't install them unless they are needed.
155+
try:
156+
import numpy as np
157+
158+
if areinstance(x, y, (np.ndarray,)):
159+
np.testing.assert_equal(x, y)
138160
return True
139-
assert_frame_equal(x, y)
140-
return True
141-
elif areinstance(x, y, (pd.Series,)):
142-
if x.equals(y):
161+
except ImportError:
162+
if areinstance(x, y, (np.ndarray,)):
163+
raise RuntimeError("NumPy is required for comparing NumPy objects.")
164+
165+
try:
166+
import pandas as pd
167+
from pandas.testing import assert_frame_equal, assert_series_equal
168+
169+
if areinstance(x, y, (pd.DataFrame,)):
170+
if x.equals(y):
171+
return True
172+
assert_frame_equal(x, y)
143173
return True
144-
assert_series_equal(x, y)
145-
return True
146-
else:
147-
return x == y
174+
elif areinstance(x, y, (pd.Series,)):
175+
if x.equals(y):
176+
return True
177+
assert_series_equal(x, y)
178+
return True
179+
except ImportError:
180+
if areinstance(x, y, (pd.DataFrame, pd.Series)):
181+
raise RuntimeError("pandas is required for comparing pandas objects.")
182+
183+
return x == y
148184

149185
except Exception:
150186
return False

requirements-test.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ h5py~=3.11.0
1515
# test-utils deps
1616
pytest~=6.2.5
1717
pytest-cov~=2.12.1
18+
19+
# not included in requirements.txt
20+
numpy~=1.26.0
21+
pandas~=1.5.3

requirements.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,3 @@ jinja2~=3.1.3
77
markupsafe==2.1.5
88
black==19.10b0
99
Pygments==2.13.0
10-
11-
numpy~=1.26.0
12-
pandas~=1.5.3

setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
PACKAGE_NAME = "pythonwhat"
99
REQUIREMENT_NAMES = ["protowhat", "markdown2", "jinja2", "asttokens", "dill"]
10-
PEER_REQUIREMENTS = ["numpy", "pandas"]
1110

1211
HERE = path.abspath(path.dirname(__file__))
1312
VERSION_FILE = path.join(HERE, PACKAGE_NAME, "__init__.py")
@@ -23,7 +22,7 @@
2322
REQUIREMENTS = [
2423
re.search(_requirements_re_template.format(requirement), req_txt, re.M).group(0)
2524
for requirement in REQUIREMENT_NAMES
26-
] + PEER_REQUIREMENTS
25+
]
2726
with open(README_FILE, encoding="utf-8") as fp:
2827
README = fp.read()
2928

0 commit comments

Comments
 (0)