Repository: pvlib/pvlib-python

Issue:
PVSystem.temperature_model_parameters requirement
The `temperature_model_parameters` handling code below suggests to me that in 0.8 we're going to 

1. set default values `module_type=None` and `racking_model=None`.
2. require user to specify either `temperature_model_parameters` or both `module_type` and `racking_model`.

https://github.com/pvlib/pvlib-python/blob/27872b83b0932cc419116f79e442963cced935bb/pvlib/pvsystem.py#L208-L221

@cwhanse is that correct?

The problem is that the only way to see this warning is to supply an invalid `module_type` or `racking_model`. That's because `PVSystem._infer_temperature_model` is called before the code above, and it looks up the default `module_type` and `racking_model` and successfully finds temperature coefficients.

https://github.com/pvlib/pvlib-python/blob/27872b83b0932cc419116f79e442963cced935bb/pvlib/pvsystem.py#L201-L203

So I'm guessing that this warning has been seen by only a small fraction of people that need to see it. I'm ok moving forward with the removal in 0.8 or pushing to 0.9. 
remove deprecated functions in 0.8
`pvsystem`:
* `sapm_celltemp`
* `pvsyst_celltemp`
* `ashraeiam`
* `physicaliam`
* `sapm_aoi_loss`
* `PVSystem.ashraeiam`
* `PVSystem.physicaliam`
* `PVSystem.sapm_aoi_loss`
* inference of `PVSystem.temperature_model_parameters`

`modelchain.ModelChain`:
* remove `times` from `complete_irradiance`, `prepare_inputs`, `run_model`
* remove `temp_model` kwarg


Discussion:
> The `temperature_model_parameters` handling code below suggests to me that in 0.8 we're going to
> 
> 1. set default values `module_type=None` and `racking_model=None`.
> 2. require user to specify either `temperature_model_parameters` or both `module_type` and `racking_model`.
> 
> @cwhanse is that correct?

Yes, that is the intent.

> So I'm guessing that this warning has been seen by only a small fraction of people that need to see it. I'm ok moving forward with the removal in 0.8 or pushing to 0.9.

The warning should have been raised whenever condition #2 above wasn't met; it looks to me that has been the case. If that hasn't been the case I would prefer to fix the warning and push the deprecation out to v0.9. pvlib-python has had that unadvertised default temperature model assignment for a long time.

> The problem is that the only way to see this warning is to supply an invalid `module_type` or `racking_model`. That's because `PVSystem._infer_temperature_model` is called before the code above, and it looks up the default `module_type` and `racking_model` and successfully finds temperature coefficients.

I don't follow here - it looks to me that the warning should be raised if 1) `temperature_model_parameters` isn't specified, or 2) either `module_type` or `racking_model` are invalid. Maybe we're saying the same thing. `_infer_temperature_model` doesn't assign the default temperature model, that is done in the block of code that raises the warning. 


The `module_type` and `racking_model` defaults prevent the warning from showing up in many use cases. If we change the defaults to `None` then the warning will be triggered. If we simultaneously remove the warning then code will break without users having ever seen the warning.
What is the expected behavior for `PVSystem()`?
> The `module_type` and `racking_model` defaults prevent the warning from showing up in many use cases. If we change the defaults to `None` then the warning will be triggered. If we simultaneously remove the warning then code will break without users having ever seen the warning.

Aha. I see the problem now, thanks.  Perhaps remove the defaults in v0.8 and leave the warning until v0.9?
Ok, I'll work on that.


Patch:
diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py
--- a/pvlib/modelchain.py
+++ b/pvlib/modelchain.py
@@ -179,7 +179,7 @@ def basic_chain(times, latitude, longitude,
             linke_turbidity,
             altitude=altitude,
             dni_extra=dni_extra
-            )
+        )
 
     total_irrad = pvlib.irradiance.get_total_irradiance(
         surface_tilt,
@@ -346,24 +346,6 @@ def __init__(self, system, location,
         self.ac_model = ac_model
         self.aoi_model = aoi_model
         self.spectral_model = spectral_model
-
-        # 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:
-            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).',
-                              pvlibDeprecationWarning)
-            else:
-                raise ValueError(
-                    'Conflicting temperature_model {} and temp_model {}. '
-                    'temp_model is deprecated. Specify only temperature_model.'
-                    .format(temperature_model, temp_model))
         self.temperature_model = temperature_model
 
         self.losses_model = losses_model
@@ -544,7 +526,7 @@ def __repr__(self):
             'transposition_model', 'solar_position_method',
             'airmass_model', 'dc_model', 'ac_model', 'aoi_model',
             'spectral_model', 'temperature_model', 'losses_model'
-            ]
+        ]
 
         def getmcattr(self, attr):
             """needed to avoid recursion in property lookups"""
@@ -588,8 +570,8 @@ def dc_model(self, model):
             model = model.lower()
             if model in _DC_MODEL_PARAMS.keys():
                 # validate module parameters
