@@ -248,7 +248,7 @@ def from_params(
248248
249249def _parse_position (
250250 position : Position | Sequence [float | str ] | str | None ,
251- default : Position | None ,
251+ default : Position | None = None ,
252252 kwdict : dict [str , Any ] | None = None ,
253253) -> Position | str | None :
254254 """
@@ -269,7 +269,9 @@ def _parse_position(
269269 is ``None``, use the GMT default.
270270 kwdict
271271 The keyword arguments dictionary that conflicts with ``position`` if
272- ``position`` is given as a raw GMT command string.
272+ ``position`` is given as a raw GMT command string. This is used for backward
273+ compatibility to raise an exception if there are conflicting parameters. If
274+ ``kwdict`` is ``None``, no conflict checking is performed (for new functions).
273275
274276 Returns
275277 -------
@@ -336,21 +338,49 @@ def _parse_position(
336338 Traceback (most recent call last):
337339 ...
338340 pygmt.exceptions.GMTInvalidInput: Invalid type for parameter 'position':...
341+
342+ >>> # Below are examples without kwdict (for new functions).
343+ >>> _parse_position(
344+ ... "BL",
345+ ... default=Position((0, 0), cstype="plotcoords"),
346+ ... )
347+ Position(refpoint='BL', cstype='inside')
348+
349+ >>> _parse_position(
350+ ... "invalid",
351+ ... default=Position((0, 0), cstype="plotcoords"),
352+ ... )
353+ Traceback (most recent call last):
354+ ...
355+ pygmt.exceptions.GMTValueError: Invalid position: 'invalid'...
339356 """
340357
341358 _valid_anchors = {f"{ h } { v } " for v in "TMB" for h in "LCR" } | {
342359 f"{ v } { h } " for v in "TMB" for h in "LCR"
343360 }
344361 match position :
345- case str () if position in _valid_anchors : # Anchor code
346- position = Position (position , cstype = "inside" )
347- case str (): # Raw GMT command string.
348- if any (v is not None and v is not False for v in kwdict .values ()):
349- msg = (
350- "Parameter 'position' is given with a raw GMT command string, and "
351- f"conflicts with parameters { ', ' .join (repr (c ) for c in kwdict )} ."
362+ case str (): # String for anchor code or raw GMT command.
363+ if position in _valid_anchors : # Anchor code
364+ position = Position (position , cstype = "inside" )
365+ elif kwdict : # Raw GMT command string with potential conflicts.
366+ if any (v is not None and v is not False for v in kwdict .values ()):
367+ msg = (
368+ "Parameter 'position' is given with a raw GMT command string, "
369+ "and conflicts with parameters "
370+ f"{ ', ' .join (repr (c ) for c in kwdict )} ."
371+ )
372+ raise GMTInvalidInput (msg )
373+ else :
374+ # No conflicting parameters to check, indicating it's a new function.
375+ # The string must be an anchor code.
376+ raise GMTValueError (
377+ position ,
378+ description = "position" ,
379+ reason = (
380+ "Parameter 'position' must be a two-characeter anchor code, "
381+ "a coordinate, or a Position object." ,
382+ ),
352383 )
353- raise GMTInvalidInput (msg )
354384 case Sequence () if len (position ) == 2 : # A sequence of x and y coordinates.
355385 position = Position (position , cstype = "plotcoords" )
356386 case Position (): # Already a Position object.
0 commit comments