Repository navigation
Resolve pkg:// search paths without importing packages - #78
Merged
Merged
Conversation
Plugin discovery and config lookups called importlib.util.find_spec and importlib.resources.files, which run every parent __init__ of each registered pkg:// path. Any app with a few plugins installed paid for importing all of them on startup. Existence checks and listings now locate the package directory by walking the import path, and fall back to importlib for zip imports, namespace packages, already-imported packages and modules shadowing packages. Reading a config still uses importlib.resources, so a package whose configs are used is imported as before. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
ruff 0.17 no longer enables DTZ005 by default, so the suppression trips RUF100 and fails lint-py. Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com>
Contributor
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every
pkg://search path registered throughhydra.lernapluginswas resolved withimportlib.util.find_spec(plugin discovery) andimportlib.resources.files(config source checks and listings). Both import the package and run every parent__init__.py, so an app paid for importing every installed plugin on startup, even ones it never used. On my machine, with 14 plugins installed, composing a one-line config took 2.45s and imported ccflow along with most of the plugin packages.pkg_helper.find_package_dirnow locates a regular package's directory by walking the import path in the same order the path finder uses: a regular package, then a module, then namespace portions. Already-imported parents use their real__path__. It returnsNonewhenever a walk can't match what an import would do (zip imports, namespace leaf packages, already-imported packages, modules shadowing packages, missing packages), and callers then useimportlibas before._is_pkg_path_availableandImportlibResourcesConfigSource.available/is_group/is_config/listuse the walk, as do thepkg_config_exists,pkg_group_existsandpkg_list_optionscallbacks used by the Rust repository.ImportlibResourcesConfigSource.load_configandload_pkg_configstill callimportlib.resources.files. A package whose configs are actually read is imported as before, so import-time side effects such asConfigStoreregistrations still run before its configs are used.The same compose now takes 0.24s and imports none of the plugin packages.
test_pkg_paths.pycovers parents with an__init__that raises, namespace parents, an extended__path__, the fallback cases including a zip import, and that reading a config still imports the package. The full suite has the same 147 failures asmainlocally (shell-completionexpectscripts, completion tests that see installed plugins' groups, and fixturepip installin an externally managed Python), with no new ones.