diff --git a/petsctools/appctx.py b/petsctools/appctx.py index 661c3a1..17dbce4 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 isinstance(value, str) and value.startswith(_APPCTX_KEY_PREFIX) + } + class AppContextManager: """ diff --git a/tests/test_appctx.py b/tests/test_appctx.py index f9c6fb9..fb0db13 100644 --- a/tests/test_appctx.py +++ b/tests/test_appctx.py @@ -126,3 +126,22 @@ def test_appctx_key(): prm = appctx1['param'] assert prm is prefix1_param + + +@pytest.mark.skipnopetsc4py +def test_appctx_get_all(): + item1 = object() + item2 = object() + + optsmngr = petsctools.OptionsManager( + { + "item1": item1, + "item2": item2, + "other_option": 666, + "another_option": None, + }, + options_prefix="myprefix", + ) + with optsmngr.inserted_options(): + appctx = petsctools.AppContext("myprefix") + assert appctx.getAll() == {"item1": item1, "item2": item2}