Plugins: a theme plugin switched off or removed at run time stays in the theme picker, and a removed one breaks export #609
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#609
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, reading what the registry undoes when a plugin goes away.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atplugins/installing.py:1072-1088(_forget_metadata_cache);catch_upand the other files have not moved.Related to #228, which made installs, removals and switch-offs take effect without a restart (
registry.catch_up) and stopped rejected plugins registering templates and themes (§5), but did not undo what a plugin that was loaded registered once it is switched off or removed.Loading a plugin registers its document themes (
documents.themes._from_plugins), itstemplates/directory, itslocale/directory and, when its logo is first shown, a cached copy of the logo. When the record's stamp moves,catch_upclearsregistry._cacheand reloads the plugins that are still on; nothing removes what the others registered.themes.forgetis called only from tests, andlogos.forgetlikewise.plugins/registry.py:237-271(catch_up:_cache.clear(); activate(); …invalidate_caches());plugins/installing.py:1246-1262(_forget_metadata_cache, which only refreshes the registry);documents/themes.py:125and:150-155(_from_plugins,forget);plugins/logos.py:51and:172-177(_cache,forget);plugins/themes.py:38,:52-69;plugins/locale.py:22,:73-97.themes.for_kindstill lists it, so the CV and letter theme pickers still offer it andtemplate_for(documents/themes.py:218-231) still resolves documents set in it to the plugin's templates, which still render because the template directory is still onDIRS.template_fordoes not fall back to the default as it would after a restart (find(name) or find(DEFAULT)), and Export reachesrender_to_stringwith a template that no longer exists:TemplateDoesNotExist, a 500. That is the failure thedocuments/themes.pydocstring says the registry exists to prevent.logo_for's docstring (plugins/logos.py:128-129) says "installing one rebuilds the registry" as the reason the cache is safe.catch_upand in_forget_metadata_cache, after the reload, forget the themes and logos of every plugin that is no longer loaded and drop its template and locale paths (then_forget_the_engines()and resettrans_real._translations). Clearlogos._cacheon every rebuild. Correct theregister_locale_dirdocstring (plugins/locale.py:76-80), which says registration happens "at start-up and never during a request": since #228catch_upre-runs_load_third_party, and so this, inside whichever request first notices the change.Done when
tests/test_document_themes.pyregisters a theme plugin, switches it off (moves the record stamp), callsregistry.plugins(...), and asserts its theme is gone fromthemes.for_kindand thattemplate_forfalls back to the default; a test intests/test_plugin_logos.pyasserts the logo cache is empty after a rebuild.