From 76cbb79c75f8564474db27bafc55cba3a9f4d605 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 17 Jun 2015 19:46:11 +0000 Subject: [PATCH] Correctly wrap arbitrarily nested aggregates of entity instance attributes in IfcOpenShell-Python --- .../ifcopenshell/__init__.py | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/__init__.py b/src/ifcopenshell-python/ifcopenshell/__init__.py index 4912860fb3..e9f3ff8dde 100644 --- a/src/ifcopenshell-python/ifcopenshell/__init__.py +++ b/src/ifcopenshell-python/ifcopenshell/__init__.py @@ -51,16 +51,20 @@ class entity_instance(object): return entity_instance.wrap_value(self.wrapped_data.get_inverse(name)) else: raise AttributeError("entity instance of type '%s' has no attribute '%s'"%(self.wrapped_data.is_a(), name)) @staticmethod + def walk(f, g, value): + if isinstance(value, (tuple, list)): return tuple(map(functools.partial(entity_instance.walk, f, g), value)) + elif f(value): return g(value) + else: return value + @staticmethod def wrap_value(v): wrap = lambda e: entity_instance(e) - if isinstance(v, ifcopenshell_wrapper.entity_instance): return wrap(v) - elif isinstance(v, (tuple, list)) and len(v): - classes = set(map(type, v)) - if {ifcopenshell_wrapper.entity_instance} == classes: return list(map(wrap, v)) - elif {list} == classes: - classes = set(map(type, v[0])) - if {ifcopenshell_wrapper.entity_instance} == classes: return [list(map(wrap, x)) for x in v] - return v + is_instance = lambda e: isinstance(e, ifcopenshell_wrapper.entity_instance) + return entity_instance.walk(is_instance, wrap, v) + @staticmethod + def unwrap_value(v): + unwrap = lambda e: e.wrapped_data + is_instance = lambda e: isinstance(e, entity_instance) + return entity_instance.walk(is_instance, unwrap, v) def attribute_type(self, attr): attr_idx = attr if isinstance(attr, int) else self.wrapped_data.get_argument_index(attr) return self.wrapped_data.get_argument_type(attr_idx) @@ -74,7 +78,7 @@ class entity_instance(object): attr_type = self.attribute_type(idx).title().replace(' ', '') attr_type = attr_type.replace('Binary', 'String') attr_type = attr_type.replace('Enumeration', 'String') - getattr(self.wrapped_data, "setArgumentAs%s" % attr_type)(idx, value) + getattr(self.wrapped_data, "setArgumentAs%s" % attr_type)(idx, entity_instance.unwrap_value(value)) def __len__(self): return len(self.wrapped_data) def __repr__(self): return repr(self.wrapped_data) def is_a(self, *args): return self.wrapped_data.is_a(*args)