From 780b86068b3c9de0be68df71a8e45b22dccc1c0c Mon Sep 17 00:00:00 2001 From: Connor Ward Date: Wed, 15 Jul 2026 15:49:13 +0100 Subject: [PATCH 1/3] Add AppContext.getAll method --- petsctools/appctx.py | 15 ++++++++++++++- tests/test_appctx.py | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/petsctools/appctx.py b/petsctools/appctx.py index 661c3a1..d770fef 100644 --- a/petsctools/appctx.py +++ b/petsctools/appctx.py @@ -8,6 +8,9 @@ """The global storage for user data with arbitrary python types.""" +_APPCTX_KEY_PREFIX = "petsctools_appctx_key_" + + class AppContextKey(str): """A custom key type for AppContext. @@ -26,7 +29,7 @@ class AppContextKey(str): @classmethod def _generate_key(cls): - return f"petsctools_appctx_key_{next(cls._count)}" + return f"{_APPCTX_KEY_PREFIX}{next(cls._count)}" class AppContext: @@ -214,6 +217,16 @@ def get( except PetscToolsAppctxException: return default + def getAll(self) -> dict[str, Any]: + """Return all entries in the app context.""" + from petsc4py import PETSc + + return { + key: _global_appctx_data[value] + for key, value in PETSc.Options(self.prefix).getAll().items() + if value.startswith(_APPCTX_KEY_PREFIX) + } + class AppContextManager: """ diff --git a/tests/test_appctx.py b/tests/test_appctx.py index f9c6fb9..bb5cecb 100644 --- a/tests/test_appctx.py +++ b/tests/test_appctx.py @@ -126,3 +126,19 @@ def test_appctx_key(): prm = appctx1['param'] assert prm is prefix1_param + + +@pytest.mark.skipnopetsc4py +def test_appctx_get_all(): + PETSc = petsctools.init() + + item1 = object() + item2 = object() + + optsmngr = petsctools.OptionsManager( + {"item1": item1, "item2": item2, "other_option": 666}, + options_prefix="myprefix", + ) + with optsmngr.inserted_options(): + appctx = petsctools.AppContext("myprefix") + assert appctx.getAll() == {"item1": item1, "item2": item2} From 625e292d7066cd0178fc5520345d1a20d2c73081 Mon Sep 17 00:00:00 2001 From: Connor Ward Date: Wed, 15 Jul 2026 16:00:48 +0100 Subject: [PATCH 2/3] fixup --- tests/test_appctx.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_appctx.py b/tests/test_appctx.py index bb5cecb..4583198 100644 --- a/tests/test_appctx.py +++ b/tests/test_appctx.py @@ -130,8 +130,6 @@ def test_appctx_key(): @pytest.mark.skipnopetsc4py def test_appctx_get_all(): - PETSc = petsctools.init() - item1 = object() item2 = object() From 0d7efbc038586f61c9a413dfa42a77cfbc05bfe0 Mon Sep 17 00:00:00 2001 From: Connor Ward Date: Wed, 15 Jul 2026 16:22:55 +0100 Subject: [PATCH 3/3] fixup --- petsctools/appctx.py | 2 +- tests/test_appctx.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/petsctools/appctx.py b/petsctools/appctx.py index d770fef..17dbce4 100644 --- a/petsctools/appctx.py +++ b/petsctools/appctx.py @@ -224,7 +224,7 @@ def getAll(self) -> dict[str, Any]: return { key: _global_appctx_data[value] for key, value in PETSc.Options(self.prefix).getAll().items() - if value.startswith(_APPCTX_KEY_PREFIX) + if isinstance(value, str) and value.startswith(_APPCTX_KEY_PREFIX) } diff --git a/tests/test_appctx.py b/tests/test_appctx.py index 4583198..fb0db13 100644 --- a/tests/test_appctx.py +++ b/tests/test_appctx.py @@ -134,7 +134,12 @@ def test_appctx_get_all(): item2 = object() optsmngr = petsctools.OptionsManager( - {"item1": item1, "item2": item2, "other_option": 666}, + { + "item1": item1, + "item2": item2, + "other_option": 666, + "another_option": None, + }, options_prefix="myprefix", ) with optsmngr.inserted_options():