From b0436faa5e3c35977607da6a653425fc6bf43403 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Thu, 22 Jan 2026 07:03:05 -0800 Subject: [PATCH] Fix test isolation bug in test_startup_error_from_plugin_is_click_exception (#2627) * Fix test isolation bug in test_startup_error_from_plugin_is_click_exception The test creates a plugin that raises StartupError("boom") and registers it in the global plugin manager (pm). Without cleanup, this plugin leaks to subsequent tests, causing test_setting_boolean_validation_false_values to fail with "Error: boom" instead of "Forbidden". Add try/finally block to ensure the plugin is unregistered after the test completes, following the established cleanup pattern used elsewhere in the test suite. * Fix blacken-docs formatting in plugin_hooks.rst Apply blacken-docs formatting to code example that exceeded the 60 character line limit. --------- Co-authored-by: Claude --- docs/plugin_hooks.rst | 5 ++++- tests/test_cli.py | 14 +++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/plugin_hooks.rst b/docs/plugin_hooks.rst index da49811a..ad4a70f8 100644 --- a/docs/plugin_hooks.rst +++ b/docs/plugin_hooks.rst @@ -967,11 +967,14 @@ Here is an example that validates required plugin configuration. The server will from datasette.utils import StartupError + @hookimpl def startup(datasette): config = datasette.plugin_config("my-plugin") or {} if "required-setting" not in config: - raise StartupError("my-plugin requires setting required-setting") + raise StartupError( + "my-plugin requires setting required-setting" + ) You can also return an async function, which will be awaited on startup. Use this option if you need to execute any database queries, for example this function which creates the ``my_table`` database table if it does not yet exist: diff --git a/tests/test_cli.py b/tests/test_cli.py index 36d90e82..6cdfd924 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,7 +4,7 @@ from .fixtures import ( EXPECTED_PLUGINS, ) from datasette.app import SETTINGS -from datasette.plugins import DEFAULT_PLUGINS +from datasette.plugins import DEFAULT_PLUGINS, pm from datasette.cli import cli, serve from datasette.version import __version__ from datasette.utils import tilde_encode @@ -326,8 +326,16 @@ def test_startup_error_from_plugin_is_click_exception(tmp_path): "/", ], ) - assert result.exit_code == 1 - assert "Error: boom" in result.output + try: + assert result.exit_code == 1 + assert "Error: boom" in result.output + finally: + # Cleanup: Unregister the plugin to avoid test isolation issues + to_unregister = [ + p for p in pm.get_plugins() if p.__name__ == "startup_error.py" + ] + if to_unregister: + pm.unregister(to_unregister[0]) def test_setting_type_validation():