Skip to content

Improve IDE/Editor Support for External Accessors #11078

@FBumann

Description

@FBumann

Is your feature request related to a problem?

External accessor packages have no IDE support:

import xarray as xr
import hvplot.xarray  # required just to register accessor

ds = xr.open_dataset("data.nc")

ds.plot.scatter()    # Built-in: full IDE completion ✓
ds.hvplot.scatter()  # External: nothing. no hints, no docs ✗
Feature Built-in .plot External Accessor
Method completion
Parameter hints
Docstrings
Go-to-definition

This affects every accessor package: hvplot, cf-xarray, pint-xarray, rioxarray, xarray-plotly, and the entire xarray-contrib ecosystem.

The current message to package authors is "use the accessor system" - but that system provides a degraded experience compared to built-in features.

Describe the solution you'd like

Typed properties with lazy imports. Same pattern as dask.distributed.

# xarray/core/dataarray.py

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from hvplot.xarray import hvPlotAccessor
    from cf_xarray import CFAccessor

class DataArray:

    @property
    def hvplot(self) -> hvPlotAccessor:
        """hvPlot accessor. Requires: pip install hvplot"""
        from xarray.accessors import load_accessor
        return load_accessor("hvplot", self)

    @property
    def cf(self) -> CFAccessor:
        """CF conventions accessor. Requires: pip install cf-xarray"""
        from xarray.accessors import load_accessor
        return load_accessor("cf", self)
# xarray/accessors.py

ACCESSORS = {
    "hvplot": ("hvplot.xarray", "hvPlotAccessor", "hvplot"),
    "cf": ("cf_xarray", "CFAccessor", "cf-xarray"),
    "pint": ("pint_xarray", "PintDataArrayAccessor", "pint-xarray"),
    "rio": ("rioxarray", "RasterArray", "rioxarray"),
    "plotly": ("xarray_plotly", "DataArrayPlotlyAccessor", "xarray-plotly"),
}

def load_accessor(name: str, obj):
    package, cls_name, install_name = ACCESSORS[name]
    try:
        module = importlib.import_module(package)
        return getattr(module, cls_name)(obj)
    except ImportError:
        raise ImportError(f"{install_name} is not installed.\n\nInstall with: pip install {install_name}")

User experience after:

import xarray as xr

ds.hvplot.scatter()  # just works, full IDE support, no registration import!

Benefits:

  • Users: No registration imports, full IDE completion, helpful errors if not installed
  • Accessor maintainers: File PR adding ~5 lines, remove register_*_accessor boilerplate
  • xarray: Stays lean, implementation remains external, fully backwards compatible

Describe alternatives you've considered

Status quo: Keep register_*_accessor - but IDE support is impossible since types are unknown at static analysis time.

Stub files (.pyi): External packages could ship stubs, but this doesn't solve the "xarray doesn't know about the accessor" problem - the property still needs to exist on DataArray/Dataset.

Additional context

Backwards compatible: Old packages using register_*_accessor continue to work (setattr overwrites property). New packages remove registration and users get IDE completion.

Precedent: This is exactly how dask handles dask.distributed - typed entry point in dask, implementation in separate package.

Origin: PR #11075 - accessor was rejected (correctly) in favor of external package, but this revealed the IDE support gap.

cc: @xarray-contrib @holoviz @corteva

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions