Skip to content

Commit 01f2b1e

Browse files
authored
Merge branch 'main' into mikofski-112-what’s-new
2 parents a366777 + 2c61a64 commit 01f2b1e

File tree

9 files changed

+299
-52
lines changed

9 files changed

+299
-52
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Update Top Ranked Issues
2+
3+
on:
4+
# For testing purposes (can be removed later)
5+
pull_request:
6+
schedule:
7+
# # Runs every day at 3:00 AM UTC
8+
# - cron: '0 3 * * *'
9+
- cron: '*/10 * * * *'
10+
11+
jobs:
12+
run-script:
13+
runs-on: ubuntu-latest
14+
15+
env:
16+
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17+
18+
steps:
19+
- name: Check out the repository
20+
uses: actions/checkout@v4 # This ensures the repository code is available
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: "3.12"
26+
27+
- name: Install dependencies
28+
run: |
29+
python -m pip install --upgrade pip
30+
pip install PyGithub
31+
32+
- name: Run update_top_ranking_issues.py
33+
run: |
34+
python ./scripts/update_top_ranking_issues.py

docs/sphinx/source/contributing/testing.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. _testing:
22

3-
Testing
4-
=======
3+
Testing and benchmarking
4+
========================
55

66
.. _overview:
77

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,16 @@ Requirements
2727
~~~~~~~~~~~~
2828

2929

30+
Maintenance
31+
~~~~~~~~~~~
32+
* Added a decorator to deprecate renamed keyword arguments in functions,
33+
:py:func:`pvlib._deprecation.renamed_kwarg_warning`. (:pull:`2237`)
34+
35+
3036
Contributors
3137
~~~~~~~~~~~~
3238
* Cliff Hansen (:ghuser:`cwhanse`)
3339
* Rajiv Daxini (:ghuser:`RDaxini`)
3440
* Mark Mikofski (:ghuser:`mikofski`)
3541
* matsuobasho (:ghuser:`matsuobasho`)
36-
42+
* Echedey Luis (:ghuser:`echedey-ls`)

pvlib/_deprecation.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,76 @@ def wrapper(*args, **kwargs):
316316
return finalize(wrapper, new_doc)
317317

318318
return deprecate
319+
320+
321+
def renamed_kwarg_warning(since, old_param_name, new_param_name, removal=""):
322+
"""
323+
Decorator to mark a possible keyword argument as deprecated and replaced
324+
with other name.
325+
326+
Raises a warning when the deprecated argument is used, and replaces the
327+
call with the new argument name. Does not modify the function signature.
328+
329+
.. warning::
330+
Ensure ``removal`` date with a ``fail_on_pvlib_version`` decorator in
331+
the test suite.
332+
333+
.. note::
334+
Not compatible with positional-only arguments.
335+
336+
.. note::
337+
Documentation for the function may updated to reflect the new parameter
338+
name; it is suggested to add a |.. versionchanged::| directive.
339+
340+
Parameters
341+
----------
342+
since : str
343+
The release at which this API became deprecated.
344+
old_param_name : str
345+
The name of the deprecated parameter.
346+
new_param_name : str
347+
The name of the new parameter.
348+
removal : str, optional
349+
The expected removal version, in order to compose the Warning message.
350+
351+
Examples
352+
--------
353+
>>> @renamed_kwarg_warning("1.4.0", "old_name", "new_name", "1.6.0")
354+
>>> def some_function(new_name=None):
355+
>>> pass
356+
>>> some_function(old_name=1)
357+
Parameter 'old_name' has been renamed since 1.4.0. and
358+
will be removed in 1.6.0. Please use 'new_name' instead.
359+
360+
>>> @renamed_kwarg_warning("1.4.0", "old_name", "new_name")
361+
>>> def some_function(new_name=None):
362+
>>> pass
363+
>>> some_function(old_name=1)
364+
Parameter 'old_name' has been renamed since 1.4.0. and
365+
will be removed soon. Please use 'new_name' instead.
366+
"""
367+
368+
def deprecate(func, old=old_param_name, new=new_param_name, since=since):
369+
def wrapper(*args, **kwargs):
370+
if old in kwargs:
371+
if new in kwargs:
372+
raise ValueError(
373+
f"{func.__name__} received both '{old}' and '{new}', "
374+
"which are mutually exclusive since they refer to the "
375+
f"same parameter. Please remove deprecated '{old}'."
376+
)
377+
warnings.warn(
378+
f"Parameter '{old}' has been renamed since {since}. "
379+
f"and will be removed "
380+
+ (f"in {removal}" if removal else "soon")
381+
+ f". Please use '{new}' instead.",
382+
_projectWarning,
383+
stacklevel=2,
384+
)
385+
kwargs[new] = kwargs.pop(old)
386+
return func(*args, **kwargs)
387+
388+
wrapper = functools.wraps(func)(wrapper)
389+
return wrapper
390+
391+
return deprecate

