wrapper class to help with passing methods via parametrize This is works a bit similar to using `partial(Class.method, arg, kwarg)`
| 292 | |
| 293 | |
| 294 | class method: |
| 295 | """wrapper class to help with passing methods via parametrize |
| 296 | |
| 297 | This is works a bit similar to using `partial(Class.method, arg, kwarg)` |
| 298 | """ |
| 299 | |
| 300 | def __init__(self, name, *args, fallback_func=None, **kwargs): |
| 301 | self.name = name |
| 302 | self.fallback = fallback_func |
| 303 | self.args = args |
| 304 | self.kwargs = kwargs |
| 305 | |
| 306 | def __call__(self, obj, *args, **kwargs): |
| 307 | from functools import partial |
| 308 | |
| 309 | all_args = merge_args(self.args, args) |
| 310 | all_kwargs = {**self.kwargs, **kwargs} |
| 311 | |
| 312 | from xarray.core.groupby import GroupBy |
| 313 | |
| 314 | xarray_classes = ( |
| 315 | xr.Variable, |
| 316 | xr.DataArray, |
| 317 | xr.Dataset, |
| 318 | GroupBy, |
| 319 | ) |
| 320 | |
| 321 | if not isinstance(obj, xarray_classes): |
| 322 | # remove typical xarray args like "dim" |
| 323 | exclude_kwargs = ("dim", "dims") |
| 324 | # TODO: figure out a way to replace dim / dims with axis |
| 325 | all_kwargs = { |
| 326 | key: value |
| 327 | for key, value in all_kwargs.items() |
| 328 | if key not in exclude_kwargs |
| 329 | } |
| 330 | if self.fallback is not None: |
| 331 | func = partial(self.fallback, obj) |
| 332 | else: |
| 333 | func_attr = getattr(obj, self.name, None) |
| 334 | |
| 335 | if func_attr is None or not callable(func_attr): |
| 336 | # fall back to module level numpy functions |
| 337 | numpy_func = getattr(np, self.name) |
| 338 | func = partial(numpy_func, obj) |
| 339 | else: |
| 340 | func = func_attr |
| 341 | else: |
| 342 | func = getattr(obj, self.name) |
| 343 | |
| 344 | return func(*all_args, **all_kwargs) |
| 345 | |
| 346 | def __repr__(self): |
| 347 | return f"method_{self.name}" |
| 348 | |
| 349 | |
| 350 | class function: |
no outgoing calls
searching dependent graphs…