4
4
5
5
import dataclasses
6
6
import warnings
7
+ from collections import UserDict
7
8
from collections .abc import Mapping , Sequence
8
9
from typing import Any , Literal
9
10
@@ -198,17 +199,17 @@ def _value(self) -> str | list[str] | None:
198
199
)
199
200
200
201
201
- class AliasSystem :
202
+ class AliasSystem ( UserDict ) :
202
203
"""
203
204
Alias system for mapping PyGMT's long-form parameters to GMT's short-form options.
204
205
205
206
This class is initialized with keyword arguments, where each key is a GMT option
206
207
flag, and the corresponding value is an ``Alias`` object or a list of ``Alias``
207
208
objects.
208
209
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 .
212
213
213
214
Examples
214
215
--------
@@ -218,16 +219,16 @@ class AliasSystem:
218
219
>>> def func(
219
220
... par0, par1=None, par2=None, frame=False, repeat=None, panel=None, **kwargs
220
221
... ):
221
- ... alias = AliasSystem(
222
+ ... aliasdict = AliasSystem(
222
223
... A=[
223
224
... Alias(par1, name="par1"),
224
225
... Alias(par2, name="par2", prefix="+o", separator="/"),
225
226
... ],
226
227
... B=Alias(frame, name="frame"),
227
228
... D=Alias(repeat, name="repeat"),
228
229
... 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 )
231
232
>>> func(
232
233
... "infile",
233
234
... par1="mytext",
@@ -242,16 +243,12 @@ class AliasSystem:
242
243
243
244
def __init__ (self , ** kwargs ):
244
245
"""
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.
247
247
"""
248
- # Storing the aliases as a dictionary for easy access .
248
+ # Store the aliases in a dictionary, to be used in the merge() method .
249
249
self .aliasdict = kwargs
250
250
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
255
252
# objects. If it is a single Alias object, we will use its _value property. If
256
253
# it is a sequence of Alias objects, we will concatenate their _value properties
257
254
# into a single string.
@@ -261,17 +258,19 @@ def __init__(self, **kwargs):
261
258
# - None means the parameter is not specified.
262
259
# - Sequence of strings means this is a repeatable option, so it can only have
263
260
# one long-form parameter.
264
- for option , aliases in self .aliasdict .items ():
261
+ kwdict = {}
262
+ for option , aliases in kwargs .items ():
265
263
if isinstance (aliases , Sequence ): # A sequence of Alias objects.
266
264
values = [alias ._value for alias in aliases if alias ._value is not None ]
267
265
if values :
268
- self . kwdict [option ] = "" .join (values )
266
+ kwdict [option ] = "" .join (values )
269
267
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 )
271
270
272
- def update (self , kwargs : Mapping [str , Any ]):
271
+ def merge (self , kwargs : Mapping [str , Any ]):
273
272
"""
274
- Update the kwdict dictionary with additional keyword arguments.
273
+ Update the dictionary with additional keyword arguments.
275
274
276
275
This method is necessary to allow users to use the single-letter parameters for
277
276
option flags that are not aliased.
@@ -293,7 +292,7 @@ def update(self, kwargs: Mapping[str, Any]):
293
292
)
294
293
295
294
# Long-form parameters are already specified.
296
- if short_param in self . kwdict :
295
+ if short_param in self :
297
296
msg = (
298
297
f"Short-form parameter { short_param !r} conflicts with "
299
298
"long-form parameters and is not recommended. "
@@ -308,6 +307,6 @@ def update(self, kwargs: Mapping[str, Any]):
308
307
)
309
308
warnings .warn (msg , category = SyntaxWarning , stacklevel = 2 )
310
309
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
313
312
return self
0 commit comments