pvlib/data/variables_style_rules.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ghi;global horizontal irradiance
1111
ghi_extra;horizontal irradiance at top of atmosphere (extraterrestrial)
1212
gri;ground-reflected irradiance
1313
ape;average photon energy
14-
aoi;angle of incidence between :math:`90\deg` and :math:`90\deg`
14+
aoi;angle of incidence. Angle between the surface normal vector and the vector pointing towards the sun's center
1515
aoi_projection;cos(aoi)
1616
airmass;airmass
1717
airmass_relative;relative airmass

pvlib/iam.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,8 @@ def martin_ruiz(aoi, a_r=0.16):
269269
270270
which is presented as :math:`AL(\alpha) = 1 - IAM` in equation 4 of [1]_,
271271
with :math:`\alpha` representing the angle of incidence AOI. Thus IAM = 1
272-
at AOI = 0, and IAM = 0 at AOI = 90. This equation is only valid for
273-
-90 <= aoi <= 90, therefore `iam` is constrained to 0.0 outside this
272+
at AOI = 0°, and IAM = 0 at AOI = 90°. This equation is only valid for
273+
<= aoi <= 90°, therefore `iam` is constrained to 0.0 outside this
274274
interval.
275275
276276
References
@@ -891,8 +891,8 @@ def schlick_diffuse(surface_tilt):
891891
implements only the integrated Schlick approximation.
892892
893893
Note also that the output of this function (which is an exact integration)
894-
can be compared with the output of :py:func:`marion_diffuse` which numerically
895-
integrates the Schlick approximation:
894+
can be compared with the output of :py:func:`marion_diffuse` which
895+
numerically integrates the Schlick approximation:
896896
897897
.. code::
898898