-                missing_params = _DC_MODEL_PARAMS[model] - \
-                                 set(self.system.module_parameters.keys())
+                missing_params = (_DC_MODEL_PARAMS[model]
+                                  - set(self.system.module_parameters.keys()))
                 if missing_params:  # some parameters are not in module.keys()
                     raise ValueError(model + ' selected for the DC model but '
                                      'one or more required parameters are '
@@ -834,8 +816,8 @@ def infer_spectral_model(self):
 
     def first_solar_spectral_loss(self):
         self.spectral_modifier = self.system.first_solar_spectral_loss(
-                                        self.weather['precipitable_water'],
-                                        self.airmass['airmass_absolute'])
+            self.weather['precipitable_water'],
+            self.airmass['airmass_absolute'])
         return self
 
     def sapm_spectral_loss(self):
@@ -878,7 +860,10 @@ def temperature_model(self, model):
 
     def infer_temperature_model(self):
         params = set(self.system.temperature_model_parameters.keys())
-        if set(['a', 'b', 'deltaT']) <= params:
+        # remove or statement in v0.9
+        if set(['a', 'b', 'deltaT']) <= params or (
+                not params and self.system.racking_model is None
+                and self.system.module_type is None):
             return self.sapm_temp
         elif set(['u_c', 'u_v']) <= params:
             return self.pvsyst_temp
@@ -945,7 +930,7 @@ def effective_irradiance_model(self):
             fd*self.total_irrad['poa_diffuse'])
         return self
 
-    def complete_irradiance(self, weather, times=None):
+    def complete_irradiance(self, weather):
         """
         Determine the missing irradiation columns. Only two of the
         following data columns (dni, ghi, dhi) are needed to calculate
@@ -962,10 +947,6 @@ def complete_irradiance(self, weather, times=None):
             ``'wind_speed'``, ``'temp_air'``. All irradiance components
             are required. Air temperature of 20 C and wind speed
             of 0 m/s will be added to the DataFrame if not provided.
-        times : None, deprecated
-            Deprecated argument included for API compatibility, but not
-            used internally. The index of the weather DataFrame is used
-            for times.
 
         Returns
         -------
@@ -994,11 +975,6 @@ def complete_irradiance(self, weather, times=None):
         """
         self.weather = weather
 
-        if times is not None:
-            warnings.warn('times keyword argument is deprecated and will be '
-                          'removed in 0.8. The index of the weather DataFrame '
-                          'is used for times.', pvlibDeprecationWarning)
-
         self.solar_position = self.location.get_solarposition(
             self.weather.index, method=self.solar_position_method)
 
@@ -1029,7 +1005,7 @@ def complete_irradiance(self, weather, times=None):
 
         return self
 
-    def prepare_inputs(self, weather, times=None):
+    def prepare_inputs(self, weather):
         """
         Prepare the solar position, irradiance, and weather inputs to
         the model.
@@ -1041,10 +1017,6 @@ def prepare_inputs(self, weather, times=None):
             ``'wind_speed'``, ``'temp_air'``. All irradiance components
             are required. Air temperature of 20 C and wind speed
             of 0 m/s will be added to the DataFrame if not provided.
-        times : None, deprecated
-            Deprecated argument included for API compatibility, but not
-            used internally. The index of the weather DataFrame is used
-            for times.
 
         Notes
         -----
@@ -1064,11 +1036,6 @@ def prepare_inputs(self, weather, times=None):
 
         self.weather = weather
 
-        if times is not None:
-            warnings.warn('times keyword argument is deprecated and will be '
-                          'removed in 0.8. The index of the weather DataFrame '
-                          'is used for times.', pvlibDeprecationWarning)
-
         self.times = self.weather.index
         try:
             kwargs = _build_kwargs(['pressure', 'temp_air'], weather)
@@ -1126,7 +1093,7 @@ def prepare_inputs(self, weather, times=None):
             self.weather['temp_air'] = 20
         return self
 
-    def run_model(self, weather, times=None):
+    def run_model(self, weather):
         """
         Run the model.
 
@@ -1137,10 +1104,6 @@ def run_model(self, weather, times=None):
             ``'wind_speed'``, ``'temp_air'``. All irradiance components
             are required. Air temperature of 20 C and wind speed
             of 0 m/s will be added to the DataFrame if not provided.
-        times : None, deprecated
-            Deprecated argument included for API compatibility, but not
-            used internally. The index of the weather DataFrame is used
-            for times.
 
         Returns
         -------
