-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Deprecate/raise error for PVSystem "pass-through" properties #1196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I think this is ready for review. It feels risky to me to use |
Can you elaborate? The tests pass and the diff is straightforward. We also have the property I'm +1 on this PR. Would be good to hear any comments/concerns from others before moving forward. |
Yes, sorry for not being clear. My concern is that code like this, which does not check that |
pvlib/modelchain.py
Outdated
'desoto', 'cec', 'pvsyst', 'pvwatts'. The ModelChain instance will | ||
be passed as the first argument to a user-defined function. | ||
|
||
ac_model: None, str, or function, default None | ||
If None, the model will be inferred from the contents of | ||
system.inverter_parameters and system.module_parameters. Valid | ||
strings are 'sandia', 'adr', 'pvwatts'. The | ||
system.inverter_parameters and system.arrays[i].module_parameters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see that infer_ac_model
uses any information from system.arrays
. The check on num_arrays
is meant to provide a more meaningful error message, if a user chooses the adr
inverter model that doesn't (presently) support multiple inputs.
Co-authored-by: Cliff Hansen <[email protected]>
It's not clear to me why codecov is flagging the diff coverage. When I calculate coverage locally it shows line 961 (really, 956) in modelchain.py covered as expected. @wholmgren ready for you to review when you get a chance. |
pvlib/modelchain.py
Outdated
'system.module_parameters or explicitly ' | ||
'set the model with the dc_model kwarg.') | ||
'system.arrays[i].module_parameters. Check ' | ||
'system.arrays[i].module_parameters or ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if this notation will make sense to some users. I'm fine with it, but here's an alternative:
Could not infer DC model from the module_parameters attributes of system.arrays. Check the module_parameters attributes or explicitly set the model with the dc_model keyword argument.
pvlib/pvsystem.py
Outdated
if len(self.arrays) > 1: | ||
raise AttributeError( | ||
f'{class_name}.{pvsystem_attr} not supported for multi-array ' | ||
f'systems. Use {alternative} instead.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consistent with my comment in modelchain.py, maybe something like:
{class_name}.{pvsystem_attr} not supported for multi-array systems. Set {array_attr} for each Array in {class_name}.arrays instead.
def module_type(self): | ||
return tuple(array.module_type for array in self.arrays) | ||
|
||
@property | ||
@_unwrap_single_value | ||
@_check_deprecated_passthrough | ||
def temperature_model_parameters(self): | ||
return tuple(array.temperature_model_parameters | ||
for array in self.arrays) | ||
|
||
@temperature_model_parameters.setter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setter
s were added in #1076, so the deprecation requirement is a little more subtle. I think we either need to implement deprecation setters for each attribute or implement a __setattr__
like this from modelchain:
pvlib-python/pvlib/modelchain.py
Lines 503 to 510 in 7eae1fc
def __setattr__(self, key, value): | |
if key in ModelChain._deprecated_attrs: | |
msg = f'ModelChain.{key} is deprecated from v0.9. Use' \ | |
f' ModelChain.results.{key} instead' | |
warnings.warn(msg, pvlibDeprecationWarning) | |
setattr(self.results, key, value) | |
else: | |
super().__setattr__(key, value) |
For that matter we could implement a __getattr__
instead of properties, like this one:
pvlib-python/pvlib/modelchain.py
Lines 491 to 501 in 7eae1fc
def __getattr__(self, key): | |
if key in ModelChain._deprecated_attrs: | |
msg = f'ModelChain.{key} is deprecated and will' \ | |
f' be removed in v0.10. Use' \ | |
f' ModelChain.results.{key} instead' | |
warnings.warn(msg, pvlibDeprecationWarning) | |
return getattr(self.results, key) | |
# __getattr__ is only called if __getattribute__ fails. | |
# In that case we should check if key is a deprecated attribute, | |
# and fail with an AttributeError if it is not. | |
raise AttributeError |
I don't know that one approach is better than another.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following the issue here, can you expand on what's different about the setter
s?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After trying to come up with an example, I'm realizing the problem is a little different than I first described.
There are currently setters for only 4 properties:
- temperature_model_parameters
- surface_tilt
- surface_azimuth
- racking_model
The remaining properties do not contain setters. At first I thought this meant that for all of the other properties, a user could set something on a PVSystem
object that's different than what they'd get back from a getter that inspects the Arrays. But I'm now reminded that the user simply will not be able to set them.
In [5]: system = PVSystem([Array()])
In [6]: system.albedo = 0.3
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-d89b04b86f95> in <module>
----> 1 system.albedo = 0.3
AttributeError: can't set attribute
So the issue is that the user can set some but not all of the deprecated attributes. I'd prefer if they could set none or all.
I brought up the __getattr__
and __setattr__
methods only as an alternative to the properties and setters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the issue is that the user can set some but not all of the deprecated attributes. I'd prefer if they could set none or all.
I see, and agree it should be consistent. I think omitting the setters was a (probably unintentional?) breaking change, so I think being able to set all (with a deprecation warning) makes sense. I've added setters where they were missing.
* ``PVSystem.surface_azimuth`` | ||
* ``PVSystem.racking_model`` | ||
* ``PVSystem.modules_per_string`` | ||
* ``PVSystem.strings_per_inverter`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the alphabetization of the list preceding this one and would prefer to see that here too.
Also a handful of problems in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cwhanse ok to merge?
I'm not sure what I did wrong when I checked coverage earlier in the thread, but I now agree with codecov that the ValueError was not exercised. I checked coverage in |
Merge when green! |
Closes #xxxxdocs/sphinx/source/api.rst
for API changes.docs/sphinx/source/whatsnew
for all changes. Includes link to the GitHub Issue with:issue:`num`
or this Pull Request with:pull:`num`
. Includes contributor name and/or GitHub username (link with:ghuser:`user`
).Trying out the idea suggested in #1176 (comment): for the values that used to be
PVSystem
attributes but have been moved down toArray
, emit a deprecation warning for systems with only oneArray
and an error if more than one.Note to reviewers: I was guided more by test failures than by a solid understanding of the emerging PVSystem+Array architecture. Wouldn't be surprised if I've missed something here.