Skip to content

Commit 6aca13d

Browse files
committed
Avoid using inspect
1 parent ee072df commit 6aca13d

File tree

8 files changed

+97
-79
lines changed

8 files changed

+97
-79
lines changed

pygmt/alias.py

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"""
44

55
import dataclasses
6-
import inspect
76
from collections import defaultdict
87
from collections.abc import Mapping, Sequence
98
from typing import Any, Literal
@@ -210,14 +209,14 @@ class AliasSystem:
210209
... ):
211210
... alias = AliasSystem(
212211
... A=[
213-
... Alias("par1"),
214-
... Alias("par2", prefix="+j"),
215-
... Alias("par3", prefix="+o", separator="/"),
212+
... Alias("par1", value=par1),
213+
... Alias("par2", prefix="+j", value=par2),
214+
... Alias("par3", prefix="+o", separator="/", value=par3),
216215
... ],
217-
... B=Alias("frame"),
218-
... c=Alias("panel", separator=","),
216+
... B=Alias("frame", value=frame),
217+
... c=Alias("panel", separator=",", value=panel),
219218
... )
220-
... return build_arg_list(alias.kwdict)
219+
... return build_arg_list(alias.kwdict | kwargs)
221220
>>> func(
222221
... "infile",
223222
... par1="mytext",
@@ -235,33 +234,26 @@ def __init__(self, **kwargs):
235234
"""
236235
self.options = {}
237236
for option, aliases in kwargs.items():
238-
if isinstance(aliases, list):
239-
self.options[option] = aliases
240-
elif isinstance(aliases, str): # Support shorthand like 'J="projection"'
241-
self.options[option] = [Alias(aliases)]
242-
else:
243-
self.options[option] = [aliases]
237+
match aliases:
238+
case list():
239+
self.options[option] = aliases
240+
case str(): # Support shorthand like 'J="projection"'
241+
self.options[option] = [Alias(aliases)]
242+
case _:
243+
self.options[option] = [aliases]
244244

245245
@property
246246
def kwdict(self):
247247
"""
248248
A keyword dictionary that stores the current parameter values.
249249
"""
250-
# Get the local variables from the calling function.
251-
p_locals = inspect.currentframe().f_back.f_locals
252-
# Get parameters/arguments from **kwargs of the calling function.
253-
p_kwargs = p_locals.get("kwargs", {})
254-
255-
params = p_locals | p_kwargs
256250
# Default value is an empty string to simplify code logic.
257251
kwdict = defaultdict(str)
258252
for option, aliases in self.options.items():
259253
for alias in aliases:
260-
alias.value = params.get(alias.name)
261254
# value can be a string, a sequence of strings or None.
262255
if alias.value is None:
263256
continue
264-
265257
# Special handing of repeatable parameter like -B/frame.
266258
if is_nonstr_iter(alias.value):
267259
kwdict[option] = alias.value
@@ -270,24 +262,24 @@ def kwdict(self):
270262

271263
kwdict[option] += alias.value
272264

273-
# Support short-form parameter names specified in kwargs.
274-
# Short-form parameters can be either one-letter (e.g., '-B'), or two-letters
275-
# (e.g., '-Td').
276-
for option, value in p_kwargs.items():
277-
# Here, we assume that long-form parameters specified in kwargs are longer
278-
# than two characters. Sometimes, we may use parameter like 'az', but it's
279-
# not specified in kwargs. So, the assumption is still valid.
280-
if len(option) > 2:
281-
continue
282-
283-
# Two cases for short-form parameters:
284-
#
285-
# If it has an alias and the long-form parameter is also specified, (e.g.,
286-
# 'projection="X10c", J="X10c"'), then we silently ignore the short-form
287-
# parameter.
288-
#
289-
# If it has an alias but the long-form parameter is not specified, or it
290-
# doesn't has an alias, then we use the value of the short-form parameter.
291-
if option not in self.options or option not in kwdict:
292-
kwdict[option] = value
265+
# # Support short-form parameter names specified in kwargs.
266+
# # Short-form parameters can be either one-letter (e.g., '-B'), or two-letters
267+
# # (e.g., '-Td').
268+
# for option, value in self.options.items():
269+
# # Here, we assume that long-form parameters specified in kwargs are longer
270+
# # than two characters. Sometimes, we may use parameter like 'az', but it's
271+
# # not specified in kwargs. So, the assumption is still valid.
272+
# if len(option) > 2:
273+
# continue
274+
275+
# # Two cases for short-form parameters:
276+
# #
277+
# # If it has an alias and the long-form parameter is also specified, (e.g.,
278+
# # 'projection="X10c", J="X10c"'), then we silently ignore the short-form
279+
# # parameter.
280+
# #
281+
# # If it has an alias but the long-form parameter is not specified, or it
282+
# # doesn't has an alias, then we use the value of the short-form parameter.
283+
# if option not in self.options or option not in kwdict:
284+
# kwdict[option] = value
293285
return kwdict

