Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion petsctools/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,14 @@ def get(

def getAll(self) -> dict[str, Any]:
"""Return all entries."""
# Try to apply type casting to the objects returned by
# super().getAll(). Command line arguments with double dashes e.g.
# "--opt val" will appear as {"opt": "val"} in
# PETSc.Options().getAll(), but PETSc.Options()["opt"] or
# PETSc.Options().get("opt") will raise KeyErrors. Passing self.get() a
# default value from PETSc.Options().getAll() works around this error
# by returning the default when the KeyError is raised.
return {
key: self[key]
key: self.get(key, value)
for key, value in super().getAll().items()
}
48 changes: 48 additions & 0 deletions tests/test_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def temporarily_remove_options():
options = petsctools.Options()

previous_options = dict(options.getAll())
# Note that options.clear() does not actually remove all options from
# the database - definitely a bug.
Comment thread
JHopeCollins marked this conversation as resolved.
Resolved
options.clear()
previous_option_types = petsctools.options._option_types
petsctools.options._option_types = {}
Expand All @@ -28,6 +30,7 @@ def temporarily_remove_options():

yield

options.clear()
for k, v in previous_options.items():
options[k] = v
petsctools.options._option_types = previous_option_types
Expand Down Expand Up @@ -481,3 +484,48 @@ def test_options_missing_types(setter, deleter):
for opts in [petsc_opts, petsctools_opts]:
with pytest.raises(KeyError):
opts["my_option"]


@pytest.mark.skipnopetsc4py
def test_getAll_does_type_casting():
opts = petsctools.Options()
params = {
"integer": 666,
"float": 12.3,
"string": "abc",
"bool": False,
}
for name, value in params.items():
opts[name] = value

# Note that opts.getAll() can contain more than one entry because
# PETSc.Options().clear() is bugged, so we get contamination from previous
# tests.
for name, value in params.items():
assert (name, value) in opts.getAll().items()


@pytest.mark.skipnopetsc4py
@pytest.mark.parametrize("backend", ["petsc4py", "petsctools"])
def test_double_dash_options_do_not_break_getAll(backend):
# PETSc.Options.getAll() will include options passed with double-dashes
# (e.g. --pdb as 'pdb') but any attempt to access the option with
# .get(), __getitem__ etc will raise a KeyError. This test is here to
# check that petsctools.Options.getAll() will run without error when '--'
# options are passed (even though the result itself is bugged).
from petsc4py import PETSc

opts = petsctools.Options() if backend == "petsctools" else PETSc.Options()
opts["--value"] = "xyz"

# Note that opts.getAll() can contain more than one entry because
# PETSc.Options().clear() is bugged, so we get contamination from previous
# tests.
assert ("value", "xyz") in opts.getAll().items()

# Check that PETSc have the odd behaviour that we expect - if this fails
# then we can undo things!
with pytest.raises(KeyError):
opts["value"]
with pytest.raises(KeyError):
opts.getString("value")
Comment thread
JHopeCollins marked this conversation as resolved.
Resolved
Loading