diff --git a/src/ifcopenshell-python/ifcopenshell/express/rule_compiler.py b/src/ifcopenshell-python/ifcopenshell/express/rule_compiler.py index 7a39bcb3ac..e844c8d605 100644 --- a/src/ifcopenshell-python/ifcopenshell/express/rule_compiler.py +++ b/src/ifcopenshell-python/ifcopenshell/express/rule_compiler.py @@ -444,6 +444,7 @@ def process_expression(context): break_points[-1].append(len(args)) + # @todo don't depend on registered schema S = ifcopenshell.ifcopenshell_wrapper.schema_by_name(schema.name) entity = S.declaration_by_name(typename) entity_attributes = entity.attributes() @@ -806,7 +807,26 @@ if __name__ == "__main__": import subprocess schema = ifcopenshell.express.express_parser.parse(sys.argv[1]).schema - ofn = os.path.join(os.path.dirname(__file__), "rules", f"{schema.name}.py") + + try: + ifcopenshell.ifcopenshell_wrapper.schema_by_name(schema.name) + except: + # @nb note the difference here between: + # + # - ifcopenshell.express.express_parser.parse + # - ifcopenshell.express.parse.parse + # + # First generates a pyparsing AST + # + # Second populates a latebound schema + # that can be registered in C++. + builder = ifcopenshell.express.parse(sys.argv[1]) + ifcopenshell.register_schema(builder) + + try: + ofn = sys.argv[2] + except IndexError as e: + ofn = os.path.join(os.path.dirname(__file__), "rules", f"{schema.name}.py") output = io.StringIO() print("import ifcopenshell", file=output, sep="\n") @@ -1025,5 +1045,8 @@ INDETERMINATE = indeterminate_type() trsf.assign_parent_refs(tree) trsf.visit(tree) - with open(ofn, "w") as f: - f.write(ast.unparse(tree)) + if ofn == "-": + print(ast.unparse(tree)) + else: + with open(ofn, "w") as f: + f.write(ast.unparse(tree)) diff --git a/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py b/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py index e73e31707b..0bd9bb5501 100644 --- a/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py +++ b/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py @@ -82,7 +82,22 @@ def run(f, logger): ifcopenshell.settings.unpack_non_aggregate_inverses = True fn = os.path.join(os.path.dirname(__file__), "rules", f"{f.schema}.py") - source = open(fn, "r").read() + try: + source = open(fn, "r").read() + except FileNotFoundError as e: + import sys + import time + import subprocess + + current_dir_files = {fn.lower(): fn for fn in os.listdir('.')} + schema_name = str(f.schema).split(' ')[-1].lower() + schema_path = current_dir_files.get(schema_name + '.exp') + fn = schema_name + '.py' + if not os.path.exists(fn): + subprocess.run([sys.executable, "-m", "ifcopenshell.express.rule_compiler", schema_path, fn], check=True) + time.sleep(1.) + source = open(fn, "r").read() + a = ast.parse(source) assertion.rewrite.rewrite_asserts(mod=a, source=source) cd = compile(a, f"{f.schema}.py", "exec")