Skip to content

Commit 1d43c1a

Browse files
authored
Test and CI updates (#129)
* CI: drop 3.6, add 3.9, 3.10; only lint once * FutureWarning: The series.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead. * pvlib deprecation warnings * mirror tests for pvlib 0.9.0 * lint * lint * another series.append -> pd.concat * whatsnew * fix scipy error
1 parent 27ec167 commit 1d43c1a

File tree

9 files changed

+195
-50
lines changed

9 files changed

+195
-50
lines changed

.github/workflows/lint-and-test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ jobs:
77

88
strategy:
99
matrix:
10-
os: [ubuntu-latest, macos-10.15, windows-latest] # macos-latest does not have py3.6
11-
python-version: [3.6, 3.7, 3.8]
10+
os: [ubuntu-latest, macos-latest, windows-latest]
11+
python-version: [3.7, 3.8, 3.9, "3.10"]
1212
requirements: [requirements.txt]
1313
include:
1414
- requirements: requirements-min.txt
15-
python-version: 3.6
15+
python-version: 3.7
1616
os: ubuntu-latest
1717

1818
runs-on: ${{ matrix.os }}
@@ -65,7 +65,7 @@ jobs:
6565

6666
strategy:
6767
matrix:
68-
python-version: [3.6, 3.7, 3.8]
68+
python-version: [3.7]
6969

7070
runs-on: ubuntu-latest
7171

docs/whatsnew/0.1.1.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ Bug Fixes
2727
* Fixed an issue with :py:func:`pvanalytics.features.clearsky.reno` in recent
2828
pandas versions (:issue:`125`, :pull:`128`)
2929

30+
Requirements
31+
~~~~~~~~~~~~
32+
33+
* Drop support for python 3.6, which reached end of life Dec 2021 (:pull:`129`)
34+
3035
Documentation
3136
~~~~~~~~~~~~~
3237

pvanalytics/tests/conftest.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
import pytest
33
import numpy as np
44
import pandas as pd
5+
import pvlib
56
from pvlib import location, pvsystem
67
from pvlib.temperature import TEMPERATURE_MODEL_PARAMETERS
78

9+
from pkg_resources import Requirement, parse_version
10+
811

912
def pytest_addoption(parser):
1013
parser.addoption(
@@ -29,6 +32,25 @@ def pytest_collection_modifyitems(config, items):
2932
item.add_marker(skip_slow)
3033

3134

35+
def requires_pvlib(versionspec, reason=''):
36+
"""
37+
Decorator to skip pytest tests if a dependency version is not satisfied.
38+
39+
Parameters
40+
----------
41+
versionspec : str
42+
A version specifier like '==0.8.1' or '<=0.9.0'
43+
reason : str, optional
44+
Additional context to show in pytest log output
45+
"""
46+
req = Requirement.parse('pvlib' + versionspec)
47+
is_satisfied = parse_version(pvlib.__version__) in req
48+
message = 'requires pvlib' + versionspec
49+
if reason:
50+
message += f'({reason})'
51+
return pytest.mark.skipif(not is_satisfied, reason=message)
52+
53+
3254
@pytest.fixture
3355
def quadratic():
3456
"""Downward facing quadratic.
@@ -106,17 +128,24 @@ def solarposition_year(one_year_hourly, albuquerque):
106128

107129

108130
@pytest.fixture(scope='module')
109-
def system_parameters():
110-
"""System parameters for generating simulated power data."""
131+
def array_parameters():
132+
"""Array parameters for generating simulated power data."""
111133
sandia_modules = pvsystem.retrieve_sam('SandiaMod')
112-
sapm_inverters = pvsystem.retrieve_sam('cecinverter')
113134
module = sandia_modules['Canadian_Solar_CS5P_220M___2009_']
114-
inverter = sapm_inverters['ABB__MICRO_0_25_I_OUTD_US_208__208V_']
115135
temperature_model_parameters = (
116136
TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass']
117137
)
118138
return {
119139
'module_parameters': module,
120-
'inverter_parameters': inverter,
121140
'temperature_model_parameters': temperature_model_parameters
122141
}
142+
143+
144+
@pytest.fixture(scope='module')
145+
def system_parameters():
146+
"""PVSystem parameters for generating simulated power data."""
147+
sapm_inverters = pvsystem.retrieve_sam('cecinverter')
148+
inverter = sapm_inverters['ABB__MICRO_0_25_I_OUTD_US_208__208V_']
149+
return {
150+
'inverter_parameters': inverter,
151+
}

pvanalytics/tests/features/test_clearsky.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
"""Tests for feature labeling functions."""
22
import pytest
33
import pandas as pd
4-
import pvlib
54
from pvanalytics.features import clearsky
5+
from ..conftest import requires_pvlib
66

7-
from pkg_resources import parse_version
8-
is_old_pvlib = parse_version(pvlib.__version__) < parse_version("0.9.0")
97

10-
11-
@pytest.mark.skipif(is_old_pvlib, reason="GH #105")
8+
@requires_pvlib('>=0.9.0', reason="GH #105")
129
@pytest.mark.filterwarnings("ignore:Support for multi-dimensional indexing")
1310
def test_reno_identical(quadratic):
1411
"""Identical clearsky and measured irradiance all True"""
@@ -18,7 +15,7 @@ def test_reno_identical(quadratic):
1815
assert clearsky.reno(quadratic, quadratic).all()
1916

2017

21-
@pytest.mark.skipif(is_old_pvlib, reason="GH #105")
18+
@requires_pvlib('>=0.9.0', reason="GH #105")
2219
@pytest.mark.filterwarnings("ignore:Support for multi-dimensional indexing")
2320
@pytest.mark.filterwarnings("ignore:invalid value encountered in")
2421
def test_reno_begining_end(quadratic):

pvanalytics/tests/features/test_clipping.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,12 @@ def test_threshold_clipping_four_days(quadratic, quadratic_clipped):
202202
# scale the rest of the days below the clipping threshold
203203
full_day *= 0.75
204204

205-
power = full_day_clipped
206-
power.append(full_day)
207-
power.append(full_day)
208-
power.append(full_day)
205+
power = pd.concat([
206+
full_day_clipped,
207+
full_day,
208+
full_day,
209+
full_day,
210+
])
209211

210212
power.index = pd.date_range(
211213
start='01/01/2020 00:00', freq='10T', periods=len(power)
@@ -232,10 +234,12 @@ def test_threshold_no_clipping_four_days(quadratic):
232234
)
233235
full_day.fillna(0)
234236

235-
power = full_day
236-
power.append(full_day * 1.3)
237-
power.append(full_day * 1.2)
238-
power.append(full_day * 1.1)
237+
power = pd.concat([
238+
full_day,
239+
full_day * 1.3,
240+
full_day * 1.2,
241+
full_day * 1.1,
242+
])
239243

240244
power.index = pd.date_range(
241245
start='01/01/2020 00:00', freq='10T', periods=len(power)

pvanalytics/tests/features/test_orientation.py

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import pytest
22
from pandas.util.testing import assert_series_equal
33
import pandas as pd
4-
from pvlib import tracking, modelchain, irradiance
4+
from pvlib import tracking, pvsystem, modelchain, irradiance
55
from pvanalytics.features import orientation
66

7+
from ..conftest import requires_pvlib
8+
79

810
def test_clearsky_ghi_fixed(clearsky, solarposition):
911
"""Identify every day as fixed, since clearsky GHI is sunny."""
@@ -40,9 +42,13 @@ def test_ghi_not_tracking(clearsky, solarposition):
4042

4143

4244
@pytest.fixture
43-
def power_tracking(clearsky, albuquerque, system_parameters):
45+
def power_tracking_old_pvlib(clearsky, albuquerque, array_parameters,
46+
system_parameters):
4447
"""Simulated power for a pvlib SingleAxisTracker PVSystem in Albuquerque"""
45-
system = tracking.SingleAxisTracker(**system_parameters)
48+
# copy of `power_tracking` but with older pvlib API
49+
# TODO: remove when minimum pvlib version is >= 0.9.0
50+
system = tracking.SingleAxisTracker(**array_parameters,
51+
**system_parameters)
4652
mc = modelchain.ModelChain(
4753
system,
4854
albuquerque,
@@ -51,6 +57,34 @@ def power_tracking(clearsky, albuquerque, system_parameters):
5157
return mc.ac
5258

5359

60+
@pytest.fixture
61+
def power_tracking(clearsky, albuquerque, array_parameters, system_parameters):
62+
"""Simulated power for a pvlib SingleAxisTracker PVSystem in Albuquerque"""
63+
array = pvsystem.Array(pvsystem.SingleAxisTrackerMount(),
64+
**array_parameters)
65+
system = pvsystem.PVSystem(arrays=[array],
66+
**system_parameters)
67+
mc = modelchain.ModelChain(
68+
system,
69+
albuquerque,
70+
)
71+
mc.run_model(clearsky)
72+
return mc.results.ac
73+
74+
75+
@requires_pvlib('<0.9.0', reason="SingleAxisTracker deprecation")
76+
def test_power_tracking_old_pvlib(power_tracking_old_pvlib, solarposition):
77+
"""simulated power from a single axis tracker is identified as sunny
78+
with tracking=True"""
79+
# copy of `test_power_tracking` but with older pvlib API
80+
# TODO: remove when minimum pvlib version is >= 0.9.0
81+
assert orientation.tracking_nrel(
82+
power_tracking_old_pvlib,
83+
solarposition['zenith'] < 87
84+
).all()
85+
86+
87+
@requires_pvlib('>=0.9.0', reason="Array class")
5488
def test_power_tracking(power_tracking, solarposition):
5589
"""simulated power from a single axis tracker is identified as sunny
5690
with tracking=True"""
@@ -60,6 +94,33 @@ def test_power_tracking(power_tracking, solarposition):
6094
).all()
6195

6296

97+
@requires_pvlib('<0.9.0', reason="SingleAxisTracker deprecation")
98+
def test_power_tracking_perturbed_old_pvlib(power_tracking_old_pvlib,
99+
solarposition):
100+
"""A day with perturbed values is not marked as tracking."""
101+
# copy of `test_power_tracking_perturbed` but with older pvlib API
102+
# TODO: remove when minimum pvlib version is >= 0.9.0
103+
power_tracking_old_pvlib.iloc[6:18] = 10
104+
expected = pd.Series(True, index=power_tracking_old_pvlib.index)
105+
expected.iloc[0:24] = False
106+
assert_series_equal(
107+
expected,
108+
orientation.tracking_nrel(
109+
power_tracking_old_pvlib,
110+
solarposition['zenith'] < 87
111+
)
112+
)
113+
assert_series_equal(
114+
expected,
115+
orientation.tracking_nrel(
116+
power_tracking_old_pvlib,
117+
solarposition['zenith'] < 87,
118+
peak_min=100
119+
)
120+
)
121+
122+
123+
@requires_pvlib('>=0.9.0', reason="Array class")
63124
def test_power_tracking_perturbed(power_tracking, solarposition):
64125
"""A day with perturbed values is not marked as tracking."""
65126
power_tracking.iloc[6:18] = 10

pvanalytics/tests/quality/test_time.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def _shift_between(series, shift, start, end):
296296
during = series[start:end]
297297
after = series[end:]
298298
during = during + shift
299-
shifted = before.append(during).append(after)
299+
shifted = pd.concat([before, during, after])
300300
return shifted[~shifted.index.duplicated()]
301301

302302

0 commit comments

Comments
 (0)