Skip to content

Release Notes — v1.17

Release date: May 2026

This release makes the validation API importable without PySpark. Tools that consume from weevr.config import load_config — CLIs, IDE plugins, docs generators, run-summary renderers — no longer need a PySpark install on sys.path to load and validate weevr configs. Existing Fabric runtime users see no behavior change.


Spark-free imports for the validation API

Prior to v1.17, import weevr (and transitively from weevr.config import load_config) loaded weevr.context at module-import time, which in turn imported pyspark.sql.SparkSession at the top of the file. Tools that deliberately ship without PySpark — the first concrete consumer is weevr-cli doing local config validation — could not reuse weevr's own Pydantic models, validators, and resolution pipeline. They had to maintain hand-written JSON Schemas that drifted from the engine's truth.

v1.17 closes the gap with two coordinated changes:

  1. PEP 562 lazy __getattr__ on the top-level weevr package. The four convenience names — Context, RunResult, ExecutionMode, LoadedConfig — now resolve through a _LAZY_ATTRS map at first-access time rather than eagerly at import. import weevr itself no longer pulls weevr.context (and therefore PySpark) into sys.modules. Static tooling still sees the names through a TYPE_CHECKING-guarded import block, so IDE autocomplete and pyright resolution are unchanged.

  2. Pure-Python helper extractions that previously sat inside Spark-bound modules:

    • merge_audit_columns_with_templates and its supporting template-merge helpers moved into a new weevr.config.audit_templates module. weevr.config.inheritance now imports the helper directly from the new location, breaking its transitive dependency on weevr.operations.audit.
    • resolve_effective_words moved to weevr.reserved_words. Both callers (the column_set._validate_rename_strategy Pydantic validator and weevr.operations.naming) keep working unchanged.

The original module locations (weevr.operations.audit, weevr.operations.reserved_words) keep one-line re-export shims so any code that imports from those paths continues to resolve. This is the "transparency contract" of the refactor: every public path that worked before still works.

A new CI lock test, tests/test_no_pyspark_imports.py, blocks pyspark* imports via sys.meta_path and then asserts that import weevr, from weevr.config import load_config, the model imports, and a representative end-to-end load_config(<example>) call all succeed. The test exercises both resolve_effective_words consumers (direct weevr.operations.reserved_words import and the Pydantic-validator path through column_set), so a future refactor that quietly relinks the lazy chain will fail this gate before users see it.

# Before v1.17 — this import failed without PySpark on sys.path:
from weevr.config import load_config

# v1.17 — same import, no PySpark required:
from weevr.config import load_config

config = load_config("my_thread.thread.yaml")

What stays the same

  • All existing import paths resolve unchanged. from weevr import Context still works in any environment that has PySpark available; the lazy resolver pulls weevr.context on first access.
  • pip install weevr continues to install the same surface; this release does not split the package on PyPI (that lands in v1.18).
  • Public API signatures, return types, and exception classes are byte-identical. Function bodies of the extracted helpers were preserved exactly — only their physical home changed, and the re-export shims keep the old paths importable.

Backwards compatibility

  • Existing configurations and existing engine call sites keep working without changes.
  • No public API renames, signature changes, or behavior tweaks. The refactor is intentionally transparent.
  • git log --follow is preserved on every relocated file.
  • The lazy __getattr__ only fires for the four names in _LAZY_ATTRS; any other attribute access on weevr raises AttributeError exactly as before.

What's next

v1.18 follows up by splitting weevr into two PyPI distributions (weevr-core for the pure-Python validation surface, weevr for the Spark engine) so consumers can pip install weevr-core and skip PySpark entirely. v1.17 is the prerequisite that makes that split safe.