Bengal 0.1.9
Architecture decomposition, Python 3.14 modernization, build performance, protocol migrations, and comprehensive docs audit
Key additions: Major architecture decomposition (mixins → free functions + composed services, 12 → 4 Site mixins), Python 3.14 modernization (PEP 695 type params, slots, exception chaining), build performance optimizations (~50-60% faster), protocol-based decoupling across 40+ files, thread safety hardening, incremental build improvements, structured error handling, and a comprehensive documentation staleness audit.
Highlights
Architecture Decomposition
The largest structural change in Bengal's history — systematic decomposition of monolithic mixins into free functions and composed services:
- Protocol-based decoupling:
PageLikeandSiteLikesplit into role-based protocols (SiteConfig,SiteContent,Summarizable), migrated across 40+ consumer files - Mixin elimination:
Siteinheritance chain reduced from 12 to 4 mixins —PageComputedMixin,PageBundleMixin,PageNavigationMixin,SitePropertiesMixin, andSiteVersioningMixinall extracted to free functions or composed services - ConfigService: New frozen dataclass composing all configuration access, wired into
Sitewith bridge properties (31 tests) - EffectTracer: Replaces
DependencyTrackerwith persistence, file fingerprinting, and thread-safe operation - Module splits:
snapshots/builder.py(1,762 lines) split into 5 focused modules - Type cleanup: 55 stale
type: ignorecomments removed,Anyescape hatches replaced with correct types across rendering and Page files
Python 3.14 Modernization
Codebase-wide adoption of modern Python syntax:
- PEP 695 type parameters:
class Foo[T]:replacesclass Foo(Generic[T]):throughout slots=Trueon all frozen dataclasses for memory efficiency- Exception chaining in all raise-in-except blocks
ClassVarannotations on mutable class defaults- Comprehension conversion from manual list building (PERF401)
- Narrowed exception handlers across rendering modules
Build Performance Optimizations
Three-phase performance RFC delivering cumulative ~50-60% speedup for large sites:
- Fast mode (
build.fast_mode=True): Skip HTML pretty-printing/minification for ~10-15% speedup - Render-time asset tracking: ContextVar-based AssetTracker eliminates post-render HTML parsing (~20-25% speedup)
- Autodoc AST caching: Cache parsed Python module data across builds (~30-40% speedup for autodoc-heavy sites)
- Parser pooling: Re-enabled with patitas 0.1.1's
_reinit()support (~78% faster parser instantiation) - Snapshot pre-computation: NavTrees and renderer caches pre-computed at snapshot time for lock-free lookups
Incremental Build Observability
New CLI flags for understanding rebuild decisions:
# Explain why pages are being rebuilt
bengal build --explain
# Preview what would be rebuilt without doing it
bengal build --dry-run
# Machine-readable rebuild manifest
bengal build --explain-json > manifest.json
Thread Safety Hardening
Comprehensive free-threading support for Python 3.14t:
- ContextVar asset manifest: Fixes TOCTOU race condition (~8M ops/sec, zero lock contention)
- Lock ordering convention: Documented lock hierarchy prevents deadlocks
- Immutable snapshots: Pre-computed at snapshot time for lock-free rendering
- BuildCache/DependencyTracker separation: Clean pipeline boundaries
- Threading integration tests: EffectTracer and BuildTaxonomyIndex verified under concurrent load
Cache Coordination
UnifiedCacheCoordinatormanages cache invalidation across all subsystems:
- PathRegistry: Centralized path-to-cache-key mapping
- RebuildManifest: Tracks what needs rebuilding and why
- Content-hash embedding: O(1) change detection via embedded hashes in output
- Template change detection: Cache now detects template file changes and triggers rebuilds
- EffectTracer pipeline: Wired into incremental builds with persistence and file fingerprinting
Structured Error Handling
Five new exception classes with actionable suggestions:
| Exception | Use Case |
|---|---|
BengalParsingError |
Markdown/frontmatter parsing failures |
BengalAutodocError |
Autodoc extraction issues |
BengalValidatorError |
Health check validation failures |
BengalBuildError |
Build pipeline errors |
BengalTemplateFunctionError |
Template filter/function errors |
All exceptions include error codes (O/V/B series) and contextual suggestions.
Documentation Audit
Comprehensive staleness audit across all documentation sections:
- Fixed stale claims in about, building, content, extending, get-started, reference, and theming
- Aligned page URL properties to match codebase (
page.href,page._path) - Replaced Jinja2-style block endings with
{% end %}in Kida examples - Added external cross-links for Kida, Patitas, and Rosettes
Additional Changes
Developer Experience
bengal upgrade: Self-update command with PyPI version checking and installer detection- Serve-first startup: Dev server serves cached content immediately (~200ms first paint)
- Dead link indicators: Visual styling for broken internal links
Theme Enhancements
- Header customization:
nav_position(left/center),sticky, andautohideoptions via data attributes
Changelog & Releases Filter
- Smart semver-aware version sorting
- Domain-aware filtering with simplified API
CI & Packaging
- Trusted publishing:
python-publish.ymlGitHub Actions workflow for OIDC-based PyPI publishing - Pages fix:
--clean-outputflag fixes 404s on/api/and/cli/
Directives
- Patitas-native glossary directive
Breaking Changes
None. This is a fully backward-compatible release.
Bug Fixes
- Duplicate tag pages: Fixed incremental builds generating duplicate taxonomy pages
- Anchor fragment preservation:
.mdlinks now preserve#sectionanchors during normalization - Serve-first activation: Fixed serve-first not triggering when
baseurlis/ - Python 3.14 import scoping: Fixed cache loading issue with import scoping in 3.14
- Undefined references: Fixed undefined name references in site and sitemap modules
- Incremental tag terms: Fixed tag term page generation in incremental builds
- CI test failures: Fixed missing module, wrong kwarg, and unimplemented test gaps
Dependency Updates
| Package | Version | Change |
|---|---|---|
patitas |
≥0.1.1 | Adds_reinit()for parser pooling |
kida-templates |
≥0.1.2 | RenderContext, profiling support |
Upgrading
uv pip install --upgrade bengal
# or
pip install --upgrade bengal
# or use the new self-update command
bengal upgrade