Skip to content

Commit a6667a3

Browse files
authored
deprecate Location, PVSystem, ModelChain kwargs, LocalizedPVSystem, LocalizedSingleAxisTracker (#1053)
* deprecate class kwargs and localized classes * remove localized example from intro * api * update pr number * fix * review * use the deprecated decorator duh * fix whatsnew
1 parent bc3a9c8 commit a6667a3

11 files changed

+85
-109
lines changed

docs/sphinx/source/api.rst

-5
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ corresponding procedural code.
2222
pvsystem.PVSystem
2323
tracking.SingleAxisTracker
2424
modelchain.ModelChain
25-
pvsystem.LocalizedPVSystem
26-
tracking.LocalizedSingleAxisTracker
2725

2826

2927
Solar Position
@@ -209,7 +207,6 @@ wrap the functions listed below. See its documentation for details.
209207
:toctree: generated/
210208

211209
pvsystem.PVSystem
212-
pvsystem.LocalizedPVSystem
213210

214211
Incident angle modifiers
215212
------------------------
@@ -421,8 +418,6 @@ The :py:class:`~tracking.SingleAxisTracker` inherits from
421418
tracking.SingleAxisTracker
422419
tracking.SingleAxisTracker.singleaxis
423420
tracking.SingleAxisTracker.get_irradiance
424-
tracking.SingleAxisTracker.localize
425-
tracking.LocalizedSingleAxisTracker
426421

427422
Functions
428423
---------

docs/sphinx/source/comparison_pvlib_matlab.rst

-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ Major differences
5454
* pvlib-python implements a handful of class designed to simplify the
5555
PV modeling process. These include :py:class:`~pvlib.location.Location`,
5656
:py:class:`~pvlib.pvsystem.PVSystem`,
57-
:py:class:`~pvlib.pvsystem.LocalizedPVSystem`,
5857
:py:class:`~pvlib.tracking.SingleAxisTracker`,
5958
and
6059
:py:class:`~pvlib.modelchain.ModelChain`.

docs/sphinx/source/introtutorial.rst

-78
Original file line numberDiff line numberDiff line change
@@ -178,81 +178,3 @@ by examining the parameters defined for the module.
178178
plt.ylabel('Yearly energy yield (W hr)')
179179
@suppress
180180
plt.close();
181-
182-
183-
Object oriented (LocalizedPVSystem)
184-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
185-
186-
The second object oriented paradigm uses a model where a
187-
:py:class:`~pvlib.pvsystem.LocalizedPVSystem` represents a PV system at
188-
a particular place on the planet. This can be a useful paradigm if
189-
you're thinking about a power plant that already exists.
190-
191-
The :py:class:`~pvlib.pvsystem.LocalizedPVSystem` inherits from both
192-
:py:class:`~pvlib.pvsystem.PVSystem` and
193-
:py:class:`~pvlib.location.Location`, while the
194-
:py:class:`~pvlib.tracking.LocalizedSingleAxisTracker` inherits from
195-
:py:class:`~pvlib.tracking.SingleAxisTracker` (itself a subclass of
196-
:py:class:`~pvlib.pvsystem.PVSystem`) and
197-
:py:class:`~pvlib.location.Location`. The
198-
:py:class:`~pvlib.pvsystem.LocalizedPVSystem` and
199-
:py:class:`~pvlib.tracking.LocalizedSingleAxisTracker` classes may
200-
contain bugs due to the relative difficulty of implementing multiple
201-
inheritance. The :py:class:`~pvlib.pvsystem.LocalizedPVSystem` and
202-
:py:class:`~pvlib.tracking.LocalizedSingleAxisTracker` may be deprecated
203-
in a future release. We recommend that most modeling workflows implement
204-
:py:class:`~pvlib.location.Location`,
205-
:py:class:`~pvlib.pvsystem.PVSystem`, and
206-
:py:class:`~pvlib.modelchain.ModelChain`.
207-
208-
The following code demonstrates how to use a
209-
:py:class:`~pvlib.pvsystem.LocalizedPVSystem` object to accomplish our
210-
modeling goal:
211-
212-
.. ipython:: python
213-
214-
from pvlib.pvsystem import LocalizedPVSystem
215-
216-
energies = {}
217-
for latitude, longitude, name, altitude, timezone in coordinates:
218-
localized_system = LocalizedPVSystem(module_parameters=module,
219-
inverter_parameters=inverter,
220-
temperature_model_parameters=temperature_model_parameters,
221-
surface_tilt=latitude,
222-
surface_azimuth=180,
223-
latitude=latitude,
224-
longitude=longitude,
225-
name=name,
226-
altitude=altitude,
227-
tz=timezone)
228-
times = naive_times.tz_localize(timezone)
229-
clearsky = localized_system.get_clearsky(times)
230-
solar_position = localized_system.get_solarposition(times)
231-
total_irrad = localized_system.get_irradiance(solar_position['apparent_zenith'],
232-
solar_position['azimuth'],
233-
clearsky['dni'],
234-
clearsky['ghi'],
235-
clearsky['dhi'])
236-
tcell = localized_system.sapm_celltemp(total_irrad['poa_global'],
237-
temp_air, wind_speed)
238-
aoi = localized_system.get_aoi(solar_position['apparent_zenith'],
239-
solar_position['azimuth'])
240-
airmass = localized_system.get_airmass(solar_position=solar_position)
241-
effective_irradiance = localized_system.sapm_effective_irradiance(
242-
total_irrad['poa_direct'], total_irrad['poa_diffuse'],
243-
airmass['airmass_absolute'], aoi)
244-
dc = localized_system.sapm(effective_irradiance, tcell)
245-
ac = localized_system.snlinverter(dc['v_mp'], dc['p_mp'])
246-
annual_energy = ac.sum()
247-
energies[name] = annual_energy
248-
249-
energies = pd.Series(energies)
250-
251-
# based on the parameters specified above, these are in W*hrs
252-
print(energies.round(0))
253-
254-
energies.plot(kind='bar', rot=0)
255-
@savefig localized-pvsystem-energies.png width=6in
256-
plt.ylabel('Yearly energy yield (W hr)')
257-
@suppress
258-
plt.close();

docs/sphinx/source/whatsnew/v0.8.0.rst

+11
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ API Changes with Deprecations
3232
glass/glass module in open racking and emit a warning. In v0.9, users must
3333
provide ``temperature_model_parameters`` or a valid combination of
3434
``module_type`` and ``racking_model``. (:issue:`1030`, :pull:`1033`)
35+
* Deprecated arbitrary keyword arguments for
36+
:py:class:`pvlib.location.Location`, :py:class:`pvlib.pvsystem.PVSystem`,
37+
:py:class:`pvlib.tracking.SingleAxisTracker`, and
38+
:py:class:`pvlib.modelchain.ModelChain`. Supplying arbitrary keyword
39+
to these objects will result in TypeErrors in v0.9. (:issue:`1029`, :pull:`1053`)
40+
* ``pvlib.pvsystem.LocalizedPVSystem`` and ``pvlib.pvsystem.LocalizedSingleAxisTracker``
41+
are deprecated and will be removed in 0.9. Use
42+
:py:class:`pvlib.location.Location`, :py:class:`pvlib.pvsystem.PVSystem`,
43+
:py:class:`pvlib.tracking.SingleAxisTracker`, and
44+
:py:class:`pvlib.modelchain.ModelChain` instead.
45+
(:issue:`1029`, :pull:`1034`, :pull:`1053`)
3546

3647
API Changes
3748
~~~~~~~~~~~

pvlib/location.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
# Will Holmgren, University of Arizona, 2014-2016.
66

77
import datetime
8+
import warnings
89

910
import pandas as pd
1011
import pytz
1112

1213
from pvlib import solarposition, clearsky, atmosphere, irradiance
14+
from pvlib._deprecation import pvlibDeprecationWarning
1315

1416

1517
class Location:
@@ -48,10 +50,6 @@ class Location:
4850
name : None or string, default None.
4951
Sets the name attribute of the Location object.
5052
51-
**kwargs
52-
Arbitrary keyword arguments.
53-
Included for compatibility, but not used.
54-
5553
See also
5654
--------
5755
pvlib.pvsystem.PVSystem
@@ -82,6 +80,12 @@ def __init__(self, latitude, longitude, tz='UTC', altitude=0,
8280

8381
self.name = name
8482

83+
if kwargs:
84+
warnings.warn(
85+
'Arbitrary Location kwargs are deprecated and will be '
86+
'removed in v0.9', pvlibDeprecationWarning
87+
)
88+
8589
def __repr__(self):
8690
attrs = ['name', 'latitude', 'longitude', 'altitude', 'tz']
8791
return ('Location: \n ' + '\n '.join(

pvlib/modelchain.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,6 @@ class ModelChain:
333333
334334
name: None or str, default None
335335
Name of ModelChain instance.
336-
337-
**kwargs
338-
Arbitrary keyword arguments. Included for compatibility, but not
339-
used.
340336
"""
341337

342338
def __init__(self, system, location,
@@ -372,6 +368,12 @@ def __init__(self, system, location,
372368
self.times = None
373369
self.solar_position = None
374370

371+
if kwargs:
372+
warnings.warn(
373+
'Arbitrary ModelChain kwargs are deprecated and will be '
374+
'removed in v0.9', pvlibDeprecationWarning
375+
)
376+
375377
@classmethod
376378
def with_pvwatts(cls, system, location,
377379
orientation_strategy=None,

pvlib/pvsystem.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,6 @@ class PVSystem:
7979
:py:class:`~pvlib.modelchain.ModelChain`
8080
objects.
8181
82-
See the :py:class:`LocalizedPVSystem` class for an object model that
83-
describes an installed PV system.
84-
8582
The class supports basic system topologies consisting of:
8683
8784
* `N` total modules arranged in series
@@ -164,7 +161,6 @@ class PVSystem:
164161
--------
165162
pvlib.location.Location
166163
pvlib.tracking.SingleAxisTracker
167-
pvlib.pvsystem.LocalizedPVSystem
168164
"""
169165

170166
def __init__(self,
@@ -220,6 +216,12 @@ def __init__(self,
220216

221217
self.name = name
222218

219+
if kwargs:
220+
warnings.warn(
221+
'Arbitrary PVSystem kwargs are deprecated and will be '
222+
'removed in v0.9', pvlibDeprecationWarning
223+
)
224+
223225
def __repr__(self):
224226
attrs = ['name', 'surface_tilt', 'surface_azimuth', 'module',
225227
'inverter', 'albedo', 'racking_model', 'module_type',
@@ -819,9 +821,12 @@ def pvwatts_ac(self, pdc):
819821
return inverter.pvwatts(pdc, self.inverter_parameters['pdc0'],
820822
**kwargs)
821823

824+
@deprecated('0.8', alternative='PVSystem, Location, and ModelChain',
825+
name='PVSystem.localize', removal='0.9')
822826
def localize(self, location=None, latitude=None, longitude=None,
823827
**kwargs):
824-
"""Creates a LocalizedPVSystem object using this object
828+
"""
829+
Creates a LocalizedPVSystem object using this object
825830
and location data. Must supply either location object or
826831
latitude, longitude, and any location kwargs
827832
@@ -843,6 +848,8 @@ def localize(self, location=None, latitude=None, longitude=None,
843848
return LocalizedPVSystem(pvsystem=self, location=location)
844849

845850

851+
@deprecated('0.8', alternative='PVSystem, Location, and ModelChain',
852+
name='LocalizedPVSystem', removal='0.9')
846853
class LocalizedPVSystem(PVSystem, Location):
847854
"""
848855
The LocalizedPVSystem class defines a standard set of installed PV

pvlib/tests/test_location.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
from pvlib.solarposition import declination_spencer71
1717
from pvlib.solarposition import equation_of_time_spencer71
1818
from test_solarposition import expected_solpos, golden, golden_mst
19-
from conftest import requires_ephem, requires_tables
19+
from pvlib._deprecation import pvlibDeprecationWarning
20+
from conftest import requires_ephem, requires_tables, fail_on_pvlib_version
2021

2122

2223
def test_location_required():
@@ -323,3 +324,10 @@ def test_get_sun_rise_set_transit_valueerror(golden):
323324
tz='MST')
324325
with pytest.raises(ValueError):
325326
golden.get_sun_rise_set_transit(times, method='eyeball')
327+
328+
329+
@fail_on_pvlib_version('0.9')
330+
def test_deprecated_09():
331+
match = "Arbitrary Location kwargs"
332+
with pytest.warns(pvlibDeprecationWarning, match=match):
333+
Location(32.2, -111, arbitrary_kwarg='value')

pvlib/tests/test_modelchain.py

+7
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,13 @@ def test_deprecated_09(sapm_dc_snl_ac_system, cec_dc_adr_ac_system,
776776
aoi_model='no_loss', spectral_model='no_loss')
777777

778778

779+
@fail_on_pvlib_version('0.9')
780+
def test_ModelChain_kwargs_deprecated_09(sapm_dc_snl_ac_system, location):
781+
match = "Arbitrary ModelChain kwargs"
782+
with pytest.warns(pvlibDeprecationWarning, match=match):
783+
ModelChain(sapm_dc_snl_ac_system, location, arbitrary_kwarg='value')
784+
785+
779786
def test_basic_chain_required(sam_data, cec_inverter_parameters,
780787
sapm_temperature_cs5p_220m):
781788
times = pd.date_range(start='20160101 1200-0700',

pvlib/tests/test_pvsystem.py

+23-11
Original file line numberDiff line numberDiff line change
@@ -1064,20 +1064,24 @@ def test_PVSystem_get_irradiance():
10641064
assert_frame_equal(irradiance, expected, check_less_precise=2)
10651065

10661066

1067+
@fail_on_pvlib_version('0.9')
10671068
def test_PVSystem_localize_with_location():
10681069
system = pvsystem.PVSystem(module='blah', inverter='blarg')
10691070
location = Location(latitude=32, longitude=-111)
1070-
localized_system = system.localize(location=location)
1071+
with pytest.warns(pvlibDeprecationWarning):
1072+
localized_system = system.localize(location=location)
10711073

10721074
assert localized_system.module == 'blah'
10731075
assert localized_system.inverter == 'blarg'
10741076
assert localized_system.latitude == 32
10751077
assert localized_system.longitude == -111
10761078

10771079

1080+
@fail_on_pvlib_version('0.9')
10781081
def test_PVSystem_localize_with_latlon():
10791082
system = pvsystem.PVSystem(module='blah', inverter='blarg')
1080-
localized_system = system.localize(latitude=32, longitude=-111)
1083+
with pytest.warns(pvlibDeprecationWarning):
1084+
localized_system = system.localize(latitude=32, longitude=-111)
10811085

10821086
assert localized_system.module == 'blah'
10831087
assert localized_system.inverter == 'blarg'
@@ -1103,11 +1107,13 @@ def test_PVSystem___repr__():
11031107
assert system.__repr__() == expected
11041108

11051109

1110+
@fail_on_pvlib_version('0.9')
11061111
def test_PVSystem_localize___repr__():
11071112
system = pvsystem.PVSystem(
11081113
module='blah', inverter='blarg', name='pv ftw',
11091114
temperature_model_parameters={'a': -3.56})
1110-
localized_system = system.localize(latitude=32, longitude=-111)
1115+
with pytest.warns(pvlibDeprecationWarning):
1116+
localized_system = system.localize(latitude=32, longitude=-111)
11111117
# apparently name is not preserved when creating a system using localize
11121118
expected = """LocalizedPVSystem:
11131119
name: None
@@ -1131,23 +1137,26 @@ def test_PVSystem_localize___repr__():
11311137
# when they are attached to LocalizedPVSystem, but
11321138
# that's probably not necessary at this point.
11331139

1134-
1140+
@fail_on_pvlib_version('0.9')
11351141
def test_LocalizedPVSystem_creation():
1136-
localized_system = pvsystem.LocalizedPVSystem(latitude=32,
1137-
longitude=-111,
1138-
module='blah',
1139-
inverter='blarg')
1142+
with pytest.warns(pvlibDeprecationWarning):
1143+
localized_system = pvsystem.LocalizedPVSystem(latitude=32,
1144+
longitude=-111,
1145+
module='blah',
1146+
inverter='blarg')
11401147

11411148
assert localized_system.module == 'blah'
11421149
assert localized_system.inverter == 'blarg'
11431150
assert localized_system.latitude == 32
11441151
assert localized_system.longitude == -111
11451152

11461153

1154+
@fail_on_pvlib_version('0.9')
11471155
def test_LocalizedPVSystem___repr__():
1148-
localized_system = pvsystem.LocalizedPVSystem(
1149-
latitude=32, longitude=-111, module='blah', inverter='blarg',
1150-
name='my name', temperature_model_parameters={'a': -3.56})
1156+
with pytest.warns(pvlibDeprecationWarning):
1157+
localized_system = pvsystem.LocalizedPVSystem(
1158+
latitude=32, longitude=-111, module='blah', inverter='blarg',
1159+
name='my name', temperature_model_parameters={'a': -3.56})
11511160

11521161
expected = """LocalizedPVSystem:
11531162
name: my name
@@ -1311,3 +1320,6 @@ def test_deprecated_09(cec_inverter_parameters, adr_inverter_parameters):
13111320
system = pvsystem.PVSystem()
13121321
with pytest.warns(pvlibDeprecationWarning, match=match):
13131322
system.sapm_celltemp(1, 2, 3)
1323+
match = "Arbitrary PVSystem kwargs"
1324+
with pytest.warns(pvlibDeprecationWarning, match=match):
1325+
system = pvsystem.PVSystem(arbitrary_kwarg='value')

0 commit comments

Comments
 (0)