diff --git a/src/ifcopenshell-python/ifcopenshell/express/rule_compiler.py b/src/ifcopenshell-python/ifcopenshell/express/rule_compiler.py index ab6caf93f8..545d68c50a 100644 --- a/src/ifcopenshell-python/ifcopenshell/express/rule_compiler.py +++ b/src/ifcopenshell-python/ifcopenshell/express/rule_compiler.py @@ -738,7 +738,7 @@ class AttributeGetattrTransformer(ast.NodeTransformer): while n := getattr(n, "parent", 0): parents.append(n) - custom_funcs = "is_entity", "usedin", "express_len", "express_getitem", "typeof" + custom_funcs = "is_entity", "usedin", "express_len", "express_getitem", "typeof", "express_getattr" function_defs = [p.name for p in parents if isinstance(p, ast.FunctionDef)] if any(fn in function_defs for fn in custom_funcs): return node @@ -755,7 +755,7 @@ class AttributeGetattrTransformer(ast.NodeTransformer): # Replace the Attribute node with a call to the built-in `getattr` function return ast.copy_location( ast.Call( - func=ast.Name(id="getattr", ctx=ast.Load()), + func=ast.Name(id="express_getattr", ctx=ast.Load()), args=[ new_value, ast.Str(s=node.attr), @@ -772,7 +772,7 @@ class AttributeGetattrTransformer(ast.NodeTransformer): while n := getattr(n, "parent", 0): parents.append(n) - custom_funcs = "is_entity", "usedin", "express_len", "express_getitem", "typeof" + custom_funcs = "is_entity", "usedin", "express_len", "express_getitem", "typeof", "express_getattr" function_defs = [p.name for p in parents if isinstance(p, ast.FunctionDef)] if any(fn in function_defs for fn in custom_funcs): return node @@ -937,6 +937,14 @@ def express_getitem(aggr, idx, default): except IndexError as e: return None +def express_getattr(aggr, name, default): + v = getattr(aggr, name, default) + if v is None: + return default + else: + return v + + EXPRESS_ONE_BASED_INDEXING = 1 diff --git a/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py b/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py index 0bf8ac439c..9201e480be 100644 --- a/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py +++ b/src/ifcopenshell-python/ifcopenshell/express/rule_executor.py @@ -9,7 +9,7 @@ from codegen import indent def reverse_compile(s): - return re.sub( + return re.sub(r'\bself\b', 'SELF', re.sub( r"\s*\-\s*EXPRESS_ONE_BASED_INDEXING", "", re.sub( @@ -22,11 +22,11 @@ def reverse_compile(s): .replace("len(", "SIZEOF(") .replace("assert ", "") .replace(" is not False", "") - .replace("getattr(", "") + .replace("express_getattr(", "") .replace("express_getitem(", ""), )[::-1], )[::-1], - ) + )) @dataclass