mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
black ifcopenshell-python
This commit is contained in:
@@ -8,31 +8,34 @@ from collections import namedtuple
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
named_type = ifcopenshell.ifcopenshell_wrapper.named_type
|
||||
named_type = ifcopenshell.ifcopenshell_wrapper.named_type
|
||||
aggregation_type = ifcopenshell.ifcopenshell_wrapper.aggregation_type
|
||||
simple_type = ifcopenshell.ifcopenshell_wrapper.simple_type
|
||||
simple_type = ifcopenshell.ifcopenshell_wrapper.simple_type
|
||||
type_declaration = ifcopenshell.ifcopenshell_wrapper.type_declaration
|
||||
enumeration_type = ifcopenshell.ifcopenshell_wrapper.enumeration_type
|
||||
entity_type = ifcopenshell.ifcopenshell_wrapper.entity
|
||||
select_type = ifcopenshell.ifcopenshell_wrapper.select_type
|
||||
attribute = ifcopenshell.ifcopenshell_wrapper.attribute
|
||||
entity_type = ifcopenshell.ifcopenshell_wrapper.entity
|
||||
select_type = ifcopenshell.ifcopenshell_wrapper.select_type
|
||||
attribute = ifcopenshell.ifcopenshell_wrapper.attribute
|
||||
|
||||
class ValidationError(Exception): pass
|
||||
|
||||
log_entry_type = namedtuple('log_entry_type', ("level", "message", "instance"))
|
||||
class ValidationError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
log_entry_type = namedtuple("log_entry_type", ("level", "message", "instance"))
|
||||
|
||||
|
||||
class json_logger:
|
||||
|
||||
def __init__(self):
|
||||
self.statements = []
|
||||
self.instance = None
|
||||
|
||||
|
||||
def set_instance(self, instance):
|
||||
self.instance = instance
|
||||
|
||||
|
||||
def log(self, level, message, instance):
|
||||
self.statements.append(log_entry_type(level, message, instance)._asdict())
|
||||
|
||||
|
||||
def __getattr__(self, level):
|
||||
return functools.partial(self.log, level, instance=self.instance)
|
||||
|
||||
@@ -44,10 +47,11 @@ simple_type_python_mapping = {
|
||||
"real": float,
|
||||
"number": float,
|
||||
"boolean": bool,
|
||||
"logical": bool, # still not implemented in IfcOpenShell
|
||||
"binary": str # maps to a str of "0" and "1"
|
||||
"logical": bool, # still not implemented in IfcOpenShell
|
||||
"binary": str, # maps to a str of "0" and "1"
|
||||
}
|
||||
|
||||
|
||||
def assert_valid_inverse(attr, val):
|
||||
b1, b2 = attr.bound1(), attr.bound2()
|
||||
invalid = len(val) < b1 or (b2 != -1 and len(val) > b2)
|
||||
@@ -55,24 +59,25 @@ def assert_valid_inverse(attr, val):
|
||||
raise ValidationError("%r not valid for %s" % (val, attr))
|
||||
return True
|
||||
|
||||
|
||||
def assert_valid(attr, val):
|
||||
if isinstance(attr, attribute):
|
||||
attr_type = attr.type_of_attribute()
|
||||
else:
|
||||
attr_type = attr
|
||||
|
||||
|
||||
type_wrappers = (named_type,)
|
||||
if not isinstance(val, ifcopenshell.entity_instance):
|
||||
# If val is not an entity instance we need to
|
||||
# If val is not an entity instance we need to
|
||||
# flatten the type declaration to something that
|
||||
# maps to the python types
|
||||
type_wrappers += (type_declaration,)
|
||||
|
||||
type_wrappers += (type_declaration,)
|
||||
|
||||
while isinstance(attr_type, type_wrappers):
|
||||
attr_type = attr_type.declared_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)):
|
||||
invalid = not isinstance(val, ifcopenshell.entity_instance) or not val.is_a(attr_type.name())
|
||||
elif isinstance(attr_type, select_type):
|
||||
@@ -85,77 +90,79 @@ def assert_valid(attr, val):
|
||||
invalid = len(val) < b1 or (b2 != -1 and len(val) > b2) or not all(assert_valid(ty, v) for v in val)
|
||||
else:
|
||||
raise NotImplementedError("Not impl %s %s" % (type(attr_type), attr_type))
|
||||
|
||||
|
||||
if invalid:
|
||||
raise ValidationError("%r not valid for %s" % (val, attr))
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def try_valid(attr, val):
|
||||
try:
|
||||
return assert_valid(attr, val)
|
||||
except ValidationError as e:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def validate(f, logger):
|
||||
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(f.schema)
|
||||
for inst in f:
|
||||
if hasattr(logger, 'set_instance'):
|
||||
if hasattr(logger, "set_instance"):
|
||||
logger.set_instance(inst)
|
||||
|
||||
|
||||
entity = schema.declaration_by_name(inst.is_a())
|
||||
|
||||
|
||||
if entity.is_abstract():
|
||||
e = "Entity %s is abstract" % entity.name()
|
||||
if hasattr(logger, 'set_instance'):
|
||||
if hasattr(logger, "set_instance"):
|
||||
logger.error(e)
|
||||
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()):
|
||||
|
||||
|
||||
if val is None and not (is_derived or attr.optional()):
|
||||
logger.error("Attribute %s.%s not optional", entity, attr)
|
||||
logger.error("Attribute %s.%s not optional", entity, attr)
|
||||
|
||||
if val is not None:
|
||||
attr_type = attr.type_of_attribute()
|
||||
try:
|
||||
try:
|
||||
assert_valid(attr, val)
|
||||
except ValidationError as e:
|
||||
if hasattr(logger, 'set_instance'):
|
||||
if hasattr(logger, "set_instance"):
|
||||
logger.error(str(e))
|
||||
else:
|
||||
logger.error('In %s\n%s', inst, e)
|
||||
|
||||
logger.error("In %s\n%s", inst, e)
|
||||
|
||||
for attr in entity.all_inverse_attributes():
|
||||
val = getattr(inst, attr.name())
|
||||
try:
|
||||
assert_valid_inverse(attr, val)
|
||||
except ValidationError as e:
|
||||
if hasattr(logger, 'set_instance'):
|
||||
if hasattr(logger, "set_instance"):
|
||||
logger.error(str(e))
|
||||
else:
|
||||
logger.error('In %s\n%s', inst, e)
|
||||
logger.error("In %s\n%s", inst, e)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
import logging
|
||||
|
||||
filenames = [x for x in sys.argv[1:] if not x.startswith('--')]
|
||||
flags = set(x for x in sys.argv[1:] if x.startswith('--'))
|
||||
|
||||
|
||||
filenames = [x for x in sys.argv[1:] if not x.startswith("--")]
|
||||
flags = set(x for x in sys.argv[1:] if x.startswith("--"))
|
||||
|
||||
for fn in filenames:
|
||||
if '--json' in flags:
|
||||
if "--json" in flags:
|
||||
logger = json_logger()
|
||||
else:
|
||||
logger = logging.getLogger('validate')
|
||||
logger = logging.getLogger("validate")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
f = ifcopenshell.open(fn)
|
||||
|
||||
|
||||
print("Validating", fn, file=sys.stderr)
|
||||
validate(f, logger)
|
||||
|
||||
if '--json' in flags:
|
||||
|
||||
if "--json" in flags:
|
||||
print("\n".join(json.dumps(x, default=str) for x in logger.statements))
|
||||
|
||||
Reference in New Issue
Block a user