Skip to content

Commit 86a367b

Browse files
authored
Fix solar position tests for pandas 3 (#2668)
* Update test_solarposition.py * Update test_spa.py * lint
1 parent aa5fc55 commit 86a367b

File tree

2 files changed

+60
-61
lines changed

2 files changed

+60
-61
lines changed

tests/test_solarposition.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -142,20 +142,15 @@ def test_spa_python_numpy_physical_dst(expected_solpos, golden):
142142

143143
@pytest.mark.parametrize('delta_t', [65.0, None, np.array([65, 65])])
144144
def test_sun_rise_set_transit_spa(expected_rise_set_spa, golden, delta_t):
145-
# solution from NREL SAP web calculator
145+
# solution from NREL SPA web calculator
146146
south = Location(-35.0, 0.0, tz='UTC')
147-
times = pd.DatetimeIndex([datetime.datetime(1996, 7, 5, 0),
148-
datetime.datetime(2004, 12, 4, 0)]
149-
).tz_localize('UTC')
150-
sunrise = pd.DatetimeIndex([datetime.datetime(1996, 7, 5, 7, 8, 15),
151-
datetime.datetime(2004, 12, 4, 4, 38, 57)]
152-
).tz_localize('UTC').tolist()
153-
sunset = pd.DatetimeIndex([datetime.datetime(1996, 7, 5, 17, 1, 4),
154-
datetime.datetime(2004, 12, 4, 19, 2, 3)]
155-
).tz_localize('UTC').tolist()
156-
transit = pd.DatetimeIndex([datetime.datetime(1996, 7, 5, 12, 4, 36),
157-
datetime.datetime(2004, 12, 4, 11, 50, 22)]
158-
).tz_localize('UTC').tolist()
147+
times = pd.to_datetime(["1996-07-05", "2004-12-04"], utc=True)
148+
sunrise = pd.to_datetime(["1996-07-05 07:08:15", "2004-12-04 04:38:57"],
149+
utc=True)
150+
sunset = pd.to_datetime(["1996-07-05 17:01:04", "2004-12-04 19:02:03"],
151+
utc=True)
152+
transit = pd.to_datetime(["1996-07-05 12:04:36", "2004-12-04 11:50:22"],
153+
utc=True)
159154
frame = pd.DataFrame({'sunrise': sunrise,
160155
'sunset': sunset,
161156
'transit': transit}, index=times)
@@ -169,7 +164,9 @@ def test_sun_rise_set_transit_spa(expected_rise_set_spa, golden, delta_t):
169164
for col, data in result.items():
170165
result_rounded[col] = data.dt.round('1s')
171166

172-
assert_frame_equal(frame, result_rounded)
167+
assert_frame_equal(frame, result_rounded,
168+
check_dtype=False # ignore us/ns dtypes
169+
)
173170

174171
# test for Golden, CO compare to NREL SPA
175172
result = solarposition.sun_rise_set_transit_spa(
@@ -182,7 +179,9 @@ def test_sun_rise_set_transit_spa(expected_rise_set_spa, golden, delta_t):
182179
for col, data in result.items():
183180
result_rounded[col] = data.dt.round('s').tz_convert('MST')
184181

185-
assert_frame_equal(expected_rise_set_spa, result_rounded)
182+
assert_frame_equal(expected_rise_set_spa, result_rounded,
183+
check_dtype=False # ignore us/ns dtypes
184+
)
186185

187186

188187
@requires_ephem
@@ -726,7 +725,10 @@ def test_hour_angle_with_tricky_timezones():
726725
'2014-09-07 02:00:00',
727726
]).tz_localize('America/Santiago', nonexistent='shift_forward')
728727

729-
with pytest.raises(pytz.exceptions.NonExistentTimeError):
728+
with pytest.raises((
729+
pytz.exceptions.NonExistentTimeError, # pandas 1.x, 2.x
730+
ValueError, # pandas 3.x
731+
)):
730732
times.normalize()
731733

732734
# should not raise `pytz.exceptions.NonExistentTimeError`
@@ -740,7 +742,10 @@ def test_hour_angle_with_tricky_timezones():
740742
'2014-11-02 02:00:00',
741743
]).tz_localize('America/Havana', ambiguous=[True, True, False, False])
742744

743-
with pytest.raises(pytz.exceptions.AmbiguousTimeError):
745+
with pytest.raises((
746+
pytz.exceptions.AmbiguousTimeError, # pandas 1.x, 2.x
747+
ValueError, # pandas 3.x
748+
)):
744749
solarposition.hour_angle(times, longitude, eot)
745750

