Make QuantLib::ext::shared_ptr resolvable by SWIG (#351) - #353
Open
dazivo wants to merge 1 commit into
Open
Conversation
dazivo
force-pushed
the
fix/351-swig-quantlib-ext-shared-ptr-alias
branch
from
August 18, 2026 15:30
eb6ebdd to
2fac510
Compare
This was referenced Aug 18, 2026
QuantLib-SWIG's common.i sets SWIG_SHARED_PTR_NAMESPACE to `ext`, and the
C++ alias `namespace ext = QuantLib::ext` it depends on sits inside a %{ %}
block that the SWIG parser never sees. Declarations spelled
`QuantLib::ext::shared_ptr<T>` were therefore registered as a type distinct
from `ext::shared_ptr<T>` and wrapped as an opaque pointer rather than a
proper proxy.
The two spellings are mixed throughout the interface files, so a value
produced by one could not be passed to the other. In particular
OREApp::getCube() (unqualified) could not be handed to
InputParameters::setCube() (qualified), which made in-memory cube reuse
unreachable from Python:
TypeError: in method 'InputParameters_setCube', argument 2 of type
'QuantLib::ext::shared_ptr< ore::analytics::NPVCube > const &'
setMarketCube/getMarketCube were affected identically, along with nine
further declarations in orea_app.i alone -- setXvaSensiPricingEngine and
its three siblings reject a freshly constructed EngineData on the released
1.8.16.0 wheel, while 1.8.15.0 (where both sides read `ext::shared_ptr`)
accepts every one of them.
Declare the namespace alias where SWIG can see it, collapsing both
spellings onto the same wrapped type. Regenerating oreanalytics.i shows
all 80 opaque SWIGTYPE_p_QuantLib__ext__shared_ptrT_* descriptors resolve
to their registered ext::shared_ptr counterparts, with no Python symbols
added or removed; the Python API surface diff is docstring-only.
Verified by building the bindings and running them in a debian trixie
container (clang 19, swig 4.3, apt boost): a freshly constructed
in-memory cube passes InputParameters::setCube, all four EngineData
setters accept a wrapped EngineData, and mismatched argument types are
still rejected.
Reviving the qualified overloads does surface new SWIG warnings (53 lines,
all Warning 509 overload shadowing; 88 -> 140 in total with SWIG 4.4.1),
confined to three constructors: DigitalCMSLegData and
DigitalCMSSpreadLegData taking a shared_ptr to their underlying leg data,
and BasketData taking a vector of shared_ptr constituents. Those
constructors were dead under the qualified spelling and %extend value-copy
workarounds had been added alongside them; this change brings the native
constructors back to life, and they now shadow the workarounds. As a
consequence, passing a CMSLegData to DigitalCMSLegData now shares the
underlying object with the constructed leg data, as the C++ API does,
instead of copying it through the workaround.
The accompanying test drives the EngineData setters and the setCube
round-trip; the round-trip constructs its cube directly and skips on
builds where the in-memory cubes are still wrongly abstract (issue OpenSourceRisk#354).
It fails against the 1.8.16.0 wheel.
dazivo
force-pushed
the
fix/351-swig-quantlib-ext-shared-ptr-alias
branch
from
August 18, 2026 18:10
2fac510 to
4e7f3a8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #351.
QuantLib-SWIG's common.i sets SWIG_SHARED_PTR_NAMESPACE to
ext, and the C++ aliasnamespace ext = QuantLib::extit depends on sits inside a %{ %} block that the SWIG parser never sees. Declarations spelledQuantLib::ext::shared_ptr<T>were therefore registered as a type distinct fromext::shared_ptr<T>and wrapped as an opaque pointer rather than a proper proxy.The two spellings are mixed throughout the interface files, so a value produced by one could not be passed to the other. In particular OREApp::getCube() (unqualified) could not be handed to InputParameters::setCube() (qualified), which made in-memory cube reuse unreachable from Python:
setMarketCube/getMarketCube were affected identically, along with nine further declarations in orea_app.i alone -- setXvaSensiPricingEngine and its three siblings reject a freshly constructed EngineData on the released 1.8.16.0 wheel, while 1.8.15.0 (where both sides read
ext::shared_ptr) accepts every one of them.Declare the namespace alias where SWIG can see it, collapsing both spellings onto the same wrapped type. Regenerating oreanalytics.i shows all 80 opaque SWIGTYPE_p_QuantLib__ext__shared_ptrT_* descriptors resolve to their registered ext::shared_ptr counterparts, with no Python symbols added or removed; the Python API surface diff is docstring-only.
Verified by building the bindings and running them in a debian trixie container (clang 19, swig 4.3, apt boost): a freshly constructed in-memory cube passes InputParameters::setCube, all four EngineData setters accept a wrapped EngineData, and mismatched argument types are still rejected.
Reviving the qualified overloads does surface new SWIG warnings (53 lines, all Warning 509 overload shadowing; 88 -> 140 in total with SWIG 4.4.1), confined to three constructors: DigitalCMSLegData and DigitalCMSSpreadLegData taking a shared_ptr to their underlying leg data, and BasketData taking a vector of shared_ptr constituents. Those constructors were dead under the qualified spelling and %extend value-copy workarounds had been added alongside them; this change brings the native constructors back to life, and they now shadow the workarounds. As a consequence, passing a CMSLegData to DigitalCMSLegData now shares the underlying object with the constructed leg data, as the C++ API does, instead of copying it through the workaround.
The accompanying test drives the EngineData setters and the setCube round-trip; the round-trip constructs its cube directly and skips on builds where the in-memory cubes are still wrongly abstract (#354, fixed by #355). It fails against the 1.8.16.0 wheel.