mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 14:33:28 +00:00
Validate instance attribute values by catching exceptions
This commit is contained in:
@@ -34,7 +34,9 @@ class json_logger:
|
|||||||
self.instance = instance
|
self.instance = instance
|
||||||
|
|
||||||
def log(self, level, message, *args, **kwargs):
|
def log(self, level, message, *args, **kwargs):
|
||||||
self.statements.append(log_entry_type(level, message % args, kwargs.get("instance"))._asdict())
|
self.statements.append(
|
||||||
|
log_entry_type(level, message % args, kwargs.get("instance"))._asdict()
|
||||||
|
)
|
||||||
|
|
||||||
def __getattr__(self, level):
|
def __getattr__(self, level):
|
||||||
return functools.partial(self.log, level, instance=self.instance)
|
return functools.partial(self.log, level, instance=self.instance)
|
||||||
@@ -81,7 +83,9 @@ def assert_valid(attr, val, schema):
|
|||||||
if isinstance(attr_type, simple_type):
|
if isinstance(attr_type, simple_type):
|
||||||
invalid = type(val) != simple_type_python_mapping[attr_type.declared_type()]
|
invalid = type(val) != simple_type_python_mapping[attr_type.declared_type()]
|
||||||
elif isinstance(attr_type, (entity_type, type_declaration)):
|
elif isinstance(attr_type, (entity_type, type_declaration)):
|
||||||
invalid = not isinstance(val, ifcopenshell.entity_instance) or not val.is_a(attr_type.name())
|
invalid = not isinstance(val, ifcopenshell.entity_instance) or not val.is_a(
|
||||||
|
attr_type.name()
|
||||||
|
)
|
||||||
elif isinstance(attr_type, select_type):
|
elif isinstance(attr_type, select_type):
|
||||||
val_to_use = val
|
val_to_use = val
|
||||||
if isinstance(schema.declaration_by_name(val.is_a()), enumeration_type):
|
if isinstance(schema.declaration_by_name(val.is_a()), enumeration_type):
|
||||||
@@ -90,13 +94,19 @@ def assert_valid(attr, val, schema):
|
|||||||
else:
|
else:
|
||||||
invalid = True
|
invalid = True
|
||||||
if not invalid:
|
if not invalid:
|
||||||
invalid = not any(try_valid(x, val_to_use, schema) for x in attr_type.select_list())
|
invalid = not any(
|
||||||
|
try_valid(x, val_to_use, schema) for x in attr_type.select_list()
|
||||||
|
)
|
||||||
elif isinstance(attr_type, enumeration_type):
|
elif isinstance(attr_type, enumeration_type):
|
||||||
invalid = val not in attr_type.enumeration_items()
|
invalid = val not in attr_type.enumeration_items()
|
||||||
elif isinstance(attr_type, aggregation_type):
|
elif isinstance(attr_type, aggregation_type):
|
||||||
b1, b2 = attr_type.bound1(), attr_type.bound2()
|
b1, b2 = attr_type.bound1(), attr_type.bound2()
|
||||||
ty = attr_type.type_of_element()
|
ty = attr_type.type_of_element()
|
||||||
invalid = len(val) < b1 or (b2 != -1 and len(val) > b2) or not all(assert_valid(ty, v, schema) for v in val)
|
invalid = (
|
||||||
|
len(val) < b1
|
||||||
|
or (b2 != -1 and len(val) > b2)
|
||||||
|
or not all(assert_valid(ty, v, schema) for v in val)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError("Not impl %s %s" % (type(attr_type), attr_type))
|
raise NotImplementedError("Not impl %s %s" % (type(attr_type), attr_type))
|
||||||
|
|
||||||
@@ -135,6 +145,7 @@ def validate(f, logger):
|
|||||||
logger.set_instance(inst)
|
logger.set_instance(inst)
|
||||||
|
|
||||||
entity = schema.declaration_by_name(inst.is_a())
|
entity = schema.declaration_by_name(inst.is_a())
|
||||||
|
attrs = entity.all_attributes()
|
||||||
|
|
||||||
if entity.is_abstract():
|
if entity.is_abstract():
|
||||||
e = "Entity %s is abstract" % entity.name()
|
e = "Entity %s is abstract" % entity.name()
|
||||||
@@ -143,20 +154,38 @@ def validate(f, logger):
|
|||||||
else:
|
else:
|
||||||
logger.error("In %s\n%s", inst, e)
|
logger.error("In %s\n%s", inst, e)
|
||||||
|
|
||||||
for attr, val, is_derived in zip(entity.all_attributes(), inst, entity.derived()):
|
has_invalid_value = False
|
||||||
|
for i in range(len(attrs)):
|
||||||
|
try:
|
||||||
|
inst[i]
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
if hasattr(logger, "set_instance"):
|
||||||
|
logger.error("Invalid attribute value for %s.%s", entity, attrs[i])
|
||||||
|
else:
|
||||||
|
logger.error(
|
||||||
|
"In %s\nInvalid attribute value for %s.%s",
|
||||||
|
inst,
|
||||||
|
entity,
|
||||||
|
attrs[i],
|
||||||
|
)
|
||||||
|
has_invalid_value = True
|
||||||
|
|
||||||
if val is None and not (is_derived or attr.optional()):
|
if not has_invalid_value:
|
||||||
logger.error("Attribute %s.%s not optional", entity, attr)
|
for attr, val, is_derived in zip(attrs, inst, entity.derived()):
|
||||||
|
|
||||||
if val is not None:
|
if val is None and not (is_derived or attr.optional()):
|
||||||
attr_type = attr.type_of_attribute()
|
logger.error("Attribute %s.%s not optional", entity, attr)
|
||||||
try:
|
|
||||||
assert_valid(attr, val, schema)
|
if val is not None:
|
||||||
except ValidationError as e:
|
attr_type = attr.type_of_attribute()
|
||||||
if hasattr(logger, "set_instance"):
|
try:
|
||||||
logger.error(str(e))
|
assert_valid(attr, val, schema)
|
||||||
else:
|
except ValidationError as e:
|
||||||
logger.error("In %s\n%s", inst, e)
|
if hasattr(logger, "set_instance"):
|
||||||
|
logger.error(str(e))
|
||||||
|
else:
|
||||||
|
logger.error("In %s\n%s", inst, e)
|
||||||
|
|
||||||
for attr in entity.all_inverse_attributes():
|
for attr in entity.all_inverse_attributes():
|
||||||
val = getattr(inst, attr.name())
|
val = getattr(inst, attr.name())
|
||||||
|
|||||||
Reference in New Issue
Block a user