746751

@@ -798,8 +803,13 @@ def test_sun_rise_set_transit_geometric(expected_rise_set_spa, golden_mst):
798803
@pytest.mark.parametrize('tz', [None, 'utc', 'US/Eastern'])
799804
def test__datetime_to_unixtime(tz):
800805
# for pandas < 2.0 where "unit" doesn't exist in pd.date_range. note that
801-
# unit of ns is the only option in pandas<2, and the default in pandas 2.x
802-
times = pd.date_range(start='2019-01-01', freq='h', periods=3, tz=tz)
806+
# unit of ns is the only option in pandas<2, and the default in pandas 2.x,
807+
# but the default is us in pandas 3.x
808+
kwargs = dict(start='2019-01-01', freq='h', periods=3, tz=tz)
809+
try:
810+
times = pd.date_range(**kwargs, unit='ns') # pandas 2.x, 3.x
811+
except TypeError:
812+
times = pd.date_range(**kwargs) # pandas 1.x
803813
expected = times.view(np.int64)/10**9
804814
actual = solarposition._datetime_to_unixtime(times)
805815
np.testing.assert_equal(expected, actual)

tests/test_spa.py

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import warnings
44
import pytest
55
import pvlib
6+
from pvlib.solarposition import _datetime_to_unixtime
67

78
try:
89
from importlib import reload
@@ -19,9 +20,13 @@
1920
import unittest
2021
from .conftest import requires_numba
2122

23+
kwargs = dict(start='2003-10-17 12:30:30', periods=1, freq='D')
24+
try:
25+
times = pd.date_range(**kwargs, unit='ns') # pandas 2.x, 3.x
26+
except TypeError:
27+
times = pd.date_range(**kwargs) # pandas 1.x
2228

23-
times = (pd.date_range('2003-10-17 12:30:30', periods=1, freq='D')
24-
.tz_localize('MST'))
29+
times = times.tz_localize('MST')
2530
unixtimes = np.array(times.tz_convert('UTC').view(np.int64)*1.0/10**9)
2631

2732
lat = 39.742476
@@ -258,35 +263,29 @@ def test_transit_sunrise_sunset(self):
258263
# tests at greenwich
259264
times = pd.DatetimeIndex([dt.datetime(1996, 7, 5, 0),
260265
dt.datetime(2004, 12, 4, 0)]
261-
).tz_localize(
262-
'UTC').view(np.int64)*1.0/10**9
266+
).tz_localize('UTC')
263267
sunrise = pd.DatetimeIndex([dt.datetime(1996, 7, 5, 7, 8, 15),
264268
dt.datetime(2004, 12, 4, 4, 38, 57)]
265-
).tz_localize(
266-
'UTC').view(np.int64)*1.0/10**9
269+
).tz_localize('UTC')
267270
sunset = pd.DatetimeIndex([dt.datetime(1996, 7, 5, 17, 1, 4),
268271
dt.datetime(2004, 12, 4, 19, 2, 2)]
269-
).tz_localize(
270-
'UTC').view(np.int64)*1.0/10**9
271-
times = np.array(times)
272-
sunrise = np.array(sunrise)
273-
sunset = np.array(sunset)
272+
).tz_localize('UTC')
273+
times = _datetime_to_unixtime(times)
274+
sunrise = _datetime_to_unixtime(sunrise)
275+
sunset = _datetime_to_unixtime(sunset)
274276
result = self.spa.transit_sunrise_sunset(times, -35.0, 0.0, 64.0, 1)
275277
assert_almost_equal(sunrise/1e3, result[1]/1e3, 3)
276278
assert_almost_equal(sunset/1e3, result[2]/1e3, 3)
277279

