rgpycrumbs.config

Ecosystem-wide layered TOML config (rgpkgs suite).

Shared by rgpycrumbs, chemparseplot, and siblings — not a package-private silo. One pin/lock policy for the whole stack.

Search order for config files (later merges override earlier):

  1. User global: $XDG_CONFIG_HOME/rgpkgs/config.toml (default ~/.config/rgpkgs/config.toml)

  2. Legacy user: ~/.config/rgpycrumbs/config.toml (still read)

  3. Project: walk upward for rgpkgs.toml / .rgpkgs.toml, then legacy rgpycrumbs.toml / .rgpycrumbs.toml

  4. RGPKGS_CONFIG or RGPYCRUMBS_CONFIG — explicit file (merged last)

Runtime precedence for values (highest first):

  • CLI flags (--lock, --sbom, --dev, …)

  • Environment (RGPKGS_LOCK / RGPYCRUMBS_LOCK, RGPKGS_FORCE_UV, …)

  • Merged TOML (project overrides global)

  • Built-in defaults

Example ~/.config/rgpkgs/config.toml:

# Shared across the suite (chemparseplot, rgpycrumbs, …)
[pins]
lock = "uv.lock"   # or pylock.toml / CycloneDX JSON

[pins.packages]
jax = "0.4.31"

# Tool-specific (optional)
[rgpycrumbs.dispatch]
auto_deps = true
force_uv = false

# Future: [chemparseplot.plot] theme = "…"

Added in version 1.9.15.

Changed in version 1.9.16: Ecosystem identity is rgpkgs (not per-package config trees).

Attributes

Classes

RgpycrumbsConfig

Resolved configuration (files + defaults; env/CLI applied separately).

Functions

_xdg_config_home(→ pathlib.Path)

user_config_path(→ pathlib.Path)

Preferred global config: ~/.config/rgpkgs/config.toml.

user_config_path_legacy(→ pathlib.Path)

Legacy global: ~/.config/rgpycrumbs/config.toml.

_is_file(→ bool)

Existence check via os.path (not Path.is_file) to avoid class mocks.

find_project_config(→ pathlib.Path | None)

Walk from start (default CWD) upward for a project config file.

_load_toml_file(→ dict[str, Any])

_as_bool(→ bool | None)

_normalize_packages(→ dict[str, str])

_resolve_path(→ pathlib.Path)

_first_env(→ str)

_env_flag_any(→ bool | None)

Return True/False if any env is set; None if all unset.

_extract_dispatch(→ dict[str, Any])

Return dispatch table from top-level or [rgpycrumbs.dispatch].

_merge_section(→ None)

load_config(→ RgpycrumbsConfig)

Load and merge global + project + optional explicit config files.

resolve_lock_path_layered(→ pathlib.Path | None)

CLI → env (RGPKGS_* / RGPYCRUMBS_*) → config file lock path.

resolve_force_uv(→ bool)

Whether to force uv isolation (False if --dev / DEV env).

resolve_auto_deps_default(→ str)

Return '1' or '0' for default AUTO_DEPS when env unset.

Module Contents

rgpycrumbs.config.tomllib = None[source]
rgpycrumbs.config.PROJECT_CONFIG_NAMES = ('rgpkgs.toml', '.rgpkgs.toml', 'rgpycrumbs.toml', '.rgpycrumbs.toml')[source]
rgpycrumbs.config.USER_CONFIG_REL[source]
rgpycrumbs.config.USER_CONFIG_LEGACY_REL[source]
rgpycrumbs.config.CONFIG_PATH_ENV = 'RGPKGS_CONFIG'[source]
rgpycrumbs.config.CONFIG_PATH_ENV_LEGACY = 'RGPYCRUMBS_CONFIG'[source]
rgpycrumbs.config.LOCK_PATH_ENVS = ('RGPKGS_LOCK', 'RGPYCRUMBS_LOCK', 'RGPYCRUMBS_SBOM')[source]
rgpycrumbs.config.FORCE_UV_ENVS = ('RGPKGS_FORCE_UV', 'RGPYCRUMBS_FORCE_UV')[source]
rgpycrumbs.config.AUTO_DEPS_ENVS = ('RGPKGS_AUTO_DEPS', 'RGPYCRUMBS_AUTO_DEPS')[source]
rgpycrumbs.config.DEV_ENVS = ('RGPKGS_DEV', 'RGPYCRUMBS_DEV')[source]
rgpycrumbs.config._xdg_config_home() pathlib.Path[source]
rgpycrumbs.config.user_config_path() pathlib.Path[source]

Preferred global config: ~/.config/rgpkgs/config.toml.

rgpycrumbs.config.user_config_path_legacy() pathlib.Path[source]

Legacy global: ~/.config/rgpycrumbs/config.toml.

rgpycrumbs.config._is_file(path: pathlib.Path) bool[source]

Existence check via os.path (not Path.is_file) to avoid class mocks.

rgpycrumbs.config.find_project_config(start: pathlib.Path | None = None) pathlib.Path | None[source]

Walk from start (default CWD) upward for a project config file.

Prefers rgpkgs.toml over legacy rgpycrumbs.toml in the same directory.

rgpycrumbs.config._load_toml_file(path: pathlib.Path) dict[str, Any][source]
rgpycrumbs.config._as_bool(value: Any) bool | None[source]
rgpycrumbs.config._normalize_packages(raw: Any) dict[str, str][source]
rgpycrumbs.config._resolve_path(raw: str, base_dir: pathlib.Path) pathlib.Path[source]
rgpycrumbs.config._first_env(*names: str) str[source]
rgpycrumbs.config._env_flag_any(*names: str) bool | None[source]

Return True/False if any env is set; None if all unset.

class rgpycrumbs.config.RgpycrumbsConfig[source]

Resolved configuration (files + defaults; env/CLI applied separately).

Shared pin fields apply suite-wide; dispatch fields are rgpycrumbs CLI defaults (other tools may ignore them).

auto_deps: bool | None = None[source]
force_uv: bool | None = None[source]
lock_path: pathlib.Path | None = None[source]
package_pins: dict[str, str][source]
sources: list[pathlib.Path] = [][source]
tool_tables: dict[str, dict[str, Any]][source]
merged_package_pins_normalized() dict[str, str][source]
rgpycrumbs.config._extract_dispatch(data: dict[str, Any]) dict[str, Any][source]

Return dispatch table from top-level or [rgpycrumbs.dispatch].

rgpycrumbs.config._merge_section(cfg: RgpycrumbsConfig, data: dict[str, Any], *, base_dir: pathlib.Path, source: pathlib.Path) None[source]
rgpycrumbs.config.load_config(*, cwd: pathlib.Path | None = None, explicit_config: pathlib.Path | str | None = None) RgpycrumbsConfig[source]

Load and merge global + project + optional explicit config files.

rgpycrumbs.config.resolve_lock_path_layered(*, cli_lock: str | None = None, cli_sbom: str | None = None, config: RgpycrumbsConfig | None = None, cwd: pathlib.Path | None = None) pathlib.Path | None[source]

CLI → env (RGPKGS_* / RGPYCRUMBS_*) → config file lock path.

rgpycrumbs.config.resolve_force_uv(*, is_dev: bool, config: RgpycrumbsConfig | None = None, cwd: pathlib.Path | None = None) bool[source]

Whether to force uv isolation (False if –dev / DEV env).

rgpycrumbs.config.resolve_auto_deps_default(*, config: RgpycrumbsConfig | None = None, cwd: pathlib.Path | None = None) str[source]

Return '1' or '0' for default AUTO_DEPS when env unset.