pvlib/tests/test__deprecation.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""
2+
Test the _deprecation module.
3+
"""
4+
5+
import pytest
6+
7+
from pvlib import _deprecation
8+
from .conftest import fail_on_pvlib_version
9+
10+
import warnings
11+
12+
13+
@pytest.mark.xfail(strict=True,
14+
reason='fail_on_pvlib_version should cause test to fail')
15+
@fail_on_pvlib_version('0.0')
16+
def test_fail_on_pvlib_version():
17+
pass # pragma: no cover
18+
19+
20+
@fail_on_pvlib_version('100000.0')
21+
def test_fail_on_pvlib_version_pass():
22+
pass
23+
24+
25+
@pytest.mark.xfail(strict=True, reason='ensure that the test is called')
26+
@fail_on_pvlib_version('100000.0')
27+
def test_fail_on_pvlib_version_fail_in_test():
28+
raise Exception
29+
30+
31+
# set up to test using fixtures with function decorated with
32+
# conftest.fail_on_pvlib_version
33+
@pytest.fixture
34+
def some_data():
35+
return "some data"
36+
37+
38+
def alt_func(*args):
39+
return args
40+
41+
42+
@pytest.fixture
43+
def deprec_func():
44+
return _deprecation.deprecated(
45+
"350.8", alternative="alt_func", name="deprec_func", removal="350.9"
46+
)(alt_func)
47+
48+
49+
@fail_on_pvlib_version('350.9')
50+
def test_use_fixture_with_decorator(some_data, deprec_func):
51+
# test that the correct data is returned by the some_data fixture
52+
assert some_data == "some data"
53+
with pytest.warns(_deprecation.pvlibDeprecationWarning):
54+
# test for custom deprecation warning provided by pvlib
55+
deprec_func(some_data)
56+
57+
58+
@pytest.fixture
59+
def renamed_kwarg_func():
60+
"""Returns a function decorated by renamed_kwarg_warning.
61+
This function is called 'func' and has a docstring equal to 'docstring'.
62+
"""
63+
64+
@_deprecation.renamed_kwarg_warning(
65+
"0.1.0", "old_kwarg", "new_kwarg", "0.2.0"
66+
)
67+
def func(new_kwarg):
68+
"""docstring"""
69+
return new_kwarg
70+
71+
return func
72+
73+
74+
def test_renamed_kwarg_warning(renamed_kwarg_func):
75+
# assert decorated function name and docstring are unchanged
76+
assert renamed_kwarg_func.__name__ == "func"
77+
assert renamed_kwarg_func.__doc__ == "docstring"
78+
79+
# assert no warning is raised when using the new kwarg
80+
with warnings.catch_warnings():
81+
warnings.simplefilter("error")
82+
assert renamed_kwarg_func(new_kwarg=1) == 1 # as keyword argument
83+
assert renamed_kwarg_func(1) == 1 # as positional argument
84+
85+
# assert a warning is raised when using the old kwarg
86+
with pytest.warns(Warning, match="Parameter 'old_kwarg' has been renamed"):
87+
assert renamed_kwarg_func(old_kwarg=1) == 1
88+
89+
# assert an error is raised when using both the old and new kwarg
90+
with pytest.raises(ValueError, match="they refer to the same parameter."):
91+
renamed_kwarg_func(old_kwarg=1, new_kwarg=2)
92+
93+
# assert when not providing any of them
94+
with pytest.raises(
95+
TypeError, match="missing 1 required positional argument"
96+
):
97+
renamed_kwarg_func()

pvlib/tests/test_conftest.py

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,6 @@
11
import pytest
2-
import pandas
32

43
from pvlib.tests import conftest
5-
from pvlib.tests.conftest import fail_on_pvlib_version
6-
7-
from pvlib._deprecation import pvlibDeprecationWarning, deprecated
8-
9-
@pytest.mark.xfail(strict=True,
10-
reason='fail_on_pvlib_version should cause test to fail')
11-
@fail_on_pvlib_version('0.0')
12-
def test_fail_on_pvlib_version():
13-
pass
14-
15-
16-
@fail_on_pvlib_version('100000.0')
17-
def test_fail_on_pvlib_version_pass():
18-
pass
19-
20-
21-
@pytest.mark.xfail(strict=True, reason='ensure that the test is called')
22-
@fail_on_pvlib_version('100000.0')
23-
def test_fail_on_pvlib_version_fail_in_test():
24-
raise Exception
25-
26-
27-
# set up to test using fixtures with function decorated with
28-
# conftest.fail_on_pvlib_version
29-
@pytest.fixture()
30-
def some_data():
31-
return "some data"
32-
33-
34-
def alt_func(*args):
35-
return args
36-
37-
38-
deprec_func = deprecated('350.8', alternative='alt_func',
39-
name='deprec_func', removal='350.9')(alt_func)
40-
41-
42-
@fail_on_pvlib_version('350.9')
43-
def test_use_fixture_with_decorator(some_data):
44-
# test that the correct data is returned by the some_data fixture
45-
assert some_data == "some data"
46-
with pytest.warns(pvlibDeprecationWarning): # test for deprecation warning
47-
deprec_func(some_data)
484

495

506
@pytest.mark.parametrize('function_name', ['assert_index_equal',

0 commit comments

Comments
 (0)