Skip to content

Parameter() raises TypeError with its documented default allowable_keys=None #110

Open

Description

@jsh9

Found while reviewing #74. Pre-existing on main (b764057); #74 does not change the behavior.

Problem

Parameter.__init__() has allowable_keys: set[str] | None = None, and the docstring lists allowable_keys : set[str] | None, default=None. But the first check rejects anything that is not a set, so the default (or an explicit None) always raises TypeError: `allowable_keys` should be a set of str. The docstring does not say what None should mean. __setitem__() also does key not in self.allowable_keys, which would need a set. The only callers in the package, HH_Param and MKZ_Param, always pass a set.

allowable_keys : set[str] | None, default=None
The allowable parameter names of the constitutive model.

allowable_keys : set[str] | None
Same as the input parameter.

allowable_keys: set[str] | None = None,

if not isinstance(allowable_keys, set) or any(
not isinstance(_, str) for _ in allowable_keys
):
raise TypeError('`allowable_keys` should be a set of str.')

def __setitem__(self, key: str, item: float) -> None:
if key not in self.allowable_keys:
raise KeyError(f"The model does not have a '{key}' parameter.")

from PySeismoSoil.class_parameters import Parameter

for kwargs in [{}, {'allowable_keys': None}]:
    try:
        Parameter({'a': 1.0}, **kwargs)
        print('OK')
    except TypeError as e:
        print(f'{type(e).__name__}: {e}')
# TypeError: `allowable_keys` should be a set of str.
# TypeError: `allowable_keys` should be a set of str.
# (expected: the documented default works)

param = Parameter({'a': 1.0}, allowable_keys={'a'})
print(dict(param))
# {'a': 1.0}

Fix

Choose one of these:

  1. Make allowable_keys a required keyword argument: change the signature to allowable_keys: set[str] with no default, and change the docstring (parameter and attribute) to allowable_keys : set[str]. This matches what HH_Param and MKZ_Param already do.
  2. Or give None a meaning, for example "any key is allowed": skip the key checks in __init__() and __setitem__() when self.allowable_keys is None, and say so in the docstring.

Add a test for the chosen behavior: either that Parameter({'a': 1.0}) raises TypeError because the argument is missing, or that it works and accepts new keys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions