mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
ifcdiff: fix crash when exporting property diffs to JSON
DeepDiff's dictionary_item_added/set_item_added results are a deepdiff.helper.SetOrdered instance, which subclasses orderly_set's StableSetEq rather than the OrderedSet class json_dump_default checked for, so the property relationship check always crashed export() with "Object of type SetOrdered is not JSON serializable". Check against StableSet, the common base class shared by every orderly_set set flavour, instead. Fixes #8905 Generated with the assistance of an AI coding tool.
This commit is contained in:
committed by
Dion Moult
parent
2f1b2f9638
commit
fbe36532a0
@@ -36,7 +36,7 @@ import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.selector
|
||||
import numpy as np
|
||||
from deepdiff import DeepDiff
|
||||
from orderly_set import OrderedSet
|
||||
from orderly_set import StableSet
|
||||
|
||||
__version__ = version = "0.0.0"
|
||||
|
||||
@@ -257,7 +257,7 @@ class IfcDiff:
|
||||
|
||||
def json_dump_default(self, obj):
|
||||
# result of DeepDiff may contain ordered sets
|
||||
if isinstance(obj, (OrderedSet, set)):
|
||||
if isinstance(obj, (StableSet, set)):
|
||||
return list(obj)
|
||||
return json.JSONEncoder.default(None, obj)
|
||||
|
||||
|
||||
@@ -16,9 +16,14 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.unit
|
||||
import ifcopenshell.util.representation
|
||||
@@ -94,6 +99,29 @@ class TestIfcDiff:
|
||||
assert ifc_diff.deleted_elements == set()
|
||||
assert ifc_diff.change_register == {wall.GlobalId: {"attributes_changed": True}}
|
||||
|
||||
def test_property_diff_exports_to_json(self):
|
||||
# Regression test for #8905: comparing "property" relationships makes
|
||||
# DeepDiff report a dictionary_item_added as a SetOrdered, which
|
||||
# json.dump couldn't serialise, crashing export() with no results.
|
||||
ifc_file = setup_project()
|
||||
wall = ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcWall", name="Foo")
|
||||
|
||||
new_file = ifc_file.from_string(ifc_file.to_string())
|
||||
wall_new = new_file.by_id(wall.id())
|
||||
pset = ifcopenshell.api.pset.add_pset(new_file, product=wall_new, name="Pset_WallCommon")
|
||||
ifcopenshell.api.pset.edit_pset(new_file, pset=pset, properties={"FireRating": "2HR"})
|
||||
|
||||
ifc_diff = ifcdiff.IfcDiff(ifc_file, new_file, relationships=["property"])
|
||||
ifc_diff.diff()
|
||||
assert ifc_diff.change_register[wall.GlobalId]["properties_changed"]
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
output = os.path.join(tmp_dir, "diff.json")
|
||||
ifc_diff.export(output)
|
||||
with open(output) as f:
|
||||
results = json.load(f)
|
||||
assert "Pset_WallCommon" in str(results["changed"][wall.GlobalId]["properties_changed"])
|
||||
|
||||
def test_changed_geometry(self):
|
||||
ifc_file = setup_project()
|
||||
wall = ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcWall", name="Foo")
|
||||
|
||||
Reference in New Issue
Block a user