Python environment engine + generic check_module() gate - #2
Merged
Conversation
reticulate is a hard Imports dependency, so requireNamespace() can never fail here; remove the guard.
Drop the import-based py_module_info() and the separate py_module_info2(); keep the metadata (no-import) implementation under the name py_module_info(). It reports module/available/version without importing, which is cheaper and safe for modules with heavy or side-effecting imports. module_version() now reads that metadata first and only falls back to importing + __version__ (module_version_by_import) when metadata yields nothing, so versions still resolve for namespace/editable installs and when importlib.metadata is unavailable. The now-unused python_module_path() and the dead reticulate guards in the introspectors are removed.
Port fafbseg's simple_python provisioning family into nat.python as the ecosystem's shared entry point for setting up a managed miniconda Python environment, including the curated basic/full/extra package bundles. Messaging uses cli rather than usethis, and the fafbseg.condaenv option is generalised to nat.python.condaenv (default r-reticulate). check_reticulate() collapses to a Python-availability gate now that reticulate is a hard dependency. Adds cli and jsonlite to Imports; reframes the Title/Description around managing Python for the natverse (this package is opinionated about how the environment should be set up, unlike bare reticulate).
A single entry point for code that needs a particular Python module: it checks
the module is installed (from distribution metadata, no import), imports it,
optionally enforces a minimum version, and on absence either installs it or
errors with actionable guidance. Ordered installed-first / load-second so a
failed import of an installed module is reported as an environment problem
(wrong Python) rather than a missing package.
install = c("ask", "never", "always") is self-documenting; instructions are
always shown, only the install action is gated. Results are memoised (cache =
TRUE) via check_module_impl, and simple_python() forgets that cache after an
install so later checks see newly installed packages. Package-specific checks
(fafbseg's check_seatable etc.) become thin wrappers over this and need not
memoise themselves.
Adds memoise to Imports.
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.
Summary
Brings fafbseg's Python provisioning engine and module install/load gate into
nat.python, so the natverse ecosystem has one place to set Python up and one
generic way to check a module is usable.
seatabler(and laterfafbseg,bancr) can then depend on nat.python for provisioning rather than on fafbseg.Four logically discrete commits, each builds on its own:
rids2pyint()— reticulate is a hardImportsdependency, so therequireNamespace()guard can never fire.py_module_info()to a single metadata-based introspector —drop the import-based
py_module_info()and the separatepy_module_info2(); keep the metadata (no-import) implementation under thename
py_module_info()(columnsmodule/available/version).module_version()now reads metadata first and falls back to importing +__version__only when metadata yields nothing, so versions still resolvefor namespace/editable installs and when
importlib.metadatais absent.Removes the now-unused
python_module_path().simple_python,check_reticulate) —ported near-verbatim from fafbseg's
simple_pythonfamily, including thecurated
basic/full/extrabundles. Messaging usesclirather thanusethis;fafbseg.condaenv→nat.python.condaenv(defaultr-reticulate).check_reticulate()collapses to a Python-availability gate.Reframes the Title/Description around managing Python for the natverse.
check_module()install/load gate — installed-first /load-second ordering so a failed import of an installed module is reported
as an environment problem (wrong Python) rather than a missing package.
install = c("ask", "never", "always")gates only the install action, neverthe instructions. Results are memoised (
cache = TRUE);simple_python()forgets that cache after an install. Package-specific checks (fafbseg's
check_seatableetc.) become thin wrappers over this and need not memoisethemselves.
Dependency changes
Adds
cli,jsonlite,memoisetoImports.Testing
Full suite green offline (
check-modulecovers every decision branch bymocking the Python-touching pieces;
py_module_info/module_versiontests passunchanged — numpy resolves via metadata, a bogus module via the import
fallback).
🤖 Generated with Claude Code