Repository: pvlib/pvlib-python
Pull request #797 (2019-10-23 16:01:12)

replace Pandas item() implementation with numpy's using .values
pvlib python pull request guidelines
====================================

Thank you for your contribution to pvlib python! You may delete all of these instructions except for the list below.

You may submit a pull request with your code at any stage of completion.

The following items must be addressed before the code can be merged. Please don't hesitate to ask for help if you're unsure of how to accomplish any of the items below:

 - [X] Closes  #794 
 - [X] I am familiar with the [contributing guidelines](http://pvlib-python.readthedocs.io/en/latest/contributing.html).
 - [X] Fully tested. Added and/or modified tests to ensure correct behavior for all reasonable inputs. Tests (usually) must pass on the TravisCI and Appveyor testing services.
* More tests passed, less warnings (probably from removing the deprecated) but one more test skipped.

 - [X] Updates entries to `docs/sphinx/source/api.rst` for API changes.
 - [x] Adds description and name entries in the appropriate `docs/sphinx/source/whatsnew` file for all changes.
* I'll do this once this method is review/approved.
 - [ ] Code quality and style is sufficient. Passes LGTM and SticklerCI checks.
 - [x] New code is fully documented. Includes sphinx/numpydoc compliant docstrings and comments in the code where necessary.
 - [x] Pull request is nearly complete and ready for detailed review.

Brief description of the problem and proposed solution (if not already fully described in the issue linked to above):

Pandas is deprecating Series.item() and warns against it for 0.25+. I've replaced the item() call with the values.item() which is a numpy method that's not going anywhere. This is exactly how Series.item() works and shouldn't change how _scalar_out() works.

Edit: [Here's a link to the pandas source code for .item() for reference](https://github.com/pandas-dev/pandas/blob/v0.25.2/pandas/core/base.py#L724-L740)



Patch:
diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py
index 16bd7ba..4786667 100644
--- a/pvlib/modelchain.py
+++ b/pvlib/modelchain.py
@@ -324,13 +324,15 @@ class ModelChain(object):
         # TODO: deprecated kwarg temp_model. Remove use of temp_model in v0.8
         temp_model = kwargs.pop('temp_model', None)
         if temp_model is not None:
-            warnings.warn('The temp_model keyword argument is deprecated. Use '
-                          'temperature_model instead', pvlibDeprecationWarning)
             if temperature_model is None:
+                warnings.warn('The temp_model keyword argument is deprecated.'
+                              ' Use temperature_model instead',
+                              pvlibDeprecationWarning)
                 temperature_model = temp_model
             elif temp_model == temperature_model:
                 warnings.warn('Provide only one of temperature_model or '
-                              'temp_model (deprecated).')
+                              'temp_model (deprecated).',
+                              pvlibDeprecationWarning)
             else:
                 raise ValueError(
                     'Conflicting temperature_model {} and temp_model {}. '
diff --git a/pvlib/tools.py b/pvlib/tools.py
index cbd59a8..dfeb817 100644
--- a/pvlib/tools.py
+++ b/pvlib/tools.py
@@ -212,7 +212,7 @@ def _scalar_out(input):
     else:  #
         # works if it's a 1 length array and
         # will throw a ValueError otherwise
-        output = input.item()
+        output = np.asarray(input).item()
 
     return output
 


Test patch:
diff --git a/pvlib/test/test_modelchain.py b/pvlib/test/test_modelchain.py
index c4d7c7a..cafaa81 100644
--- a/pvlib/test/test_modelchain.py
+++ b/pvlib/test/test_modelchain.py
@@ -470,10 +470,10 @@ def test_infer_aoi_model(location, system_no_aoi, aoi_model):
 
 
 def test_infer_aoi_model_invalid(location, system_no_aoi):
-    with pytest.raises(ValueError) as excinfo:
+    exc_text = 'could not infer AOI model'
+    with pytest.raises(ValueError, match=exc_text):
         ModelChain(system_no_aoi, location, orientation_strategy='None',
                    spectral_model='no_loss')
-    assert 'could not infer AOI model' in str(excinfo.value)
 
 
 def constant_spectral_loss(mc):
@@ -593,29 +593,26 @@ def test_deprecated_08():
     module_parameters = {'R_sh_ref': 1, 'a_ref': 1, 'I_o_ref': 1,
                          'alpha_sc': 1, 'I_L_ref': 1, 'R_s': 1}
     # do not assign PVSystem.temperature_model_parameters
+    # leave out PVSystem.racking_model and PVSystem.module_type
     system = PVSystem(module_parameters=module_parameters)
-    with pytest.warns(pvlibDeprecationWarning):
-        ModelChain(system, location,
-                   dc_model='desoto',
-                   aoi_model='no_loss', spectral_model='no_loss',
-                   temp_model='sapm',
-                   ac_model='snlinverter')
-    system = PVSystem(module_parameters=module_parameters)
-    with pytest.warns(pvlibDeprecationWarning):
-        ModelChain(system, location,
-                   dc_model='desoto',
-                   aoi_model='no_loss', spectral_model='no_loss',
-                   temperature_model='sapm',
-                   temp_model='sapm',
-                   ac_model='snlinverter')
-    system = PVSystem(module_parameters=module_parameters)
-    with pytest.raises(ValueError):
-        ModelChain(system, location,
-                   dc_model='desoto',
-                   aoi_model='no_loss', spectral_model='no_loss',
-                   temperature_model='pvsyst',
-                   temp_model='sapm',
-                   ac_model='snlinverter')
+    # deprecated temp_model kwarg
+    warn_txt = 'temp_model keyword argument is deprecated'
+    with pytest.warns(pvlibDeprecationWarning, match=warn_txt):
+        ModelChain(system, location, dc_model='desoto', aoi_model='no_loss',
+                   spectral_model='no_loss', ac_model='snlinverter',
+                   temp_model='sapm')
+    # provide both temp_model and temperature_model kwargs
+    warn_txt = 'Provide only one of temperature_model'
+    with pytest.warns(pvlibDeprecationWarning, match=warn_txt):
+        ModelChain(system, location, dc_model='desoto', aoi_model='no_loss',
+                   spectral_model='no_loss', ac_model='snlinverter',
+                   temperature_model='sapm', temp_model='sapm')
+    # conflicting temp_model and temperature_model kwargs
+    exc_text = 'Conflicting temperature_model'
+    with pytest.raises(ValueError, match=exc_text):
+        ModelChain(system, location, dc_model='desoto', aoi_model='no_loss',
+                   spectral_model='no_loss', ac_model='snlinverter',
+                   temperature_model='pvsyst', temp_model='sapm')
 
 
 @requires_scipy
diff --git a/pvlib/test/test_pvsystem.py b/pvlib/test/test_pvsystem.py
index 8157c57..bc9f142 100644
--- a/pvlib/test/test_pvsystem.py
+++ b/pvlib/test/test_pvsystem.py
@@ -419,16 +419,20 @@ def test__infer_temperature_model_params():
     expected = temperature.TEMPERATURE_MODEL_PARAMETERS[
         'sapm']['open_rack_glass_polymer']
     assert expected == system._infer_temperature_model_params()
-    expected = temperature.TEMPERATURE_MODEL_PARAMETERS[
-        'pvsyst']['freestanding']
     system = pvsystem.PVSystem(module_parameters={},
                                racking_model='freestanding',
                                module_type='glass_polymer')
+    expected = temperature.TEMPERATURE_MODEL_PARAMETERS[
+        'pvsyst']['freestanding']
     assert expected == system._infer_temperature_model_params()
-    system = pvsystem.PVSystem(module_parameters={},
-                               racking_model='not_a_rack_model',
-                               module_type='glass_polymer')
-    assert {} == system._infer_temperature_model_params()
+
+
+def test__infer_temperature_model_params_deprec_warning():
+    warn_txt = "Reverting to deprecated default"
+    with pytest.warns(pvlibDeprecationWarning, match=warn_txt):
+        pvsystem.PVSystem(module_parameters={},
+                          racking_model='not_a_rack_model',
+                          module_type='glass_polymer')
 
 
 def test_calcparams_desoto(cec_module_params):