ifcwrap: rename geometry backref helper to fix stub validation crash

The #1124 fix (824c1fc280) named its pythoncode backref helper
`_geometry_with_backref` with a leading underscore. validate_stub.py's
get_function_node_name() skips any leading-underscore name (its only
exception is `_is`), so the helper never gets added to the parsed
`subnames` set. When get_names_tree_lines() later processes
`geometry = property(_geometry_with_backref)`, find_method_by_name()
can't find the backing function and the `assert (wrapped_function :=
find_method_by_name(arg))` at validate_stub.py:154 raises AssertionError
instead of the expected clean stub/wrapper diff, crashing the CI
`ci.yml` -> compile-and-test -> "Test ifcopenshell-python" step
(`make test-parallel`) on every push since 824c1fc280.

Renaming to `geometry_with_backref_` (trailing underscore) matches the
existing local convention in the same class bodies for backing-
implementation helpers (calc_volume_, calc_surface_area_), which
validate_stub.py's heuristic already handles correctly.

Also add the six new SVG edge-classification settings-flag classes
(SvgEmitFlushEdges, SvgRenderCreaseEdges, SvgRenderSharpEdges,
SvgRidgeAngleMinDegrees, SvgUseEdgeClassification,
SvgValleyAngleMinDegrees) to ifcopenshell_wrapper.pyi. These were added
to the C++/SWIG side by the SVG edge classification commits but never
synced to the stub, and validate_stub would report them as a
stub/wrapper discrepancy once the crash above is fixed.

Reproduced by building ifcopenshell against the exact CI-tested commit
(c68e4a0eee) with SWIG 4.1.0 (matching ci.yml's pinned build-from-source
version) and running validate_stub.py's actual logic against the
generated ifcopenshell_wrapper.py: crashed identically to the CI log
before this change, passed cleanly after. test/util/scripts/test_validate_stub.py::TestValidateStub::test_run
passes against the rebuilt wrapper.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Petru Conduraru
2026-07-19 15:35:21 +03:00
parent 98a25eca96
commit e57b5ac5ed
2 changed files with 36 additions and 6 deletions
@@ -484,6 +484,26 @@ class Settings:
def set_(self, *args): ...
def setting_names(self): ...
class SvgEmitFlushEdges:
defaultvalue: Any
description: Any
name: Any
class SvgRenderCreaseEdges:
defaultvalue: Any
description: Any
name: Any
class SvgRenderSharpEdges:
defaultvalue: Any
description: Any
name: Any
class SvgRidgeAngleMinDegrees:
defaultvalue: Any
description: Any
name: Any
class SvgSerializer(WriteOnlyGeometrySerializer):
def __init__(self, out_filename, geometry_settings, settings, logger=None): ...
SH_NONE: Any
@@ -548,6 +568,16 @@ class SvgSerializer(WriteOnlyGeometrySerializer):
def write(self, *args): ...
def writeHeader(self): ...
class SvgUseEdgeClassification:
defaultvalue: Any
description: Any
name: Any
class SvgValleyAngleMinDegrees:
defaultvalue: Any
description: Any
name: Any
class SwigPyIterator:
def __init__(self, *args, **kwargs): ...
def advance(self, n): ...
+6 -6
View File
@@ -794,11 +794,11 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
%pythoncode %{
# Hide the getters with read-only property implementations
# Keep the owning element alive while its geometry is referenced (#1124).
def _geometry_with_backref(self, _f=geometry):
def geometry_with_backref_(self, _f=geometry):
result = _f(self)
result._parent = self
return result
geometry = property(_geometry_with_backref)
geometry = property(geometry_with_backref_)
%}
};
@@ -806,11 +806,11 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
%pythoncode %{
# Hide the getters with read-only property implementations
# Keep the owning element alive while its geometry is referenced (#1124).
def _geometry_with_backref(self, _f=geometry):
def geometry_with_backref_(self, _f=geometry):
result = _f(self)
result._parent = self
return result
geometry = property(_geometry_with_backref)
geometry = property(geometry_with_backref_)
%}
};
@@ -836,11 +836,11 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
%pythoncode %{
# Hide the getters with read-only property implementations
# Keep the owning element alive while its geometry is referenced (#1124).
def _geometry_with_backref(self, _f=geometry):
def geometry_with_backref_(self, _f=geometry):
result = _f(self)
result._parent = self
return result
geometry = property(_geometry_with_backref)
geometry = property(geometry_with_backref_)
volume = property(calc_volume_)
surface_area = property(calc_surface_area_)
%}