Skip to content

Commit 98c84fe

Browse files
authored
Support variable positional args. (#60)
* Support variable positional args. This is needed for transpose. * Support transpose multiple dims.
1 parent c9d66f5 commit 98c84fe

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

cf_xarray/accessor.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def _get_measure(da: Union[DataArray, Dataset], key: str) -> List[str]:
296296
#: Default mappers for common keys.
297297
_DEFAULT_KEY_MAPPERS: Mapping[str, Tuple[Mapper, ...]] = {
298298
"dim": (_get_axis_coord,),
299-
"dims": (_get_axis_coord,), # is this necessary?
299+
"dims": (_get_axis_coord,), # transpose
300300
"coords": (_get_axis_coord,), # interp
301301
"indexers": (_get_axis_coord,), # sel, isel
302302
"dims_or_levels": (_get_axis_coord,), # reset_index
@@ -433,9 +433,11 @@ def _getattr(
433433

434434
@functools.wraps(func)
435435
def wrapper(*args, **kwargs):
436-
arguments = accessor._process_signature(func, args, kwargs, key_mappers)
436+
posargs, arguments = accessor._process_signature(
437+
func, args, kwargs, key_mappers
438+
)
437439
final_func = extra_decorator(func) if extra_decorator else func
438-
result = final_func(**arguments)
440+
result = final_func(*posargs, **arguments)
439441
if wrap_classes and isinstance(result, _WRAPPED_CLASSES):
440442
result = _CFWrappedClass(result, accessor)
441443

@@ -575,25 +577,36 @@ def _process_signature(
575577
# This assigns indexers_kwargs=dict(T=5).
576578
# and indexers_kwargs is of kind VAR_KEYWORD
577579
var_kws = []
580+
# capture *args, e.g. transpose
581+
var_args = []
578582
for param in sig.parameters:
579583
if sig.parameters[param].kind is inspect.Parameter.VAR_KEYWORD:
580584
var_kws.append(param)
585+
elif sig.parameters[param].kind is inspect.Parameter.VAR_POSITIONAL:
586+
var_args.append(param)
581587

588+
posargs = []
582589
if args or kwargs:
583590
bound = sig.bind(*args, **kwargs)
584591
arguments = self._rewrite_values(
585592
bound.arguments, key_mappers, tuple(var_kws)
586593
)
587-
# now unwrap the **indexers_kwargs type arguments
588-
# so that xarray can parse it :)
594+
595+
# unwrap the *args type arguments
596+
for arg in var_args:
597+
value = arguments.pop(arg, None)
598+
if value:
599+
# value should always be Iterable
600+
posargs.extend(value)
601+
# now unwrap the **kwargs type arguments
589602
for kw in var_kws:
590603
value = arguments.pop(kw, None)
591604
if value:
592605
arguments.update(**value)
593606
else:
594607
arguments = {}
595608

596-
return arguments
609+
return posargs, arguments
597610

598611
def _rewrite_values(
599612
self,

cf_xarray/tests/test_accessor.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,19 @@ def test_kwargs_methods(obj):
183183
assert_identical(expected, actual)
184184

185185

186+
def test_pos_args_methods():
187+
expected = airds.transpose("lon", "time", "lat")
188+
actual = airds.cf.transpose("longitude", "T", "latitude")
189+
assert_identical(actual, expected)
190+
191+
actual = airds.cf.transpose("longitude", ...)
192+
assert_identical(actual, expected)
193+
194+
expected = multiple.transpose("y2", "y1", "x1", "x2")
195+
actual = multiple.cf.transpose("Y", "X")
196+
assert_identical(actual, expected)
197+
198+
186199
def test_preserve_unused_keys():
187200

188201
ds = airds.copy(deep=True)

0 commit comments

Comments
 (0)