Skip to content

Commit 99845c2

Browse files
committed
Implement AliasSystem as a subclass of UserDict
1 parent a375e69 commit 99845c2

File tree

3 files changed

+27
-28
lines changed

3 files changed

+27
-28
lines changed

pygmt/alias.py

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import dataclasses
66
import warnings
7+
from collections import UserDict
78
from collections.abc import Mapping, Sequence
89
from typing import Any, Literal
910

@@ -198,17 +199,17 @@ def _value(self) -> str | list[str] | None:
198199
)
199200

200201

201-
class AliasSystem:
202+
class AliasSystem(UserDict):
202203
"""
203204
Alias system for mapping PyGMT's long-form parameters to GMT's short-form options.
204205
205206
This class is initialized with keyword arguments, where each key is a GMT option
206207
flag, and the corresponding value is an ``Alias`` object or a list of ``Alias``
207208
objects.
208209
209-
The class provides the ``kwdict`` attribute, which is a dictionary mapping each GMT
210-
option flag to its current value. The value can be a string or a list of strings.
211-
This keyword dictionary can then be passed to the ``build_arg_list`` function.
210+
This class inherits from ``UserDict``, which allows it to behave like a dictionary
211+
and can be passed to the ``build_arg_list`` function. It also provides the ``merge``
212+
method to update the alias dictionary with additional keyword arguments.
212213
213214
Examples
214215
--------
@@ -218,16 +219,16 @@ class AliasSystem:
218219
>>> def func(
219220
... par0, par1=None, par2=None, frame=False, repeat=None, panel=None, **kwargs
220221
... ):
221-
... alias = AliasSystem(
222+
... aliasdict = AliasSystem(
222223
... A=[
223224
... Alias(par1, name="par1"),
224225
... Alias(par2, name="par2", prefix="+o", separator="/"),
225226
... ],
226227
... B=Alias(frame, name="frame"),
227228
... D=Alias(repeat, name="repeat"),
228229
... c=Alias(panel, name="panel", separator=","),
229-
... ).update(kwargs)
230-
... return build_arg_list(alias.kwdict)
230+
... ).merge(kwargs)
231+
... return build_arg_list(aliasdict)
231232
>>> func(
232233
... "infile",
233234
... par1="mytext",
@@ -242,16 +243,12 @@ class AliasSystem:
242243

243244
def __init__(self, **kwargs):
244245
"""
245-
Initialize the alias system and create the keyword dictionary that stores the
246-
current parameter values.
246+
Initialize the alias system as a dictionary with current parameter values.
247247
"""
248-
# Storing the aliases as a dictionary for easy access.
248+
# Store the aliases in a dictionary, to be used in the merge() method.
249249
self.aliasdict = kwargs
250250

251-
# Storing option-value as a keyword dictionary.
252-
self.kwdict = {}
253-
254-
# The value of each key in aliasdict is an Alias object or a sequence of Alias
251+
# The value of each key in kwargs is an Alias object or a sequence of Alias
255252
# objects. If it is a single Alias object, we will use its _value property. If
256253
# it is a sequence of Alias objects, we will concatenate their _value properties
257254
# into a single string.
@@ -261,17 +258,19 @@ def __init__(self, **kwargs):
261258
# - None means the parameter is not specified.
262259
# - Sequence of strings means this is a repeatable option, so it can only have
263260
# one long-form parameter.
264-
for option, aliases in self.aliasdict.items():
261+
kwdict = {}
262+
for option, aliases in kwargs.items():
265263
if isinstance(aliases, Sequence): # A sequence of Alias objects.
266264
values = [alias._value for alias in aliases if alias._value is not None]
267265
if values:
268-
self.kwdict[option] = "".join(values)
266+
kwdict[option] = "".join(values)
269267
elif aliases._value is not None: # A single Alias object and not None.
270-
self.kwdict[option] = aliases._value
268+
kwdict[option] = aliases._value
269+
super().__init__(kwdict)
271270

272-
def update(self, kwargs: Mapping[str, Any]):
271+
def merge(self, kwargs: Mapping[str, Any]):
273272
"""
274-
Update the kwdict dictionary with additional keyword arguments.
273+
Update the dictionary with additional keyword arguments.
275274
276275
This method is necessary to allow users to use the single-letter parameters for
277276
option flags that are not aliased.
@@ -293,7 +292,7 @@ def update(self, kwargs: Mapping[str, Any]):
293292
)
294293

295294
# Long-form parameters are already specified.
296-
if short_param in self.kwdict:
295+
if short_param in self:
297296
msg = (
298297
f"Short-form parameter {short_param!r} conflicts with "
299298
"long-form parameters and is not recommended. "
@@ -308,6 +307,6 @@ def update(self, kwargs: Mapping[str, Any]):
308307
)
309308
warnings.warn(msg, category=SyntaxWarning, stacklevel=2)
310309

311-
# Update the kwdict with the short-form parameter anyway.
312-
self.kwdict[short_param] = value
310+
# Update the dictionary with the short-form parameter anyway.
311+
self[short_param] = value
313312
return self

pygmt/src/basemap.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ def basemap(self, region=None, projection=None, frame=None, **kwargs):
8282
"""
8383
self._activate_figure()
8484

85-
alias = AliasSystem(
85+
aliasdict = AliasSystem(
8686
R=Alias(region, name="region", separator="/", size=[4, 6]),
8787
J=Alias(projection, name="projection"),
8888
B=Alias(frame, name="frame"),
89-
).update(kwargs)
89+
).merge(kwargs)
9090

9191
with Session() as lib:
92-
lib.call_module(module="basemap", args=build_arg_list(alias.kwdict))
92+
lib.call_module(module="basemap", args=build_arg_list(aliasdict))

pygmt/tests/test_alias_system.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def func(
2020
"""
2121
A simple function to test the alias system.
2222
"""
23-
alias = AliasSystem(
23+
aliasdict = AliasSystem(
2424
J=Alias(projection, name="projection"),
2525
R=Alias(region, name="region", separator="/", size=[4, 6]),
2626
B=Alias(frame, name="frame"),
@@ -29,8 +29,8 @@ def func(
2929
Alias(text, name="text", prefix="+t"),
3030
Alias(offset, name="offset", prefix="+o", separator="/"),
3131
],
32-
).update(kwargs)
33-
return build_arg_list(alias.kwdict)
32+
).merge(kwargs)
33+
return build_arg_list(aliasdict)
3434

3535

3636
def test_alias_system_long_form():

0 commit comments

Comments
 (0)