@@ -1152,11 +1115,6 @@ def run_model(self, weather, times=None):
         ``dc``, ``ac``, ``losses``,
         ``diode_params`` (if dc_model is a single diode model)
         """
-        if times is not None:
-            warnings.warn('times keyword argument is deprecated and will be '
-                          'removed in 0.8. The index of the weather DataFrame '
-                          'is used for times.', pvlibDeprecationWarning)
-
         self.prepare_inputs(weather)
         self.aoi_model()
         self.spectral_model()
diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py
--- a/pvlib/pvsystem.py
+++ b/pvlib/pvsystem.py
@@ -170,12 +170,12 @@ class PVSystem(object):
     def __init__(self,
                  surface_tilt=0, surface_azimuth=180,
                  albedo=None, surface_type=None,
-                 module=None, module_type='glass_polymer',
+                 module=None, module_type=None,
                  module_parameters=None,
                  temperature_model_parameters=None,
                  modules_per_string=1, strings_per_inverter=1,
                  inverter=None, inverter_parameters=None,
-                 racking_model='open_rack', losses_parameters=None, name=None,
+                 racking_model=None, losses_parameters=None, name=None,
                  **kwargs):
 
         self.surface_tilt = surface_tilt
@@ -201,25 +201,9 @@ def __init__(self,
         if temperature_model_parameters is None:
             self.temperature_model_parameters = \
                 self._infer_temperature_model_params()
-            # TODO: in v0.8 check if an empty dict is returned and raise error
         else:
             self.temperature_model_parameters = temperature_model_parameters
 
-        # TODO: deprecated behavior if PVSystem.temperature_model_parameters
-        # are not specified. Remove in v0.8
-        if not any(self.temperature_model_parameters):
-            warnings.warn(
-                'Required temperature_model_parameters is not specified '
-                'and parameters are not inferred from racking_model and '
-                'module_type. Reverting to deprecated default: SAPM cell '
-                'temperature model parameters for a glass/glass module in '
-                'open racking. In the future '
-                'PVSystem.temperature_model_parameters will be required',
-                pvlibDeprecationWarning)
-            params = temperature._temperature_model_params(
-                'sapm', 'open_rack_glass_glass')
-            self.temperature_model_parameters = params
-
         self.modules_per_string = modules_per_string
         self.strings_per_inverter = strings_per_inverter
 
@@ -358,26 +342,6 @@ def get_iam(self, aoi, iam_model='physical'):
         else:
             raise ValueError(model + ' is not a valid IAM model')
 
-    def ashraeiam(self, aoi):
-        """
-        Deprecated. Use ``PVSystem.get_iam`` instead.
-        """
-        import warnings
-        warnings.warn('PVSystem.ashraeiam is deprecated and will be removed in'
-                      'v0.8, use PVSystem.get_iam instead',
-                      pvlibDeprecationWarning)
-        return PVSystem.get_iam(self, aoi, iam_model='ashrae')
-
-    def physicaliam(self, aoi):
-        """
-        Deprecated. Use ``PVSystem.get_iam`` instead.
-        """
-        import warnings
-        warnings.warn('PVSystem.physicaliam is deprecated and will be removed'
-                      ' in v0.8, use PVSystem.get_iam instead',
-                      pvlibDeprecationWarning)
-        return PVSystem.get_iam(self, aoi, iam_model='physical')
-
     def calcparams_desoto(self, effective_irradiance, temp_cell, **kwargs):
         """
         Use the :py:func:`calcparams_desoto` function, the input
@@ -506,6 +470,21 @@ def sapm_celltemp(self, poa_global, temp_air, wind_speed):
         -------
         numeric, values in degrees C.
         """
+        # warn user about change in default behavior in 0.9.
+        if (self.temperature_model_parameters == {} and self.module_type
+                is None and self.racking_model is None):
+            warnings.warn(
+                'temperature_model_parameters, racking_model, and module_type '
+                'are not specified. Reverting to deprecated default: SAPM '
+                'cell temperature model parameters for a glass/glass module '
+                'in open racking. In v0.9, temperature_model_parameters or a '
+                'valid combination of racking_model and module_type will be '
+                'required.',
+                pvlibDeprecationWarning)
+            params = temperature._temperature_model_params(
+                'sapm', 'open_rack_glass_glass')
+            self.temperature_model_parameters = params
+
         kwargs = _build_kwargs(['a', 'b', 'deltaT'],
                                self.temperature_model_parameters)
         return temperature.sapm_cell(poa_global, temp_air, wind_speed,
@@ -514,7 +493,7 @@ def sapm_celltemp(self, poa_global, temp_air, wind_speed):
     def _infer_temperature_model_params(self):
         # try to infer temperature model parameters from from racking_model
         # and module_type
-        param_set = self.racking_model + '_' + self.module_type
+        param_set = '{}_{}'.format(self.racking_model, self.module_type)
         if param_set in temperature.TEMPERATURE_MODEL_PARAMETERS['sapm']:
             return temperature._temperature_model_params('sapm', param_set)
         elif 'freestanding' in param_set:
@@ -543,16 +522,6 @@ def sapm_spectral_loss(self, airmass_absolute):
         """
         return sapm_spectral_loss(airmass_absolute, self.module_parameters)
 
