ModECI / modelspec

Functionality for specifying models & enabling automatic serialization - will be used by MDF & NeuroMLlite
https://modeci.github.io/modelspec/
Apache License 2.0
3 stars 9 forks source link

Latest cattrs (v23.2.2) breaks json export (issue with serialising ndarray) #66

Open pgleeson opened 10 months ago

pgleeson commented 10 months ago
tests/test_base.py::test_ndarray_json_metadata
FAILED

================================================================================================================================ FAILURES ================================================================================================================================
_______________________________________________________________________________________________________________________ test_ndarray_json_metadata _______________________________________________________________________________________________________________________

    def test_ndarray_json_metadata():
        import numpy as np

        @modelspec.define(eq=False)
        class Node(Base):
            id: str = field(validator=instance_of(str))
            metadata: Optional[Dict[str, Any]] = field(
                kw_only=True, default=None, validator=optional(instance_of(dict))
            )

        model = Node(id="a", metadata={"b": np.array([0])})
>       model.to_json()

tests/test_base.py:354: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python3.10/dist-packages/modelspec/base_types.py:113: in to_json
    return json.dumps(self.to_dict(), indent=4)
/usr/lib/python3.10/json/__init__.py:238: in dumps
    **kw).encode(obj)
/usr/lib/python3.10/json/encoder.py:201: in encode
    chunks = list(chunks)
/usr/lib/python3.10/json/encoder.py:431: in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
/usr/lib/python3.10/json/encoder.py:405: in _iterencode_dict
    yield from chunks
/usr/lib/python3.10/json/encoder.py:405: in _iterencode_dict
    yield from chunks
/usr/lib/python3.10/json/encoder.py:405: in _iterencode_dict
    yield from chunks
/usr/lib/python3.10/json/encoder.py:438: in _iterencode
    o = _default(o)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <json.encoder.JSONEncoder object at 0xffff834542b0>, o = array([0])

    def default(self, o):
        """Implement this method in a subclass such that it returns
        a serializable object for ``o``, or calls the base implementation
        (to raise a ``TypeError``).

        For example, to support arbitrary iterators, you could
        implement default like this::

            def default(self, o):
                try:
                    iterable = iter(o)
                except TypeError:
                    pass
                else:
                    return list(iterable)
                # Let the base class default method raise the TypeError
                return JSONEncoder.default(self, o)

        """
>       raise TypeError(f'Object of type {o.__class__.__name__} '
                        f'is not JSON serializable')
E       TypeError: Object of type ndarray is not JSON serializable

/usr/lib/python3.10/json/encoder.py:179: TypeError
======================================================================================================================== short test summary info =========================================================================================================================
FAILED tests/test_base.py::test_ndarray_json_metadata - TypeError: Object of type ndarray is not JSON serializable

Looking into this @davidt0x...

pgleeson commented 10 months ago

Example of fail: https://github.com/ModECI/modelspec/actions/runs/6959928427/job/18938282812.

Fixed when pinned: https://github.com/ModECI/modelspec/commit/dbb32226b3b7452dadeaf79ae1a31deee7a6f186

pgleeson commented 10 months ago

Possibly related to this?

https://github.com/ModECI/modelspec/blob/dbb32226b3b7452dadeaf79ae1a31deee7a6f186/src/modelspec/base_types.py#L970-L976

pgleeson commented 9 months ago

Fixed in latest cattrs: https://github.com/python-attrs/cattrs/releases/tag/v23.2.3