278280
times = pd.DatetimeIndex([dt.datetime(1994, 1, 2), ]
279-
).tz_localize(
280-
'UTC').view(np.int64)*1.0/10**9
281+
).tz_localize('UTC')
281282
sunset = pd.DatetimeIndex([dt.datetime(1994, 1, 2, 16, 59, 55), ]
282-
).tz_localize(
283-
'UTC').view(np.int64)*1.0/10**9
283+
).tz_localize('UTC')
284284
sunrise = pd.DatetimeIndex([dt.datetime(1994, 1, 2, 7, 8, 12), ]
285-
).tz_localize(
286-
'UTC').view(np.int64)*1.0/10**9
287-
times = np.array(times)
288-
sunrise = np.array(sunrise)
289-
sunset = np.array(sunset)
285+
).tz_localize('UTC')
286+
times = _datetime_to_unixtime(times)
287+
sunrise = _datetime_to_unixtime(sunrise)
288+
sunset = _datetime_to_unixtime(sunset)
290289
result = self.spa.transit_sunrise_sunset(times, 35.0, 0.0, 64.0, 1)
291290
assert_almost_equal(sunrise/1e3, result[1]/1e3, 3)
292291
assert_almost_equal(sunset/1e3, result[2]/1e3, 3)
@@ -297,23 +296,20 @@ def test_transit_sunrise_sunset(self):
297296
dt.datetime(2015, 4, 2),
298297
dt.datetime(2015, 8, 2),
299298
dt.datetime(2015, 12, 2)],
300-
).tz_localize(
301-
'UTC').view(np.int64)*1.0/10**9
299+
).tz_localize('UTC')
302300
sunrise = pd.DatetimeIndex([dt.datetime(2015, 1, 2, 7, 19),
303301
dt.datetime(2015, 4, 2, 5, 43),
304302
dt.datetime(2015, 8, 2, 5, 1),
305303
dt.datetime(2015, 12, 2, 7, 1)],
306-
).tz_localize(
307-
'MST').view(np.int64)*1.0/10**9
304+
).tz_localize('MST')
308305
sunset = pd.DatetimeIndex([dt.datetime(2015, 1, 2, 16, 49),
309306
dt.datetime(2015, 4, 2, 18, 24),
310307
dt.datetime(2015, 8, 2, 19, 10),
311308
dt.datetime(2015, 12, 2, 16, 38)],
312-
).tz_localize(
313-
'MST').view(np.int64)*1.0/10**9
314-
times = np.array(times)
315-
sunrise = np.array(sunrise)
316-
sunset = np.array(sunset)
309+
).tz_localize('MST')
310+
times = _datetime_to_unixtime(times)
311+
sunrise = _datetime_to_unixtime(sunrise)
312+
sunset = _datetime_to_unixtime(sunset)
317313
result = self.spa.transit_sunrise_sunset(times, 39.0, -105.0, 64.0, 1)
318314
assert_almost_equal(sunrise/1e3, result[1]/1e3, 1)
319315
assert_almost_equal(sunset/1e3, result[2]/1e3, 1)
@@ -323,33 +319,26 @@ def test_transit_sunrise_sunset(self):
323319
dt.datetime(2015, 4, 2),
324320
dt.datetime(2015, 8, 2),
325321
dt.datetime(2015, 12, 2)],
326-
).tz_localize(
327-
'UTC').view(np.int64)*1.0/10**9
322+
).tz_localize('UTC')
328323
sunrise = pd.DatetimeIndex([dt.datetime(2015, 1, 2, 7, 36),
329324
dt.datetime(2015, 4, 2, 5, 58),
330325
dt.datetime(2015, 8, 2, 5, 13),
331326
dt.datetime(2015, 12, 2, 7, 17)],
332-
).tz_localize('Asia/Shanghai').view(
333-
np.int64)*1.0/10**9
327+
).tz_localize('Asia/Shanghai')
334328
sunset = pd.DatetimeIndex([dt.datetime(2015, 1, 2, 17, 0),
335329
dt.datetime(2015, 4, 2, 18, 39),
336330
dt.datetime(2015, 8, 2, 19, 28),
337331
dt.datetime(2015, 12, 2, 16, 50)],
338-
).tz_localize('Asia/Shanghai').view(
339-
np.int64)*1.0/10**9
340-
times = np.array(times)
341-
sunrise = np.array(sunrise)
342-
sunset = np.array(sunset)
332+
).tz_localize('Asia/Shanghai')
333+
times = _datetime_to_unixtime(times)
334+
sunrise = _datetime_to_unixtime(sunrise)
335+
sunset = _datetime_to_unixtime(sunset)
343336
result = self.spa.transit_sunrise_sunset(
344337
times, 39.917, 116.383, 64.0, 1)
345338
assert_almost_equal(sunrise/1e3, result[1]/1e3, 1)
346339
assert_almost_equal(sunset/1e3, result[2]/1e3, 1)
347340

348341
def test_earthsun_distance(self):
349-
times = (pd.date_range('2003-10-17 12:30:30', periods=1, freq='D')
350-
.tz_localize('MST'))
351-
unixtimes = times.tz_convert('UTC').view(np.int64)*1.0/10**9
352-
unixtimes = np.array(unixtimes)
353342
result = self.spa.earthsun_distance(unixtimes, 64.0, 1)
354343
assert_almost_equal(R, result, 6)
355344

0 commit comments

Comments
 (0)