Description
NatLabRockies/OpenStudio-resources#230 (comment)
For eg ShadowCalculation.addShadingZoneGroup(ThermalZoneVector) no longer works with swig 4.4.0
From 3.11.0 to develop today (3.12.0-alpha), SWIG bumped from 4.1.1 → 4.4.0 (conanfile.py).
Python calls to at least two methods now fail with a TypeError, even when passing the "correct" *Vector wrapper type that used to work:
TypeError: in method 'ShadowCalculation_addShadingZoneGroup', argument 2 of type 'std::vector<openstudio::model::ThermalZone,...> const &'
TypeError: in method 'ShadingControl_addSubSurfaces', argument 2 of type 'std::vector<openstudio::model::SubSurface,...> const &'
Confirmed via a minimal repro (openstudio.model.ShadowCalculation().addShadingZoneGroup(...)) run against both /usr/local/openstudio-3.11.0 (SWIG 4.1.1, passes) and a 26.1.0 dev build (SWIG 4.4.0, fails) — same code, same OpenStudio Python API, only the SWIG version differs. Neither a ThermalZoneVector() wrapper nor a plain Python list works on the newer build; both worked (Vector) or failed the same way (list) on 3.11.0.
Current Behavior
No longer works.
Expected Behavior
Used to work at 3.11.0
Steps to reproduce
swig_vector_repro.py
openstudio swig_vector_repro.py
#!/usr/bin/env python3
"""
Minimal reproducer for the SWIG vector-argument TypeError seen in
shadowcalculation.rb when run against newer OpenStudio builds
(SWIG 4.1.1 -> 4.4.0 bump).
Pattern: build a ThermalZoneVector wrapper object, append elements to it,
then pass it to a method whose C++ signature expects
`const std::vector<T> &`. In older SWIG this implicit conversion worked;
in SWIG 4.4.0 it appears to raise a TypeError instead. Also tries passing
a plain Python list, to see if that's accepted as a fallback.
Run with: <openstudio_cli> swig_vector_repro.py
"""
import openstudio
print(f"OpenStudio version: {openstudio.openStudioVersion()}")
model = openstudio.model.Model()
zone = openstudio.model.ThermalZone(model)
sc = model.getShadowCalculation()
zone_vector = openstudio.model.ThermalZoneVector()
zone_vector.append(zone)
try:
sc.addShadingZoneGroup(zone_vector)
print("PASS: ShadowCalculation.addShadingZoneGroup(ThermalZoneVector) worked")
except TypeError as e:
print(f"FAIL: ShadowCalculation.addShadingZoneGroup(ThermalZoneVector) raised TypeError: {e}")
sc.removeAllShadingZoneGroups()
try:
sc.addShadingZoneGroup([zone])
print("PASS: ShadowCalculation.addShadingZoneGroup([zone]) worked")
except TypeError as e:
print(f"FAIL: ShadowCalculation.addShadingZoneGroup([zone]) raised TypeError: {e}")
# Sanity check: does a plain list work for other vector-typed APIs?
# (eg constructing a Surface from a plain list of Point3d, where the C++
# signature is `Surface(const std::vector<Point3d>&, const Model&)`)
try:
space = openstudio.model.Space(model)
pts = [
openstudio.Point3d(0, 0, 0),
openstudio.Point3d(1, 0, 0),
openstudio.Point3d(1, 1, 0),
openstudio.Point3d(0, 1, 0),
]
surface = openstudio.model.Surface(pts, model)
print("PASS: Surface(list_of_Point3d, model) worked")
except TypeError as e:
print(f"FAIL: Surface(list_of_Point3d, model) raised TypeError: {e}")
# Another ModelObject-subclass vector: AirLoopHVAC.setAvailabilityManagers(std::vector<AvailabilityManager>)
# called with a plain list in model/simulationtests/availability_managers.py:34
try:
air_loop = openstudio.model.AirLoopHVAC(model)
avm = openstudio.model.AvailabilityManagerNightVentilation(model)
air_loop.setAvailabilityManagers([avm])
print("PASS: AirLoopHVAC.setAvailabilityManagers([avm]) worked")
except TypeError as e:
print(f"FAIL: AirLoopHVAC.setAvailabilityManagers([avm]) raised TypeError: {e}")
--- /usr/local/openstudio-3.11.0/bin/openstudio swig_vector_repro.py
+++ ./Products/openstudio swig_vector_repro.py
- OpenStudio version: 3.11.0
+ OpenStudio version: 3.12.0
-PASS: ShadowCalculation.addShadingZoneGroup(ThermalZoneVector) worked
+FAIL: ShadowCalculation.addShadingZoneGroup(ThermalZoneVector) raised TypeError: in method 'ShadowCalculation_addShadingZoneGroup', argument 2 of type 'std::vector< openstudio::model::ThermalZone,std::allocator< openstudio::model::ThermalZone > > const &'
FAIL: ShadowCalculation.addShadingZoneGroup([zone]) raised TypeError: in method 'ShadowCalculation_addShadingZoneGroup', argument 2 of type 'std::vector< openstudio::model::ThermalZone,std::allocator< openstudio::model::ThermalZone > > const &'
PASS: Surface(list_of_Point3d, model) worked
PASS: AirLoopHVAC.setAvailabilityManagers([avm]) worked
Possible Solution
Suspected root cause
Both affected methods share the same structural shape: they take std::vector<T>& where T is only forward-declared in the .i file defining the method's class, while T's real class and its %template(...Vector) instantiation live in a separate, dependent SWIG module that imports the defining module:
ShadowCalculation::addShadingZoneGroup(std::vector<ThermalZone>&) — ShadowCalculation is in ModelSimulation.i; ThermalZone is only forward-declared there (class ThermalZone;), with the real type + ThermalZoneVector template in ModelHVAC.i, which imports ModelSimulation.i.
ShadingControl::addSubSurfaces(std::vector<SubSurface>&) — same pattern: ShadingControl in ModelResources.i, SubSurface forward-declared there, real type + SubSurfaceVector in ModelGeometry.i, which imports ModelResources.i.
SWIG 4.1.1 apparently resolved this cross-module reference correctly at wrapper-generation time; SWIG 4.4.0 does not. Other vector-argument methods where the class and its vector-element type live in the same module (e.g. AirLoopHVAC::setAvailabilityManagers(std::vector<AvailabilityManager>&), both in ModelHVAC.i) are unaffected.
Operating System affected
All
Environment
N/A
Version of OpenStudio
3.12.0-alpha
Context
Description
NatLabRockies/OpenStudio-resources#230 (comment)
For eg
ShadowCalculation.addShadingZoneGroup(ThermalZoneVector)no longer works with swig 4.4.0From 3.11.0 to develop today (3.12.0-alpha), SWIG bumped from 4.1.1 → 4.4.0 (conanfile.py).
Python calls to at least two methods now fail with a
TypeError, even when passing the "correct"*Vectorwrapper type that used to work:Confirmed via a minimal repro (
openstudio.model.ShadowCalculation().addShadingZoneGroup(...)) run against both/usr/local/openstudio-3.11.0(SWIG 4.1.1, passes) and a 26.1.0 dev build (SWIG 4.4.0, fails) — same code, same OpenStudio Python API, only the SWIG version differs. Neither aThermalZoneVector()wrapper nor a plain Python list works on the newer build; both worked (Vector) or failed the same way (list) on 3.11.0.Current Behavior
No longer works.
Expected Behavior
Used to work at 3.11.0
Steps to reproduce
swig_vector_repro.py
openstudio swig_vector_repro.pyPossible Solution
Suspected root cause
Both affected methods share the same structural shape: they take
std::vector<T>&whereTis only forward-declared in the.ifile defining the method's class, whileT's real class and its%template(...Vector)instantiation live in a separate, dependent SWIG module that imports the defining module:ShadowCalculation::addShadingZoneGroup(std::vector<ThermalZone>&)—ShadowCalculationis inModelSimulation.i;ThermalZoneis only forward-declared there (class ThermalZone;), with the real type +ThermalZoneVectortemplate inModelHVAC.i, which importsModelSimulation.i.ShadingControl::addSubSurfaces(std::vector<SubSurface>&)— same pattern:ShadingControlinModelResources.i,SubSurfaceforward-declared there, real type +SubSurfaceVectorinModelGeometry.i, which importsModelResources.i.SWIG 4.1.1 apparently resolved this cross-module reference correctly at wrapper-generation time; SWIG 4.4.0 does not. Other vector-argument methods where the class and its vector-element type live in the same module (e.g.
AirLoopHVAC::setAvailabilityManagers(std::vector<AvailabilityManager>&), both inModelHVAC.i) are unaffected.Operating System affected
All
Environment
N/A
Version of OpenStudio
3.12.0-alpha
Context