diff --git a/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py b/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py index 9201e480be..68240aeddd 100644 --- a/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py +++ b/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py @@ -9,24 +9,28 @@ from codegen import indent def reverse_compile(s): - return re.sub(r'\bself\b', 'SELF', re.sub( - r"\s*\-\s*EXPRESS_ONE_BASED_INDEXING", - "", + return re.sub( + r"\bself\b", + "SELF", re.sub( - ", )?+.(, INDETERMINATE)\\"[::-1], - "]\\1[", + r"\s*\-\s*EXPRESS_ONE_BASED_INDEXING", + "", re.sub( - r", '(\w+)', INDETERMINATE\)", - ".\\1", - s.strip() - .replace("len(", "SIZEOF(") - .replace("assert ", "") - .replace(" is not False", "") - .replace("express_getattr(", "") - .replace("express_getitem(", ""), + ", )?+.(, INDETERMINATE)\\"[::-1], + "]\\1[", + re.sub( + r", '(\w+)', INDETERMINATE\)", + ".\\1", + s.strip() + .replace("len(", "SIZEOF(") + .replace("assert ", "") + .replace(" is not False", "") + .replace("express_getattr(", "") + .replace("express_getitem(", ""), + )[::-1], )[::-1], - )[::-1], - )) + ), + ) @dataclass @@ -68,9 +72,13 @@ def run(f: ifcopenshell.file, logger: Logger) -> None: if hasattr(logger, "set_instance"): # when using the json logger, we notify it of the relevant instance - pre_annotate_instance = lambda instance: logger.set_state('instance', instance) if hasattr(logger, 'set_state') else None + pre_annotate_instance = lambda instance: ( + logger.set_state("instance", instance) if hasattr(logger, "set_state") else None + ) post_annotate_instance = lambda instance: instance - pre_annotate_attribute = lambda attribute: logger.set_state('attribute', attribute) if hasattr(logger, 'set_state') else None + pre_annotate_attribute = lambda attribute: ( + logger.set_state("attribute", attribute) if hasattr(logger, "set_state") else None + ) post_annotate_attribute = lambda attribute: None else: # when using the normal text logger the instance is appended to the method @@ -90,13 +98,13 @@ def run(f: ifcopenshell.file, logger: Logger) -> None: import time import subprocess - current_dir_files = {fn.lower(): fn for fn in os.listdir('.')} - schema_name = str(f.schema_identifier).split(' ')[-1].lower() - schema_path = current_dir_files.get(schema_name + '.exp') - fn = schema_path[:-4] + '.py' + current_dir_files = {fn.lower(): fn for fn in os.listdir(".")} + schema_name = str(f.schema_identifier).split(" ")[-1].lower() + schema_path = current_dir_files.get(schema_name + ".exp") + fn = schema_path[:-4] + ".py" if not os.path.exists(fn): subprocess.run([sys.executable, "-m", "ifcopenshell.express.rule_compiler", schema_path, fn], check=True) - time.sleep(1.) + time.sleep(1.0) source = open(fn, "r").read() a = ast.parse(source) @@ -108,12 +116,14 @@ def run(f: ifcopenshell.file, logger: Logger) -> None: rules = list(filter(lambda x: hasattr(x, "SCOPE"), scope.values())) - if hasattr(logger, 'set_state'): - logger.set_state('type', 'global_rule') + if hasattr(logger, "set_state"): + logger.set_state("type", "global_rule") for R in [r for r in rules if r.SCOPE == "file"]: try: R()(f) + except RecursionError as e: + logger.info(str(e)) except Exception as e: ln = e.__traceback__.tb_next.tb_lineno pre_annotate_attribute(R.__name__) @@ -127,17 +137,15 @@ def run(f: ifcopenshell.file, logger: Logger) -> None: ) ) - if hasattr(logger, 'set_state'): - logger.set_state('type', 'simpletype_rule') + if hasattr(logger, "set_state"): + logger.set_state("type", "simpletype_rule") types = {} subtypes = collections.defaultdict(list) for d in S.declarations(): if isinstance(d, ifcopenshell.ifcopenshell_wrapper.type_declaration): types[d.name()] = d - if isinstance( - d.declared_type(), ifcopenshell.ifcopenshell_wrapper.named_type - ): + if isinstance(d.declared_type(), ifcopenshell.ifcopenshell_wrapper.named_type): subtypes[d.declared_type().declared_type().name()].append(d.name()) D = collections.defaultdict(list) @@ -170,6 +178,8 @@ def run(f: ifcopenshell.file, logger: Logger) -> None: for R in D[type_name(type)]: try: R()(fix_type(value)) + except RecursionError as e: + logger.info(str(e)) except Exception as e: ln = e.__traceback__.tb_next.tb_lineno pre_annotate_instance(instance) @@ -220,6 +230,8 @@ def run(f: ifcopenshell.file, logger: Logger) -> None: for inst in f: try: values = list(inst) + except RecursionError as e: + logger.info(str(e)) except Exception as e: if hasattr(logger, "set_state"): logger.error(str(e)) @@ -228,22 +240,22 @@ def run(f: ifcopenshell.file, logger: Logger) -> None: continue entity = S.declaration_by_name(inst.is_a()) attrs = entity.all_attributes() - for i, (attr, val, is_derived) in enumerate( - zip(attrs, values, entity.derived()) - ): + for i, (attr, val, is_derived) in enumerate(zip(attrs, values, entity.derived())): if is_derived: # @todo pass else: check(val, attr.type_of_attribute(), instance=inst) - if hasattr(logger, 'set_state'): - logger.set_state('type', 'entity_rule') + if hasattr(logger, "set_state"): + logger.set_state("type", "entity_rule") for R in [r for r in rules if r.SCOPE == "entity"]: for inst in f.by_type(R.TYPE_NAME): try: R()(inst) + except RecursionError as e: + logger.info(str(e)) except Exception as e: ln = e.__traceback__.tb_next.tb_lineno pre_annotate_instance(inst)