Skip to content

Commit

Permalink
Fix bug in serialisation of AttributeView
Browse files Browse the repository at this point in the history
  • Loading branch information
tomvanmele committed Oct 17, 2024
1 parent 040a902 commit e34de35
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Fixed bug in `Box.scaled` causing a `TypeError` due to incorrect parameter forwarding.
* Changed argument names of `Box.scale()` to `x`, `y`, `z`, instead of `factor` and made `y` and `z` optional to keep positional arguments backwards compatible.
* Fixed import errors in `compas_rhino.conduits` for Rhino 8.
* Fixed bug in serialisation when `compas.datastructures.attributes.AttributeView` is used.

### Removed

Expand Down
4 changes: 4 additions & 0 deletions src/compas/data/encoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def default(self, o):
The serialized object.
"""
from compas.datastructures.attributes import AttributeView

if hasattr(o, "__jsondump__"):
return o.__jsondump__(minimal=DataEncoder.minimal)
Expand Down Expand Up @@ -153,6 +154,9 @@ def default(self, o):
if isinstance(o, (System.Decimal, System.Double, System.Single)):
return float(o)

if isinstance(o, AttributeView):
return dict(o)

Check warning on line 158 in src/compas/data/encoders.py

View check run for this annotation

Codecov / codecov/patch

src/compas/data/encoders.py#L157-L158

Added lines #L157 - L158 were not covered by tests

return super(DataEncoder, self).default(o)


Expand Down
36 changes: 29 additions & 7 deletions tests/compas/data/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ def test_json_native():

def test_json_primitive():
before = Point(0, 0, 0)
after = compas.json_loads(compas.json_dumps(before))
after = compas.json_loads(compas.json_dumps(before)) # type: Point
assert before.__dtype__ == after.__dtype__
assert all(a == b for a, b in zip(before, after))
assert before.guid == after.guid


def test_json_shape():
before = Box(frame=Frame(Point(0, 0, 0), Vector(1, 0, 0), Vector(0, 1, 0)), xsize=1, ysize=1, zsize=1)
after = compas.json_loads(compas.json_dumps(before))
after = compas.json_loads(compas.json_dumps(before)) # type: Box
assert before.__dtype__ == after.__dtype__
assert all(a == b for a, b in zip(before.to_vertices_and_faces()[0], after.to_vertices_and_faces()[0]))
assert before.guid == after.guid


def test_json_xform():
before = Transformation.from_frame_to_frame(Frame.worldXY(), Frame.worldXY())
after = compas.json_loads(compas.json_dumps(before))
after = compas.json_loads(compas.json_dumps(before)) # type: Transformation
assert before.__dtype__ == after.__dtype__
assert all(a == b for a, b in zip(before, after))
assert before.guid == after.guid
Expand All @@ -47,7 +47,7 @@ def test_json_graph():
a = before.add_node()
b = before.add_node()
before.add_edge(a, b)
after = compas.json_loads(compas.json_dumps(before))
after = compas.json_loads(compas.json_dumps(before)) # type: Graph
assert before.__dtype__ == after.__dtype__
# assert before.attributes == after.attributes
assert all(before.has_node(node) for node in after.nodes())
Expand All @@ -59,7 +59,7 @@ def test_json_graph():

def test_json_mesh():
before = Mesh.from_vertices_and_faces([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]], [[0, 1, 2, 3]])
after = compas.json_loads(compas.json_dumps(before))
after = compas.json_loads(compas.json_dumps(before)) # type: Mesh
assert before.__dtype__ == after.__dtype__
# assert before.attributes == after.attributes
assert all(before.has_vertex(vertex) for vertex in after.vertices())
Expand Down Expand Up @@ -95,7 +95,7 @@ def test_json_volmesh():
]
],
)
after = compas.json_loads(compas.json_dumps(before))
after = compas.json_loads(compas.json_dumps(before)) # type: VolMesh
assert before.__dtype__ == after.__dtype__
# assert before.attributes == after.attributes
assert all(before.has_vertex(vertex) for vertex in after.vertices())
Expand All @@ -121,12 +121,34 @@ def test_json_zip():

before = Box(frame=Frame(Point(0, 0, 0), Vector(1, 0, 0), Vector(0, 1, 0)), xsize=2, ysize=5, zsize=3)
compas.json_dumpz(before, zipfile_name)
after = compas.json_loadz(zipfile_name)
after = compas.json_loadz(zipfile_name) # type: Box
assert before.__dtype__ == after.__dtype__
assert all(a == b for a, b in zip(before.to_vertices_and_faces()[0], after.to_vertices_and_faces()[0]))
assert before.guid == after.guid


def test_json_attributeview():
mesh = Mesh.from_meshgrid(10, 10)
before = Mesh()
for vertex in mesh.vertices():
attr = mesh.vertex_attributes(vertex)
before.add_vertex(key=vertex, attr_dict=attr)
for face in mesh.faces():
attr = mesh.face_attributes(face)
before.add_face(vertices=mesh.face_vertices(face), fkey=face, attr_dict=attr)
after = compas.json_loads(compas.json_dumps(before)) # type: Mesh

assert before.__dtype__ == after.__dtype__
assert all(before.has_vertex(vertex) for vertex in after.vertices())
assert all(after.has_vertex(vertex) for vertex in before.vertices())
assert all(before.has_face(face) for face in after.faces())
assert all(after.has_face(face) for face in before.faces())
assert all(before.has_edge(edge) for edge in after.edges())
assert all(after.has_edge(edge) for edge in before.edges())
assert all(before.face_vertices(a) == after.face_vertices(b) for a, b in zip(before.faces(), after.faces()))
assert before.guid == after.guid


# temporarily commented because folder does not exist yet on main
# def test_json_url():
# data = compas.json_load('https://raw.githubusercontent.com/compas-dev/compas/main/src/compas/data/schemas/graph.json')
Expand Down

0 comments on commit e34de35

Please sign in to comment.