Files
IfcOpenShell/src
Petru Conduraru 5d439f2729 Source UNIQUE-clause validation from express_parser (#4499 review)
Per review, do not hard-code the uniqueness rules. express_parser already
captures each entity's UNIQUE clauses (nodes.entity_definition.unique), but
they were dropped at codegen. Emit them, via the same pipeline that already
produces the WHERE rules, into the generated express/rules/<SCHEMA>.py
modules, and have validate read them from there so the data tracks the
EXPRESS schema.

- express/nodes.py: capture the full attribute list per UNIQUE clause
  (label, (attrs...)); previously only the first attribute was kept, which
  silently dropped compound clauses such as IfcApplication.UR2
  (ApplicationFullName, Version).
- express/rule_compiler.py: collect_uniqueness_rules / format_uniqueness_rules
  emit a uniqueness_rules dict into every generated rules module.
- express/rules/{IFC2X3,IFC4,IFC4X1,IFC4X2}.py: carry the generated dict.
- validate.py: get_uniqueness_rules reads it statically (ast, cached, no
  heavy import; graceful {} if absent) and validate_uniqueness_rules applies
  it generically. IfcRoot.UR1 and IfcApplication keep their dedicated paths
  to avoid double-reporting.

Verified: get_uniqueness_rules('IFC4') returns IfcApplication /
IfcPropertyEnumeration / IfcRoot from the rules module; a duplicate
IfcPropertyEnumeration name (IFC4) and IFC2X3 UR clauses are flagged, valid
files clean, no double-reporting. All test/test_validate.py fixtures (40)
pass; black and ruff clean.

Refs #4499. IFC4X3 variants gain the dict automatically on the next full
rules regeneration; validate no-ops gracefully until then.

Generated with the assistance of an AI coding tool.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 18:39:36 +03:00
..