-    def sapm_aoi_loss(self, aoi):
-        """
-        Deprecated. Use ``PVSystem.get_iam`` instead.
-        """
-        import warnings
-        warnings.warn('PVSystem.sapm_aoi_loss is deprecated and will be'
-                      ' removed in v0.8, use PVSystem.get_iam instead',
-                      pvlibDeprecationWarning)
-        return PVSystem.get_iam(self, aoi, iam_model='sapm')
-
     def sapm_effective_irradiance(self, poa_direct, poa_diffuse,
                                   airmass_absolute, aoi,
                                   reference_irradiance=1000):
@@ -671,7 +640,7 @@ def first_solar_spectral_loss(self, pw, airmass_absolute):
         if 'first_solar_spectral_coefficients' in \
                 self.module_parameters.keys():
             coefficients = \
-                   self.module_parameters['first_solar_spectral_coefficients']
+                self.module_parameters['first_solar_spectral_coefficients']
             module_type = None
         else:
             module_type = self._infer_cell_type()
@@ -1071,27 +1040,6 @@ def calcparams_desoto(effective_irradiance, temp_cell,
          Source: [4]
     '''
 
-    # test for use of function pre-v0.6.0 API change
-    if isinstance(a_ref, dict) or \
-       (isinstance(a_ref, pd.Series) and ('a_ref' in a_ref.keys())):
-        import warnings
-        warnings.warn('module_parameters detected as fourth positional'
-                      + ' argument of calcparams_desoto. calcparams_desoto'
-                      + ' will require one argument for each module model'
-                      + ' parameter in v0.7.0 and later', DeprecationWarning)
-        try:
-            module_parameters = a_ref
-            a_ref = module_parameters['a_ref']
-            I_L_ref = module_parameters['I_L_ref']
-            I_o_ref = module_parameters['I_o_ref']
-            R_sh_ref = module_parameters['R_sh_ref']
-            R_s = module_parameters['R_s']
-        except Exception as e:
-            raise e('Module parameters could not be extracted from fourth'
-                    + ' positional argument of calcparams_desoto. Check that'
-                    + ' parameters are from the CEC database and/or update'
-                    + ' your code for the new API for calcparams_desoto')
-
     # Boltzmann constant in eV/K
     k = 8.617332478e-05
 
@@ -1624,16 +1572,6 @@ def sapm(effective_irradiance, temp_cell, module):
     # reference_irradiance and expose
     temp_ref = 25
     irrad_ref = 1000
-    # TODO: remove this warning in v0.8 after deprecation period for change in
-    # effective irradiance units, made in v0.7
-    with np.errstate(invalid='ignore'):  # turn off warning for NaN
-        ee = np.asarray(effective_irradiance)
-        ee_gt0 = ee[ee > 0.0]
-        if ee_gt0.size > 0 and np.all(ee_gt0 < 2.0):
-            import warnings
-            msg = 'effective_irradiance inputs appear to be in suns. Units ' \
-                  'changed in v0.7 from suns to W/m2'
-            warnings.warn(msg, RuntimeWarning)
 
     q = 1.60218e-19  # Elementary charge in units of coulombs
     kb = 1.38066e-23  # Boltzmann's constant in units of J/K
@@ -1695,85 +1633,6 @@ def sapm(effective_irradiance, temp_cell, module):
     return out
 
 
-def _sapm_celltemp_translator(*args, **kwargs):
-    # TODO: remove this function after deprecation period for sapm_celltemp
-    new_kwargs = {}
-    # convert position arguments to kwargs
-    old_arg_list = ['poa_global', 'wind_speed', 'temp_air', 'model']
-    for pos in range(len(args)):
-        new_kwargs[old_arg_list[pos]] = args[pos]
-    # determine value for new kwarg 'model'
-    try:
-        param_set = new_kwargs['model']
-        new_kwargs.pop('model')  # model is not a new kwarg
-    except KeyError:
-        # 'model' not in positional arguments, check kwargs
-        try:
-            param_set = kwargs['model']
-            kwargs.pop('model')
-        except KeyError:
-            # 'model' not in kwargs, use old default value
-            param_set = 'open_rack_glass_glass'
-    if type(param_set) is list:
-        new_kwargs.update({'a': param_set[0],
-                           'b': param_set[1],
-                           'deltaT': param_set[2]})
-    elif type(param_set) is dict:
-        new_kwargs.update(param_set)
-    else:  # string
-        params = temperature._temperature_model_params('sapm', param_set)
-        new_kwargs.update(params)
-    new_kwargs.update(kwargs)  # kwargs with unchanged names
-    new_kwargs['irrad_ref'] = 1000  # default for new kwarg
-    # convert old positional arguments to named kwargs
-    return temperature.sapm_cell(**new_kwargs)
-
-
-sapm_celltemp = deprecated('0.7', alternative='temperature.sapm_cell',
-                           name='sapm_celltemp', removal='0.8',
-                           addendum='Note that the arguments and argument '
-                           'order for temperature.sapm_cell are different '
-                           'than for sapm_celltemp')(_sapm_celltemp_translator)
-
-
-def _pvsyst_celltemp_translator(*args, **kwargs):
-    # TODO: remove this function after deprecation period for pvsyst_celltemp
-    new_kwargs = {}
-    # convert position arguments to kwargs
-    old_arg_list = ['poa_global', 'temp_air', 'wind_speed', 'eta_m',
-                    'alpha_absorption', 'model_params']
-    for pos in range(len(args)):
-        new_kwargs[old_arg_list[pos]] = args[pos]
-    # determine value for new kwarg 'model'
-    try:
-        param_set = new_kwargs['model_params']
-        new_kwargs.pop('model_params')  # model_params is not a new kwarg
-    except KeyError:
-        # 'model_params' not in positional arguments, check kwargs
-        try:
-            param_set = kwargs['model_params']
-            kwargs.pop('model_params')
-        except KeyError:
-            # 'model_params' not in kwargs, use old default value
-            param_set = 'freestanding'
-    if type(param_set) in (list, tuple):
-        new_kwargs.update({'u_c': param_set[0],
-                           'u_v': param_set[1]})
-    else:  # string
-        params = temperature._temperature_model_params('pvsyst', param_set)
-        new_kwargs.update(params)
-    new_kwargs.update(kwargs)  # kwargs with unchanged names
-    # convert old positional arguments to named kwargs
-    return temperature.pvsyst_cell(**new_kwargs)
-
-
-pvsyst_celltemp = deprecated(
-    '0.7', alternative='temperature.pvsyst_cell', name='pvsyst_celltemp',
-    removal='0.8', addendum='Note that the argument names for '
-    'temperature.pvsyst_cell are different than '
-    'for pvsyst_celltemp')(_pvsyst_celltemp_translator)
-
-
 def sapm_spectral_loss(airmass_absolute, module):
     """
     Calculates the SAPM spectral loss coefficient, F1.
@@ -2051,8 +1910,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
         # calculate the IV curve if requested using bishop88
         if ivcurve_pnts:
             vd = v_oc * (
-                    (11.0 - np.logspace(np.log10(11.0), 0.0,
-                                        ivcurve_pnts)) / 10.0
+                (11.0 - np.logspace(np.log10(11.0), 0.0, ivcurve_pnts)) / 10.0
             )
             ivcurve_i, ivcurve_v, _ = _singlediode.bishop88(vd, *args)
 
@@ -2301,17 +2159,17 @@ def i_from_v(resistance_shunt, resistance_series, nNsVth, voltage,
         # equation for the diode voltage V_d then backing out voltage
         args = (voltage, photocurrent, saturation_current, resistance_series,
                 resistance_shunt, nNsVth)
-        I = _singlediode.bishop88_i_from_v(*args, method=method.lower())
+        current = _singlediode.bishop88_i_from_v(*args, method=method.lower())
         # find the right size and shape for returns
         size, shape = _singlediode._get_size_and_shape(args)
         if size <= 1:
             if shape is not None:
-                I = np.tile(I, shape)
-        if np.isnan(I).any() and size <= 1:
-            I = np.repeat(I, size)
+                current = np.tile(current, shape)
+        if np.isnan(current).any() and size <= 1:
+            current = np.repeat(current, size)
             if shape is not None:
-                I = I.reshape(shape)
-        return I
+                current = current.reshape(shape)
+        return current
 
 
 def scale_voltage_current_power(data, voltage=1, current=1):
@@ -2390,7 +2248,7 @@ def pvwatts_dc(g_poa_effective, temp_cell, pdc0, gamma_pdc, temp_ref=25.):
     .. [1] A. P. Dobos, "PVWatts Version 5 Manual"
            http://pvwatts.nrel.gov/downloads/pvwattsv5.pdf
            (2014).
-    """
+    """  # noqa: E501
 
     pdc = (g_poa_effective * 0.001 * pdc0 *
            (1 + gamma_pdc * (temp_cell - temp_ref)))
@@ -2452,18 +2310,6 @@ def pvwatts_losses(soiling=2, shading=3, snow=0, mismatch=2, wiring=2,
     return losses
 
 
-ashraeiam = deprecated('0.7', alternative='iam.ashrae', name='ashraeiam',
-                       removal='0.8')(iam.ashrae)
-
-
-physicaliam = deprecated('0.7', alternative='iam.physical', name='physicaliam',
-                         removal='0.8')(iam.physical)
-
-
-sapm_aoi_loss = deprecated('0.7', alternative='iam.sapm', name='sapm_aoi_loss',
-                           removal='0.8')(iam.sapm)
-
-
 snlinverter = deprecated('0.8', alternative='inverter.sandia',
                          name='snlinverter', removal='0.9')(inverter.sandia)
 


Test patch:
diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py
--- a/pvlib/tests/test_modelchain.py
+++ b/pvlib/tests/test_modelchain.py
@@ -13,7 +13,7 @@
 from conftest import assert_series_equal
 import pytest
 
-from conftest import fail_on_pvlib_version, requires_scipy, requires_tables
+from conftest import fail_on_pvlib_version, requires_scipy
 
 
 @pytest.fixture(scope='function')
@@ -153,6 +153,18 @@ def system_no_aoi(cec_module_cs5p_220m, sapm_temperature_cs5p_220m,
     return system
 
 
+@pytest.fixture
+def system_no_temp(cec_module_cs5p_220m, cec_inverter_parameters):
+    module_parameters = cec_module_cs5p_220m.copy()
+    module_parameters['EgRef'] = 1.121
+    module_parameters['dEgdT'] = -0.0002677
+    inverter_parameters = cec_inverter_parameters.copy()
+    system = PVSystem(surface_tilt=32.2, surface_azimuth=180,
+                      module_parameters=module_parameters,
+                      inverter_parameters=inverter_parameters)
+    return system
+
+
 @pytest.fixture
 def location():
     return Location(32.2, -111, altitude=700)
@@ -211,24 +223,6 @@ def test_run_model_with_irradiance(sapm_dc_snl_ac_system, location):
     assert_series_equal(ac, expected)
 
 
-def test_run_model_times(sapm_dc_snl_ac_system, location):
-    mc = ModelChain(sapm_dc_snl_ac_system, location)
-    times = pd.date_range('20160101 1200-0700', periods=2, freq='6H')
-    irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150},
-                              index=times)
-    with pytest.warns(pvlibDeprecationWarning):
-        mc.run_model(irradiance, times=times)
-
-
-def test_prepare_inputs_times(sapm_dc_snl_ac_system, location):
-    mc = ModelChain(sapm_dc_snl_ac_system, location)
-    times = pd.date_range('20160101 1200-0700', periods=2, freq='6H')
-    irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150},
-                              index=times)
-    with pytest.warns(pvlibDeprecationWarning):
-        mc.prepare_inputs(irradiance, times=times)
-
-
 def test_prepare_inputs_no_irradiance(sapm_dc_snl_ac_system, location):
     mc = ModelChain(sapm_dc_snl_ac_system, location)
     weather = pd.DataFrame()
@@ -236,15 +230,6 @@ def test_prepare_inputs_no_irradiance(sapm_dc_snl_ac_system, location):
         mc.prepare_inputs(weather)
 
 
-@requires_tables
-def test_complete_irradiance_times(sapm_dc_snl_ac_system, location):
-    mc = ModelChain(sapm_dc_snl_ac_system, location)
-    times = pd.date_range('20160101 1200-0700', periods=2, freq='6H')
-    irradiance = pd.DataFrame({'ghi': 600., 'dhi': 150.}, index=times)
-    with pytest.warns(pvlibDeprecationWarning):
-        mc.complete_irradiance(irradiance, times=times)
-
-
 def test_run_model_perez(sapm_dc_snl_ac_system, location):
     mc = ModelChain(sapm_dc_snl_ac_system, location,
                     transposition_model='perez')
@@ -277,8 +262,6 @@ def test_run_model_with_weather_sapm_temp(sapm_dc_snl_ac_system, location,
     # test with sapm cell temperature model
     weather['wind_speed'] = 5
     weather['temp_air'] = 10
-    sapm_dc_snl_ac_system.racking_model = 'open_rack'
-    sapm_dc_snl_ac_system.module_type = 'glass_glass'
     mc = ModelChain(sapm_dc_snl_ac_system, location)
     mc.temperature_model = 'sapm'
     m_sapm = mocker.spy(sapm_dc_snl_ac_system, 'sapm_celltemp')
@@ -437,6 +420,17 @@ def test_infer_temp_model_invalid(location, sapm_dc_snl_ac_system):
                    spectral_model='no_loss')
 
 
+# ModelChain.infer_temperature_model. remove or statement in v0.9
+@requires_scipy
+@fail_on_pvlib_version('0.9')
+def test_infer_temp_model_no_params(location, system_no_temp, weather):
+    mc = ModelChain(system_no_temp, location, aoi_model='physical',
+                    spectral_model='no_loss')
+    match = "Reverting to deprecated default: SAPM cell temperature"
+    with pytest.warns(pvlibDeprecationWarning, match=match):
+        mc.run_model(weather)
+
+
 @requires_scipy
 def test_temperature_model_inconsistent(location, sapm_dc_snl_ac_system):
     with pytest.raises(ValueError):
@@ -688,36 +682,6 @@ def test_bad_get_orientation():
         modelchain.get_orientation('bad value')
 
 
-@fail_on_pvlib_version('0.8')
-def test_deprecated_08():
-    # explicit system creation call because fail_on_pvlib_version
-    # does not support decorators.
-    # does not matter what the parameters are, just fake it until we make it
-    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)
-    # 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='sandia',
-                   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='sandia',
-                   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='sandia',
-                   temperature_model='pvsyst', temp_model='sapm')
-
-
 @fail_on_pvlib_version('0.9')
 @pytest.mark.parametrize('ac_model', ['snlinverter', 'adrinverter'])
 def test_deprecated_09(sapm_dc_snl_ac_system, cec_dc_adr_ac_system,
diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py
--- a/pvlib/tests/test_pvsystem.py
+++ b/pvlib/tests/test_pvsystem.py
@@ -198,17 +198,6 @@ def test_sapm(sapm_module_params):
                   pd.Series(sapm_module_params))
 
 
-def test_pvsystem_sapm_warning(sapm_module_params):
-    # deprecation warning for change in effective_irradiance units in
-    # pvsystem.sapm
-    # TODO: remove after deprecation period (v0.8)
-    effective_irradiance = np.array([0.1, 0.2, 1.3])
-    temp_cell = np.array([25, 25, 50])
-    warn_txt = 'effective_irradiance inputs appear to be in suns'
-    with pytest.warns(RuntimeWarning, match=warn_txt):
-        pvsystem.sapm(effective_irradiance, temp_cell, sapm_module_params)
-
-
 def test_PVSystem_sapm(sapm_module_params, mocker):
     mocker.spy(pvsystem, 'sapm')
     system = pvsystem.PVSystem(module_parameters=sapm_module_params)
@@ -386,14 +375,6 @@ def test__infer_temperature_model_params():
     assert expected == 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):
     times = pd.date_range(start='2015-01-01', periods=3, freq='12H')
     effective_irradiance = pd.Series([0.0, 800.0, 800.0], index=times)
@@ -1130,8 +1111,8 @@ def test_PVSystem___repr__():
   module: blah
   inverter: blarg
   albedo: 0.25
-  racking_model: open_rack
-  module_type: glass_polymer
+  racking_model: None
+  module_type: None
   temperature_model_parameters: {'a': -3.56}"""
     assert system.__repr__() == expected
 
@@ -1153,8 +1134,8 @@ def test_PVSystem_localize___repr__():
   module: blah
   inverter: blarg
   albedo: 0.25
-  racking_model: open_rack
-  module_type: glass_polymer
+  racking_model: None
+  module_type: None
   temperature_model_parameters: {'a': -3.56}"""
 
     assert localized_system.__repr__() == expected
@@ -1193,8 +1174,8 @@ def test_LocalizedPVSystem___repr__():
   module: blah
   inverter: blarg
   albedo: 0.25
-  racking_model: open_rack
-  module_type: glass_polymer
+  racking_model: None
+  module_type: None
   temperature_model_parameters: {'a': -3.56}"""
 
     assert localized_system.__repr__() == expected
@@ -1318,94 +1299,6 @@ def test_PVSystem_pvwatts_ac_kwargs(mocker):
     assert out < pdc
 
 
-@fail_on_pvlib_version('0.8')
-def test_deprecated_08():
-    # deprecated function pvsystem.sapm_celltemp
-    with pytest.warns(pvlibDeprecationWarning):
-        pvsystem.sapm_celltemp(1000, 25, 1)
-    # deprecated function pvsystem.pvsyst_celltemp
-    with pytest.warns(pvlibDeprecationWarning):
-        pvsystem.pvsyst_celltemp(1000, 25)
-    module_parameters = {'R_sh_ref': 1, 'a_ref': 1, 'I_o_ref': 1,
-                         'alpha_sc': 1, 'I_L_ref': 1, 'R_s': 1,
-                         'B5': 0.0, 'B4': 0.0, 'B3': 0.0, 'B2': 0.0,
-                         'B1': 0.0, 'B0': 1.0,
-                         'b': 0.05, 'K': 4, 'L': 0.002, 'n': 1.526,
-                         'a_r': 0.16}
-    temp_model_params = temperature.TEMPERATURE_MODEL_PARAMETERS['sapm'][
-        'open_rack_glass_glass']
-    # for missing temperature_model_parameters
-    with pytest.warns(pvlibDeprecationWarning):
-        pvsystem.PVSystem(module_parameters=module_parameters,
-                          racking_model='open', module_type='glass_glass')
-    pv = pvsystem.PVSystem(module_parameters=module_parameters,
-                           temperature_model_parameters=temp_model_params,
-                           racking_model='open', module_type='glass_glass')
-    # deprecated method PVSystem.ashraeiam
-    with pytest.warns(pvlibDeprecationWarning):
-        pv.ashraeiam(45)
-    # deprecated function ashraeiam
-    with pytest.warns(pvlibDeprecationWarning):
-        pvsystem.ashraeiam(45)
-    # deprecated method PVSystem.physicaliam
-    with pytest.warns(pvlibDeprecationWarning):
-        pv.physicaliam(45)
-    # deprecated function physicaliam
-    with pytest.warns(pvlibDeprecationWarning):
-        pvsystem.physicaliam(45)
-    # deprecated method PVSystem.sapm_aoi_loss
-    with pytest.warns(pvlibDeprecationWarning):
-        pv.sapm_aoi_loss(45)
-    # deprecated function sapm_aoi_loss
-    with pytest.warns(pvlibDeprecationWarning):
-        pvsystem.sapm_aoi_loss(45, {'B5': 0.0, 'B4': 0.0, 'B3': 0.0, 'B2': 0.0,
-                                    'B1': 0.0, 'B0': 1.0})
-
-
-@fail_on_pvlib_version('0.8')
-def test__pvsyst_celltemp_translator():
-    result = pvsystem._pvsyst_celltemp_translator(900, 20, 5)
-    assert_allclose(result, 45.137, 0.001)
-    result = pvsystem._pvsyst_celltemp_translator(900, 20, 5, 0.1, 0.9,
-                                                  [29.0, 0.0])
-    assert_allclose(result, 45.137, 0.001)
-    result = pvsystem._pvsyst_celltemp_translator(poa_global=900, temp_air=20,
-                                                  wind_speed=5)
-    assert_allclose(result, 45.137, 0.001)
-    result = pvsystem._pvsyst_celltemp_translator(900, 20, wind_speed=5)
-    assert_allclose(result, 45.137, 0.001)
-    result = pvsystem._pvsyst_celltemp_translator(900, 20, wind_speed=5.0,
-                                                  u_c=23.5, u_v=6.25,
-                                                  eta_m=0.1)
-    assert_allclose(result, 33.315, 0.001)
-    result = pvsystem._pvsyst_celltemp_translator(900, 20, wind_speed=5.0,
-                                                  eta_m=0.1,
-                                                  model_params=[23.5, 6.25])
-    assert_allclose(result, 33.315, 0.001)
-    result = pvsystem._pvsyst_celltemp_translator(900, 20, wind_speed=5.0,
-                                                  eta_m=0.1,
-                                                  model_params=(23.5, 6.25))
-    assert_allclose(result, 33.315, 0.001)
-
-
-@fail_on_pvlib_version('0.8')
-def test__sapm_celltemp_translator():
-    result = pvsystem._sapm_celltemp_translator(900, 5, 20,
-                                                'open_rack_glass_glass')
-    assert_allclose(result, 43.509, 3)
-    result = pvsystem._sapm_celltemp_translator(900, 5, temp_air=20,
-                                                model='open_rack_glass_glass')
-    assert_allclose(result, 43.509, 3)
-    params = temperature.TEMPERATURE_MODEL_PARAMETERS['sapm'][
-        'open_rack_glass_glass']
-    result = pvsystem._sapm_celltemp_translator(900, 5, 20, params)
-    assert_allclose(result, 43.509, 3)
-    result = pvsystem._sapm_celltemp_translator(900, 5, 20,
-                                                [params['a'], params['b'],
-                                                 params['deltaT']])
-    assert_allclose(result, 43.509, 3)
-
-
 @fail_on_pvlib_version('0.9')
 def test_deprecated_09(cec_inverter_parameters, adr_inverter_parameters):
     # deprecated function pvsystem.snlinverter
@@ -1417,3 +1310,8 @@ def test_deprecated_09(cec_inverter_parameters, adr_inverter_parameters):
     # deprecated function pvsystem.spvwatts_ac
     with pytest.warns(pvlibDeprecationWarning):
         pvsystem.pvwatts_ac(90, 100, 0.95)
+    # for missing temperature_model_parameters
+    match = "Reverting to deprecated default: SAPM cell temperature"
+    system = pvsystem.PVSystem()
+    with pytest.warns(pvlibDeprecationWarning, match=match):
+        system.sapm_celltemp(1, 2, 3)
diff --git a/pvlib/tests/test_tracking.py b/pvlib/tests/test_tracking.py
--- a/pvlib/tests/test_tracking.py
+++ b/pvlib/tests/test_tracking.py
@@ -453,8 +453,8 @@ def test_SingleAxisTracker___repr__():
   module: blah
   inverter: blarg
   albedo: 0.25
-  racking_model: open_rack
-  module_type: glass_polymer
+  racking_model: None
+  module_type: None
   temperature_model_parameters: {'a': -3.56}"""
     assert system.__repr__() == expected
 
@@ -477,8 +477,8 @@ def test_LocalizedSingleAxisTracker___repr__():
   module: blah
   inverter: blarg
   albedo: 0.25
-  racking_model: open_rack
-  module_type: glass_polymer
+  racking_model: None
+  module_type: None
   temperature_model_parameters: {'a': -3.56}
   latitude: 32
   longitude: -111