From 4b6b47270fc42f490c31d457b73950fa8375c1cb Mon Sep 17 00:00:00 2001 From: Sam Levang Date: Thu, 20 Nov 2025 13:20:06 -0500 Subject: [PATCH 1/3] fastpath for built-ins --- xarray/backends/plugins.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/xarray/backends/plugins.py b/xarray/backends/plugins.py index 97455d8acc0..eb355e7a746 100644 --- a/xarray/backends/plugins.py +++ b/xarray/backends/plugins.py @@ -215,15 +215,19 @@ def guess_engine( def get_backend(engine: str | type[BackendEntrypoint]) -> BackendEntrypoint: """Select open_dataset method based on current engine.""" if isinstance(engine, str): - engines = list_engines() - if engine not in engines: - raise ValueError( - f"unrecognized engine '{engine}' must be one of your download engines: {list(engines)}. " - "To install additional dependencies, see:\n" - "https://docs.xarray.dev/en/stable/user-guide/io.html \n" - "https://docs.xarray.dev/en/stable/getting-started-guide/installing.html" - ) - backend = engines[engine] + if engine in BACKEND_ENTRYPOINTS: + # fast path for built-in engines + backend = BACKEND_ENTRYPOINTS[engine][1]() + else: + engines = list_engines() + if engine not in engines: + raise ValueError( + f"unrecognized engine '{engine}' must be one of your download engines: {list(engines)}. " + "To install additional dependencies, see:\n" + "https://docs.xarray.dev/en/stable/user-guide/io.html \n" + "https://docs.xarray.dev/en/stable/getting-started-guide/installing.html" + ) + backend = engines[engine] elif issubclass(engine, BackendEntrypoint): backend = engine() else: From 9c206100ef5bfb4979e01c34bda504e8a19aa1a2 Mon Sep 17 00:00:00 2001 From: Sam Levang Date: Fri, 21 Nov 2025 12:36:29 -0500 Subject: [PATCH 2/3] set missing params --- xarray/backends/plugins.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xarray/backends/plugins.py b/xarray/backends/plugins.py index eb355e7a746..6e1784af5b6 100644 --- a/xarray/backends/plugins.py +++ b/xarray/backends/plugins.py @@ -217,7 +217,9 @@ def get_backend(engine: str | type[BackendEntrypoint]) -> BackendEntrypoint: if isinstance(engine, str): if engine in BACKEND_ENTRYPOINTS: # fast path for built-in engines - backend = BACKEND_ENTRYPOINTS[engine][1]() + backend_cls = BACKEND_ENTRYPOINTS[engine][1] + set_missing_parameters({engine: backend_cls}) + backend = backend_cls() else: engines = list_engines() if engine not in engines: From 852567e7918333cd36fe99f039aa47bd992a507d Mon Sep 17 00:00:00 2001 From: Sam Levang Date: Fri, 5 Dec 2025 23:50:40 -0500 Subject: [PATCH 3/3] add test and whats new --- doc/whats-new.rst | 7 +++++++ xarray/tests/test_plugins.py | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 89e9fbef56f..4b7bf8b2afd 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -35,6 +35,13 @@ Internal Changes ~~~~~~~~~~~~~~~~ +Performance +~~~~~~~~~~~ + +- Add a fastpath to the backend plugin system for standard engines (:issue:`10178`, :pull:`10937`). + By `Sam Levang `_. + + .. _whats-new.2025.12.0: v2025.12.0 (Dec 5, 2025) diff --git a/xarray/tests/test_plugins.py b/xarray/tests/test_plugins.py index a961be74b82..e20f665c9ff 100644 --- a/xarray/tests/test_plugins.py +++ b/xarray/tests/test_plugins.py @@ -208,6 +208,15 @@ def test_engines_not_installed() -> None: plugins.guess_engine("foo.nc") +@pytest.mark.parametrize("engine", common.BACKEND_ENTRYPOINTS.keys()) +def test_get_backend_fastpath_skips_list_engines(engine: str) -> None: + """Test that built-in engines skip list_engines (fastpath).""" + plugins.list_engines.cache_clear() + initial_misses = plugins.list_engines.cache_info().misses + plugins.get_backend(engine) + assert plugins.list_engines.cache_info().misses == initial_misses + + def test_lazy_import() -> None: """Test that some modules are imported in a lazy manner.