Looking at it, I'm not sure why it should pass, L28 will give a dict and L30 seems to want str/bytes
FAILED [100%]
gufe/tests/test_models.py:15 (test_json_round_trip)
> ???
pydantic/main.py:539:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
pydantic/parse.py:37:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
data = {'forcefield_file': 'note.xml', 'forcefield_settings': {'author': 'The Open Force Field Initiative', 'date': '2021-08-...1', 'solute_dielectric': 1.0, 'solvent_dielectric': 78.5}, ...}, 'protocol_settings': None, 'settings_version': 0, ...}
def json_loader(data: str) -> dict:
"""Load JSON containing custom unit-tagged quantities."""
# TODO: recursively call this function for nested models
> out: Dict = json.loads(data)
../../../../miniconda3/envs/openfe/lib/python3.9/site-packages/openff/models/types.py:127:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
s = {'forcefield_file': 'note.xml', 'forcefield_settings': {'author': 'The Open Force Field Initiative', 'date': '2021-08-...1', 'solute_dielectric': 1.0, 'solvent_dielectric': 78.5}, ...}, 'protocol_settings': None, 'settings_version': 0, ...}
cls = None, object_hook = None, parse_float = None, parse_int = None
parse_constant = None, object_pairs_hook = None, kw = {}
def loads(s, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
"""Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
containing a JSON document) to a Python object.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``object_pairs_hook`` is an optional function that will be called with the
result of any object literal decoded with an ordered list of pairs. The
return value of ``object_pairs_hook`` will be used instead of the ``dict``.
This feature can be used to implement custom decoders. If ``object_hook``
is also defined, the ``object_pairs_hook`` takes priority.
``parse_float``, if specified, will be called with the string
of every JSON float to be decoded. By default this is equivalent to
float(num_str). This can be used to use another datatype or parser
for JSON floats (e.g. decimal.Decimal).
``parse_int``, if specified, will be called with the string
of every JSON int to be decoded. By default this is equivalent to
int(num_str). This can be used to use another datatype or parser
for JSON integers (e.g. float).
``parse_constant``, if specified, will be called with one of the
following strings: -Infinity, Infinity, NaN.
This can be used to raise an exception if invalid JSON numbers
are encountered.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg; otherwise ``JSONDecoder`` is used.
"""
if isinstance(s, str):
if s.startswith('\ufeff'):
raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
s, 0)
else:
if not isinstance(s, (bytes, bytearray)):
> raise TypeError(f'the JSON object must be str, bytes or bytearray, '
f'not {s.__class__.__name__}')
E TypeError: the JSON object must be str, bytes or bytearray, not dict
../../../../miniconda3/envs/openfe/lib/python3.9/json/__init__.py:339: TypeError
During handling of the above exception, another exception occurred:
all_settings_path = '/home/richard/code/gufe/gufe/tests/data/all_settings.json'
tmp_path = PosixPath('/tmp/pytest-of-richard/pytest-3/test_json_round_trip0')
def test_json_round_trip(all_settings_path, tmp_path):
with open(all_settings_path) as fd:
settings = Settings.parse_raw(fd.read())
assert settings == Settings(**settings.dict())
d = tmp_path / "test"
d.mkdir()
with open(d / "settings.json", "w") as fd:
fd.write(settings.json())
with open(d / "settings.json") as fd:
settings_from_file = json.load(fd)
> assert settings == Settings.parse_raw(settings_from_file)
test_models.py:30:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E pydantic.error_wrappers.ValidationError: 1 validation error for Settings
E __root__
E the JSON object must be str, bytes or bytearray, not dict (type=type_error)
pydantic/main.py:548: ValidationError