pygmt/src/basemap.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
basemap - Plot base maps and frames.
33
"""
44

5-
from pygmt.alias import AliasSystem
5+
from pygmt.alias import Alias, AliasSystem
66
from pygmt.clib import Session
77
from pygmt.helpers import build_arg_list, fmt_docstring, kwargs_to_strings, use_alias
88

@@ -24,7 +24,7 @@
2424
t="transparency",
2525
)
2626
@kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence")
27-
def basemap(self, **kwargs):
27+
def basemap(self, frame=None, **kwargs):
2828
r"""
2929
Plot base maps and frames.
3030
@@ -83,8 +83,8 @@ def basemap(self, **kwargs):
8383
{transparency}
8484
"""
8585
alias = AliasSystem(
86-
B="frame",
86+
B=Alias("frame", value=frame),
8787
)
8888
kwargs = self._preprocess(**kwargs)
8989
with Session() as lib:
90-
lib.call_module(module="basemap", args=build_arg_list(alias.kwdict))
90+
lib.call_module(module="basemap", args=build_arg_list(alias.kwdict | kwargs))

pygmt/src/binstats.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def binstats(
2929
outgrid: str | None = None,
3030
statistic=None,
3131
quantile_value=50,
32-
**kwargs, # noqa: ARG001
32+
**kwargs,
3333
) -> xr.DataArray | None:
3434
r"""
3535
Bin spatial data and determine statistics per bin.
@@ -130,13 +130,14 @@ def binstats(
130130
"maxneg": "U",
131131
"sum": "z",
132132
},
133+
value=statistic,
133134
),
134-
G="outgrid",
135+
G=Alias("outgrid", value=outgrid),
135136
)
136137
if statistic == "quantile":
137138
statistic += str(quantile_value)
138139

139-
kwdict = alias.kwdict
140+
kwdict = alias.kwdict | kwargs
140141
with Session() as lib:
141142
with (
142143
lib.virtualfile_in(check_kind="vector", data=data) as vintbl,

pygmt/src/coast.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,4 @@ def coast(
221221
)
222222
raise GMTInvalidInput(msg)
223223
with Session() as lib:
224-
lib.call_module(module="coast", args=build_arg_list(alias.kwdict))
224+
lib.call_module(module="coast", args=build_arg_list(alias.kwdict | kwargs))

pygmt/src/dimfilter.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,17 @@
1212

1313

1414
@fmt_docstring
15-
def dimfilter(grid, outgrid: str | None = None, **kwargs) -> xr.DataArray | None:
15+
def dimfilter(
16+
grid,
17+
outgrid: str | None = None,
18+
distance: int | str | None = None,
19+
filter: str | None = None,
20+
sectors: str | None = None,
21+
spacing: str | list | None = None,
22+
region: str | list | None = None,
23+
verbose: bool | None = None,
24+
**kwargs,
25+
) -> xr.DataArray | None:
1626
r"""
1727
Directional filtering of grids in the space domain.
1828
@@ -125,25 +135,25 @@ def dimfilter(grid, outgrid: str | None = None, **kwargs) -> xr.DataArray | None
125135
... )
126136
"""
127137
alias = AliasSystem(
128-
D=Alias("distance"),
129-
G=Alias("outgrid"),
130-
F=Alias("filter"),
131-
I=Alias("spacing", separator="/"),
132-
N=Alias("sectors"),
133-
R=Alias("region", separator="/"),
134-
V=Alias("verbose"),
138+
D=Alias("distance", value=distance),
139+
G=Alias("outgrid", value=outgrid),
140+
F=Alias("filter", value=filter),
141+
I=Alias("spacing", separator="/", value=spacing),
142+
N=Alias("sectors", value=sectors),
143+
R=Alias("region", separator="/", value=region),
144+
V=Alias("verbose", value=verbose),
135145
)
136146

137147
if (
138-
not all(arg in kwargs for arg in ["distance", "filter", "sectors"])
148+
not all(v is not None for v in [distance, filter, sectors])
139149
and "Q" not in kwargs
140150
):
141151
msg = (
142152
"At least one of the following parameters must be specified: "
143153
"distance, filters, or sectors."
144154
)
145155
raise GMTInvalidInput(msg)
146-
kwdict = alias.kwdict
156+
kwdict = alias.kwdict | kwargs
147157
with Session() as lib:
148158
with (
149159
lib.virtualfile_in(check_kind="raster", data=grid) as vingrd,

pygmt/src/image.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,21 @@
88

99

1010
@fmt_docstring
11-
def image(self, imagefile, **kwargs):
11+
def image(
12+
self,
13+
imagefile,
14+
region=None,
15+
projection=None,
16+
position=None,
17+
box=None,
18+
bitcolor=None,
19+
monochrome=None,
20+
verbose=None,
21+
panel=None,
22+
perspective=None,
23+
transparency=None,
24+
**kwargs,
25+
):
1226
r"""
1327
Plot raster or EPS images.
1428
@@ -54,20 +68,20 @@ def image(self, imagefile, **kwargs):
5468
{transparency}
5569
"""
5670
alias = AliasSystem(
57-
R=Alias("region", separator="/"),
58-
J="projection",
59-
D="position",
60-
F="box",
61-
G="bitcolor",
62-
M="monochrome",
63-
V="verbose",
71+
R=Alias("region", separator="/", value=region),
72+
J=Alias("projection", value=projection),
73+
D=Alias("position", value=position),
74+
F=Alias("box", value=box),
75+
G=Alias("bitcolor", value=bitcolor),
76+
M=Alias("monochrome", value=monochrome),
77+
V=Alias("verbose", value=verbose),
6478
c=Alias("panel", separator=","),
6579
p=Alias("perspective", separator="/"),
66-
t="transparency",
80+
t=Alias("transparency", value=transparency),
6781
)
6882

6983
kwargs = self._preprocess(**kwargs)
7084
with Session() as lib:
7185
lib.call_module(
72-
module="image", args=build_arg_list(alias.kwdict, infile=imagefile)
86+
module="image", args=build_arg_list(alias.kwdict | kwargs, infile=imagefile)
7387
)

pygmt/src/logo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,4 @@ def logo(self, **kwargs):
5959
)
6060
kwargs = self._preprocess(**kwargs)
6161
with Session() as lib:
62-
lib.call_module(module="logo", args=build_arg_list(alias.kwdict))
62+
lib.call_module(module="logo", args=build_arg_list(alias.kwdict | kwargs))

pygmt/src/timestamp.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,6 @@ def timestamp(
7777
>>> fig.timestamp(label="Powered by PyGMT")
7878
>>> fig.show()
7979
"""
80-
alias = AliasSystem(
81-
U=[
82-
Alias("label"),
83-
Alias("justify", prefix="+j"),
84-
Alias("offset", prefix="+o", separator="/"),
85-
Alias("text", prefix="+t"),
86-
]
87-
)
8880

8981
self._preprocess()
9082

@@ -109,7 +101,16 @@ def timestamp(
109101
warnings.warn(message=msg, category=RuntimeWarning, stacklevel=2)
110102
text = text[:64]
111103

112-
kwdict: dict = {"T": True, "U": True} | alias.kwdict
104+
alias = AliasSystem(
105+
U=[
106+
Alias("label", value=label),
107+
Alias("justify", prefix="+j", value=justify),
108+
Alias("offset", prefix="+o", separator="/", value=offset),
109+
Alias("text", prefix="+t", value=text),
110+
]
111+
)
112+
113+
kwdict = {"T": True} | alias.kwdict
113114
with Session() as lib:
114115
lib.call_module(
115116
module="plot",

0 commit comments

Comments
 (0)