Skip to content

Commit 5fff42c

Browse files
Add deprecation decorators (#1683)
1 parent 93cc635 commit 5fff42c

2 files changed

Lines changed: 106 additions & 0 deletions

File tree

parcels/tools/_helpers.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""Internal helpers for Parcels."""
2+
3+
import functools
4+
import warnings
5+
from typing import Callable
6+
7+
PACKAGE = "Parcels"
8+
9+
10+
def deprecated(msg: str = "") -> Callable:
11+
"""Decorator marking a function as being deprecated
12+
13+
Parameters
14+
----------
15+
msg : str, optional
16+
Custom message to append to the deprecation warning.
17+
18+
Examples
19+
--------
20+
```
21+
@deprecated("Please use `another_function` instead")
22+
def some_old_function(x, y):
23+
return x + y
24+
25+
@deprecated()
26+
def some_other_old_function(x, y):
27+
return x + y
28+
```
29+
"""
30+
if msg:
31+
msg = " " + msg
32+
33+
def decorator(func):
34+
@functools.wraps(func)
35+
def wrapper(*args, **kwargs):
36+
msg_formatted = (
37+
f"`{func.__qualname__}` is deprecated and will be removed in a future release of {PACKAGE}.{msg}"
38+
)
39+
40+
warnings.warn(msg_formatted, category=DeprecationWarning, stacklevel=2)
41+
return func(*args, **kwargs)
42+
43+
return wrapper
44+
45+
return decorator
46+
47+
48+
def deprecated_made_private(func: Callable) -> Callable:
49+
return deprecated(
50+
"It has moved to the internal API as it is not expected to be directly used by "
51+
"the end-user. If you feel that you use this code directly in your scripts, please "
52+
"comment on our tracking issue at <>." # TODO: Add tracking issue
53+
)(func)

tests/tools/test_helpers.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import pytest
2+
3+
from parcels.tools._helpers import deprecated, deprecated_made_private
4+
5+
6+
def test_deprecated():
7+
class SomeClass:
8+
@deprecated()
9+
def some_method(self, x, y):
10+
return x + y
11+
12+
@staticmethod
13+
@deprecated()
14+
def some_static_method(x, y):
15+
return x + y
16+
17+
@property
18+
@deprecated()
19+
def some_property(self):
20+
return 2
21+
22+
@deprecated()
23+
def some_function(x, y):
24+
return x + y
25+
26+
with pytest.warns(DeprecationWarning) as record:
27+
SomeClass().some_method(1, 2)
28+
assert "SomeClass.some_method" in record[0].message.args[0]
29+
30+
with pytest.warns(DeprecationWarning) as record:
31+
SomeClass.some_static_method(1, 2)
32+
assert "SomeClass.some_static_method" in record[0].message.args[0]
33+
34+
with pytest.warns(DeprecationWarning) as record:
35+
_ = SomeClass().some_property
36+
assert "SomeClass.some_property" in record[0].message.args[0]
37+
38+
with pytest.warns(DeprecationWarning) as record:
39+
some_function(1, 2)
40+
assert "some_function" in record[0].message.args[0]
41+
42+
with pytest.warns(DeprecationWarning) as record:
43+
some_function(1, 2)
44+
assert "some_function" in record[0].message.args[0]
45+
46+
47+
def test_deprecated_made_private():
48+
@deprecated_made_private
49+
def some_function(x, y):
50+
return x + y
51+
52+
with pytest.warns(DeprecationWarning):
53+
some_function(1, 2)

0 commit comments

Comments
 (0)