Skip to content

Commit b4a40dc

Browse files
seismanweiji14
andauthored
Add a decorator to raise a FutureWarning when positional arguments are passed for functions that changed parameter orders (#1541)
Co-authored-by: Wei Ji <[email protected]>
1 parent 846add0 commit b4a40dc

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

pygmt/helpers/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Functions, classes, decorators, and context managers to help wrap GMT modules.
33
"""
44
from pygmt.helpers.decorators import (
5+
check_data_input_order,
56
deprecate_parameter,
67
fmt_docstring,
78
kwargs_to_strings,

pygmt/helpers/decorators.py

+60
Original file line numberDiff line numberDiff line change
@@ -811,3 +811,63 @@ def new_module(*args, **kwargs):
811811
return new_module
812812

813813
return deprecator
814+
815+
816+
def check_data_input_order(deprecate_version, remove_version):
817+
"""
818+
Decorator to raise a FutureWarning if the order of data input parameters
819+
changes and positional arguments are passed.
820+
821+
The decorator is temporary and should be removed in v0.7.0.
822+
823+
Parameters
824+
----------
825+
deprecate_version : str
826+
The PyGMT version when the order of data input parameters is changed.
827+
remove_version : str
828+
The PyGMT version when the deprecation warning should be removed.
829+
830+
Examples
831+
--------
832+
>>> @check_data_input_order("v0.0.0", "v9.9.9")
833+
... def module(data=None, x=None, y=None, z=None, **kwargs):
834+
... "A module that prints the arguments it received"
835+
... print(f"data={data}, x={x}, y={y}, z={z}")
836+
>>> module(data="table.txt")
837+
data=table.txt, x=None, y=None, z=None
838+
>>> module(x=0, y=1, z=2)
839+
data=None, x=0, y=1, z=2
840+
>>> with warnings.catch_warnings(record=True) as w:
841+
... module(0, 1, 2)
842+
... assert len(w) == 1
843+
... assert issubclass(w[0].category, FutureWarning)
844+
...
845+
data=0, x=1, y=2, z=None
846+
"""
847+
848+
def data_input_order_checker(module_func):
849+
"""
850+
The decorator that creates the new function to check if positional
851+
arguments are passed.
852+
"""
853+
854+
@functools.wraps(module_func)
855+
def new_module(*args, **kwargs):
856+
"""
857+
New module instance that raises a warning if positional arguments
858+
are passed.
859+
"""
860+
if len(args) > 0: # positional arguments are used
861+
msg = (
862+
"The function parameters has been re-ordered as 'data, x, y, [z]' "
863+
f"since {deprecate_version} but you're passing positional arguments. "
864+
"You can silence the warning by passing keyword arguments "
865+
"like 'x=x, y=y, z=z'. Otherwise, the warning will be removed "
866+
f"in {remove_version}."
867+
)
868+
warnings.warn(msg, category=FutureWarning, stacklevel=2)
869+
return module_func(*args, **kwargs)
870+
871+
return new_module
872+
873+
return data_input_order_checker

0 commit comments

Comments
 (0)