pvlib._deprecation.renamed_key_items_warning#
- pvlib._deprecation.renamed_key_items_warning(since, old_to_new_keys_map, removal='')[source]#
Decorator to mark a possible key item (e.g.
df["key"]
) of an object as deprecated and replaced with other attribute.Raises a warning when the deprecated attribute is used, and uses the new attribute instead, by wrapping the
__getattr__
method of the object. See [1].While this implementation is decorator-like, Python syntax won’t allow
@decorator
for applying it. Two sets of parenthesis are required: the first one configures the wrapper and the second one applies it. This leaves room for reusability too.Code is inspired by [2], thou it has been generalized to arbitrary data types.
Warning
Ensure
removal
date with afail_on_pvlib_version
decorator in the test suite.Note
This works for any object that implements a
__getitem__
method, such as dictionaries, DataFrames, and other collections.- Parameters:
- Returns:
object – A new object that behaves like the original, but raises a warning when accessing deprecated keys and returns the value of the new key.
Examples
>>> dict_obj = {"new_key": "renamed_value", "another_key": "another_value"} >>> dict_obj = renamed_key_items_warning( ... "1.4.0", {"old_key": "new_key"} ... )(dict_obj) >>> dict_obj["old_key"] pvlibDeprecationWarning: Please use 'new_key' instead of 'old_key'. Deprecated since 1.4.0 and will be removed soon. 'renamed_value' >>> isinstance(d, dict) True >>> type(dict_obj) <class 'pvlib._deprecation.DeprecatedKeyItems'>
>>> dict_obj = {"new_key": "renamed_value", "new_key2": "another_value"} >>> dict_obj = renamed_key_items_warning( ... "1.4.0", {"old_key": "new_key", "old_key2": "new_key2"}, "1.6.0" ... )(dict_obj) >>> dict_obj["old_key2"] pvlibDeprecationWarning: Please use 'new_key2' instead of 'old_key2'. Deprecated since 1.4.0 and will be removed in 1.6.0. 'another_value'
You can even chain the decorator to rename multiple keys at once:
>>> dict_obj = {"new_key1": "value1", "new_key2": "value2"} >>> dict_obj = renamed_key_items_warning( ... "0.1.0", {"old_key1": "new_key1"}, "0.2.0" ... )(dict_obj) >>> dict_obj = renamed_key_items_warning( ... "0.3.0", {"old_key2": "new_key2"}, "0.4.0" ... )(dict_obj) >>> dict_obj["old_key1"] pvlibDeprecationWarning: Please use 'new_key1' instead of 'old_key1'. Deprecated since 0.1.0 and will be removed in 0.2.0. 'value1' >>> dict_obj["old_key2"] pvlibDeprecationWarning: Please use 'new_key2' instead of 'old_key2'. Deprecated since 0.3.0 and will be removed in 0.4.0. 'value2'
Reusing the object wrapper factory:
>>> dict_obj1 = {"new_key": "renamed_value", "another_key": "another_value"} >>> dict_obj2 = {"new_key": "just_another", "yet_another_key": "yet_another_value"} >>> wrapper_renames_old_key_to_new_key = renamed_key_items_warning("1.4.0", {"old_key": "new_key"}, "2.0.0") >>> new_dict_obj1 = wrapper_renames_old_key_to_new_key(dict_obj1) >>> new_dict_obj2 = wrapper_renames_old_key_to_new_key(dict_obj2) >>> new_dict_obj1["old_key"] <stdin>:1: pvlibDeprecationWarning: Please use 'new_key' instead of 'old_key'. Deprecated since 1.4.0 and will be removed in 2.0.0. 'renamed_value' >>> new_dict_obj2["old_key"] <stdin>:1: pvlibDeprecationWarning: Please use 'new_key' instead of 'old_key'. Deprecated since 1.4.0 and will be removed in 2.0.0. 'just_another'
Notes
This decorator does not modify the way you access methods on the original type. For example, dictionaries can only be accessed with bracketed indexes,
dictionary["key"]
. After decoration,"old_key"
can only be used as follows:dictionary["old_key"]
. Bothdictionary.key
anddictionary.old_key
won’t become available after wrapping.>>> from pvlib._deprecation import renamed_key_items_warning >>> dict_base = {"a": [1]} >>> dict_depre = renamed_key_items_warning("0.0.1", {"b": "a"})(dict_base) >>> dict_depre["a"] [1] >>> dict_depre["b"] <stdin>:1: pvlibDeprecationWarning: Please use 'a' instead of 'b'. Deprecated since 0.0.1 and will be removed soon. [1] >>> dict_depre.a Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'DeprecatedKeyItems' object has no attribute 'a' >>> dict_depre.b Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'DeprecatedKeyItems' object has no attribute 'b'
On the other hand,
pandas.DataFrame
and other types may also expose indexes as attributes on the object instance. In aDataFrame
you can either usedf.a
ordf["a"]
. An old keyb
that maps toa
through the decorator, can either be accessed withdf.b
ordf["b"]
.>>> from pvlib._deprecation import renamed_key_items_warning >>> import pandas as pd >>> df_base = pd.DataFrame({"a": [1]}) >>> df_base.a 0 1 Name: a, dtype: int64 >>> df_depre = renamed_key_items_warning("0.0.1", {"b": "a"})(df_base) >>> df_depre.a 0 1 Name: a, dtype: int64 >>> df_depre.b Traceback (most recent call last): File "<stdin>", line 1, in <module> File "...", line 6299, in __getattr__ return object.__getattribute__(self, name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'DeprecatedKeyItems' object has no attribute 'b'
References