Skip to content

Sync changes from v26-0-0#15

Open
ChrisWu2024 wants to merge 4 commits intomainfrom
ado-github-sync
Open

Sync changes from v26-0-0#15
ChrisWu2024 wants to merge 4 commits intomainfrom
ado-github-sync

Conversation

@ChrisWu2024
Copy link
Copy Markdown
Collaborator

No description provided.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR syncs the repo with v26-0-0 API/binding changes, primarily standardizing Python wrapper return conventions (status-first tuples), expanding py::list interoperability, and updating the Python engine/session plumbing (wstring notifications, key-in args, session info).

Changes:

  • Standardize many Python bindings to return (status, result) and update corresponding docstrings/tests/samples.
  • Add additional py::list overloads and Python container conveniences (__len__, iterators, list conversions) across multiple wrapper types.
  • Enhance Python engine/session handling (wstring error/output plumbing, key-in argument passing, session info storage, build file restructuring, new samples/tests).

Reviewed changes

Copilot reviewed 115 out of 120 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
PublicAPI/MSPythonCore/ScriptEngineManager.h Switch notifier messages to wstring; add session APIs; replace namespace macros.
MSPythonWrapper/PyMstnPlatform/source/PSolid/psolidcoreapi.cpp Add py::list overloads for SolidUtil.Modify methods (Blend/Chamfer/Hollow/Offset variants).
MSPythonWrapper/PyMstnPlatform/source/Plot/IPrintDescription.cpp Add py::list overload for GetViewIndependentWorkingFence; minor cleanup.
MSPythonWrapper/PyMstnPlatform/source/Plot/IPlotter.cpp Add py::list overload for FindBestFitForm.
MSPythonWrapper/PyMstnPlatform/source/MdlApi/msview.cpp Add py::list overloads for view list/boolean-array style APIs.
MSPythonWrapper/PyMstnPlatform/source/isessionmgr.cpp Swap tuple return ordering + doc updates for session mgr dialogs.
MSPythonWrapper/PyMstnPlatform/source/ImageLib/ImageLibApi.cpp Reacquire GIL before building Python tuple result.
MSPythonWrapper/PyMstnPlatform/source/documentmanager.cpp Swap tuple return ordering + doc updates for document manager dialogs.
MSPythonWrapper/PyECObjects/source/ecschema.cpp Add __len__ to ECClassContainer iterator wrapper.
MSPythonWrapper/PyECObjects/PyECObjects.mke.sourcemap.json New sourcemap manifest for PyECObjects build.
MSPythonWrapper/PyDgnView/testUtilities/PyDgnViewTest.mke.sourcemap.json New sourcemap manifest for PyDgnView tests.
MSPythonWrapper/PyDgnView/source/ParentTypes/iviewmanager.cpp Add __len__ to IndexedViewSet wrapper.
MSPythonWrapper/PyDgnView/PyDgnView.mke.sourcemap.json New sourcemap manifest for PyDgnView build.
MSPythonWrapper/PyDgnPlatform/testUtilities/PyDgnPlatformTest.mke.sourcemap.json New sourcemap manifest for PyDgnPlatform tests.
MSPythonWrapper/PyDgnPlatform/source/xmlfragment.cpp Add __len__ to XmlFragmentList wrapper.
MSPythonWrapper/PyDgnPlatform/source/xdatanodecollection.cpp Add __len__ to XDataNodeCollection wrapper.
MSPythonWrapper/PyDgnPlatform/source/xattributeiter.cpp Add __len__ to XAttributeCollection wrapper.
MSPythonWrapper/PyDgnPlatform/source/workset.cpp Add __len__ to WorkSetCollection wrapper.
MSPythonWrapper/PyDgnPlatform/source/unitdefinition.cpp Add __len__ to Standard/User unit collections.
MSPythonWrapper/PyDgnPlatform/source/texttablehandler.cpp Add orientation-angle APIs + docstrings for TextTable/TextTableCell.
MSPythonWrapper/PyDgnPlatform/source/textblockiterators.cpp Add __len__ to RunRange iterator wrapper.
MSPythonWrapper/PyDgnPlatform/source/sheetsizedefinition.cpp Add __len__ to SheetSizeCollection wrapper.
MSPythonWrapper/PyDgnPlatform/source/scaledefinition.cpp Add ctor + __len__ to ScaleCollection wrapper.
MSPythonWrapper/PyDgnPlatform/source/rastercollection.cpp Add __len__ to DgnRasterCollection wrapper.
MSPythonWrapper/PyDgnPlatform/source/picklist.cpp Return reference_internal for AddValue/AddPickList; add __len__.
MSPythonWrapper/PyDgnPlatform/source/material.cpp Swap tuple return ordering + doc updates for MaterialManager searches.
MSPythonWrapper/PyDgnPlatform/source/linestyle.cpp Swap tuple return ordering; add __len__ to LsMap; doc fixes.
MSPythonWrapper/PyDgnPlatform/source/light.cpp Add __len__ to LightMapCollection wrapper.
MSPythonWrapper/PyDgnPlatform/source/itxnmanager.cpp Swap tuple return ordering + doc updates for CreateNewModel.
MSPythonWrapper/PyDgnPlatform/source/elementtemplateparamshelper.cpp Add fixed-size unit APIs + updated tuple-style docs.
MSPythonWrapper/PyDgnPlatform/source/elementrefbase.cpp Add Python list-like behaviors to ElementRefVec (iter/del/contains/remove).
MSPythonWrapper/PyDgnPlatform/source/ecinstanceholderhandler.cpp Swap tuple return ordering for CreateECInstanceHolderElement + doc update.
MSPythonWrapper/PyDgnPlatform/source/digitalsignaturecellheaderhandler.cpp Add __len__ to ApplicableSignaturesCollection wrapper.
MSPythonWrapper/PyDgnPlatform/source/dgnraster.cpp Swap tuple return ordering for DgnRaster::Create.
MSPythonWrapper/PyDgnPlatform/source/dgnmodelrefcollections.cpp Add __len__ to reachable model/element collection wrappers.
MSPythonWrapper/PyDgnPlatform/source/dgnlinktree.cpp Add __len__ to DgnLinkUserDataList wrapper.
MSPythonWrapper/PyDgnPlatform/source/dgnlinks.cpp Swap tuple return ordering for DgnModelLink tuple-returning getters.
MSPythonWrapper/PyDgnPlatform/source/dgnlinkmanager.cpp Swap tuple return ordering for CreateLink/CreateLinkSet; doc updates.
MSPythonWrapper/PyDgnPlatform/source/dgnitemindex.cpp Add __len__ to ModelIndex wrapper.
MSPythonWrapper/PyDgnPlatform/source/dgnfile.cpp Add LoadDgnFile doc; add __len__; swap tuple ordering in some methods.
MSPythonWrapper/PyBentleyGeom/testUtilities/PyGeomTest.mke.sourcemap.json New sourcemap manifest for PyBentleyGeom tests.
MSPythonWrapper/PyBentleyGeom/source/rotmatrix.cpp Fix invalid default-arg placement by removing default in binding.
MSPythonWrapper/PyBentleyGeom/source/curveprimitive.cpp Add overloads for CreateSpiral, including maxStrokeLength.
MSPythonWrapper/PyBentley/source/ParentTypes/betextfile.cpp Swap tuple return ordering for BeTextFile.Open + doc update.
MSPythonWrapper/PyBentley/source/bestringutilities.cpp Swap tuple return ordering for ParseUInt64 + doc update.
MSPythonWrapper/PyBentley/PyBentley.mke.sourcemap.json New sourcemap manifest for PyBentley build.
MSPythonTests/MstnPlatformTests/Tests/SessionMgr_Test.py Update tests for status-first tuple returns; update mdlDescr expectations.
MSPythonTests/MstnPlatformTests/Tests/PylistTests/Psolidcoreapi_Pylist_Test.py New tests covering new py::list overloads for PSolid APIs.
MSPythonTests/MstnPlatformTests/Tests/PylistTests/Msview_Pylist_test.py New tests covering new py::list overloads for msview APIs.
MSPythonTests/MstnPlatformTests/Tests/PylistTests/IPrintDescription_Pylist_Test.py New tests for GetViewIndependentWorkingFence py::list overload.
MSPythonTests/MstnPlatformTests/Tests/PylistTests/IPlotter_Pylist_Test.py New tests for FindBestFitForm py::list overload.
MSPythonTests/MstnPlatformTests/Tests/PylistTests/Fenceparams_Pylist_test.py New tests for FenceParams list/array conversions.
MSPythonTests/MstnPlatformTests/Tests/Mesh_Test.py Update tuple unpacking order for getFileFromDirectory usage.
MSPythonTests/MstnPlatformTests/Tests/Level_Test.py Update tuple return indexing order for file/document helpers.
MSPythonTests/MstnPlatformTests/Tests/KeyInManager_Test.py Update callbacks to accept optional unparsed arg string.
MSPythonTests/MstnPlatformTests/Tests/DocumentManager_Test.py Update tuple return indexing order for document manager APIs.
MSPythonTests/MstnPlatformTests/Tests/DgnFile_Test.py Update tuple unpacking order for getFileFromDirectory usage.
MSPythonTests/MstnPlatformTests/Tests/ChangeTrackCallback_Test.py Update CreateFromFileName usage (but currently inconsistent indexing).
MSPythonTests/MstnPlatformTests/Tests/ArgSupport_Test.py New argparse-based key-in argument handling sample/test script.
MSPythonTests/MstnPlatformTests/Tests/AddURLLink_Test.py Update CreateLink tuple return ordering.
MSPythonSamples/SystemCallbacks/ChangeTrackCallbacks.py Update Add/Remove functions to accept optional unparsed arg string.
MSPythonSamples/ReportSample/ReportExample.commands.xml New key-in command table for report example.
MSPythonSamples/ReportSample/report_Example.py New report sample entrypoint + key-in loader.
MSPythonSamples/ReportSample/report_example_generate_report.py New report-definition generation logic.
MSPythonSamples/ReportSample/report_example_create_itemtypes.py New item type library/type creation logic.
MSPythonSamples/ReportSample/report_example_common.py Shared config/utilities for report example workflow.
MSPythonSamples/ReportSample/report_example_attach_itemtypes.py Tool/sample to attach item types to elements.
MSPythonSamples/ParametricModeling/VariableAndVariation.py Update BeTextFile.Open tuple return ordering.
MSPythonSamples/ParametricModeling/PSampUtility.py Update LoadRootModelById tuple return ordering.
MSPythonSamples/ParametricModeling/ParametricCell.py Update LoadRootModelById tuple return ordering.
MSPythonSamples/ItemType/Custom/ItemTypeCustomProperty.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/ItemType/CRUD/ItemTypeCRUD.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/ItemType/Attach/ItemTypeAttachDetach.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/GeospatialContext/SHPImportWithDesignLink.py Update CreateLink tuple return ordering.
MSPythonSamples/GeospatialContext/GDBImportAsCell.py Add FixedSizeUnitType handling via new template helper APIs.
MSPythonSamples/GeospatialContext/CreateCustomGCS_StlouisTM96.py Handle tuple return from InitFromWellKnownText and validate status.
MSPythonSamples/GeospatialContext/AddGeographicCoordinateSystemToModel.py Handle tuple returns from InitFromEPSGCode / InitFromWellKnownText.
MSPythonSamples/EC/Schema/ECXSchema.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/EC/ExtractProperties/ExtractProperties.py Update key-in entrypoint to accept optional unparsed arg string.
MSPythonSamples/EC/ECChangeEvents/DgnECChangeEvents.py Update LoadRootModelById tuple return indexing order; key-in entrypoints updated.
MSPythonSamples/EC/Dump/ECDumpUtility.py Update key-in entrypoint to accept optional unparsed arg string.
MSPythonSamples/EC/CRUD/ECCrud.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/DgnTool/TextExample/TextExample.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/DgnTool/PolyfaceTool/PolyfaceTool.py Update key-in entrypoint to accept optional unparsed arg string.
MSPythonSamples/DgnTool/ModifyMultipleElements/ModifyMultipleElements.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/DgnTool/ModifyEdgeSamples/ModifyEdgeSamples.py Update key-in entrypoint to accept optional unparsed arg string.
MSPythonSamples/DgnTool/MeshTools/MeshTools.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/DgnTool/IncrementText/IncrementText.py Update key-in entrypoint to accept optional unparsed arg string.
MSPythonSamples/DgnTool/ElementLinkExample.py Update CreateLink tuple return ordering; update key-in entrypoints.
MSPythonSamples/DgnElements/UnitConversionsSample.py Update key-in entrypoint to accept optional unparsed arg string.
MSPythonSamples/DgnElements/TagsExamplePlaceTagFromText.py Improve robustness; auto-create tag set; add additional messaging.
MSPythonSamples/DgnElements/TagsExampleCreateTagSet.py Update messaging; make tagsExample_createTagSet key-in compatible; simplify main.
MSPythonSamples/DgnElements/TagsExampleCreateTagSet.commands.xml Removed old command table XML.
MSPythonSamples/DgnElements/Reference/Reference.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/DgnElements/MeshStyleSamples.py Update key-in entrypoints to accept optional unparsed arg string.
MSPythonSamples/DgnElements/CreateTextNodes.py Update tuple indexing for default model load result.
MSPythonCore/ScriptEngineManager/source/ScriptEngineManager.cpp Add PythonSessionInfo + session result accumulation + silence mode.
MSPythonCore/ScriptEngineManager/source/MSPythonEngine.cpp wstring InjectError; safer main dict backup; key-in arg invocation changes.
MSPythonCore/ScriptEngineManager/ScriptEngineManager.mki Removed (build rules moved/reworked).
MSPythonCore/MSPythonCore.mke.sourcemap.json New sourcemap manifest for MSPythonCore build.
MSPythonCore/MSPythonCore.mke New build file replacing top-level MSPythonCore.mke.
MSPythonCore.mke Removed (replaced by MSPythonCore/MSPythonCore.mke).
MSPython.mke Update build invocation path for new MSPythonCore/MSPythonCore.mke.
InternalAPI/MSPyCommon.h Improve pylist conversion casting and add bool conversion specializations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +239 to +242
virtual void OnException(std::exception& ex) override
{
BeConsole::WPrintf(L"%s\n", ex.what());
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UstnScriptNotifier::OnException passes std::exception::what() (char*) to BeConsole::WPrintf with a wide format string (L"%s"). For wide printf-family functions, "%s" expects wchar_t*, so this is undefined behavior and can crash or print garbage. Convert the message to a wide string (e.g., WString(ex.what()) / Utf8->WChar) or use the correct format specifier for narrow strings if supported.

Copilot uses AI. Check for mistakes.
Comment on lines +1748 to +1754
bool isdraw[DgnPlatform::MAX_VIEWS];
CONVERT_PYLIST_TO_NEW_CPPARRAY(viewDraw, cppViewDraw, BoolArray, bool);
size_t arrlen = cppViewDraw.size() > DgnPlatform::MAX_VIEWS ? DgnPlatform::MAX_VIEWS : cppViewDraw.size();
for (int i = 0; i < arrlen; i++)
isdraw[i] = cppViewDraw[i];

return mdlView_updateMulti (isdraw, incremental, drawMode, modelRefList, startEndMsg);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local isdraw array is only assigned for indices < arrlen; the remaining elements are left uninitialized but still passed to mdlView_updateMulti, which can read garbage view flags. Initialize the full MAX_VIEWS array (e.g., fill with false) before copying list entries.

Copilot uses AI. Check for mistakes.
Comment on lines +1772 to +1778
bool isdraw[DgnPlatform::MAX_VIEWS];
CONVERT_PYLIST_TO_NEW_CPPARRAY(viewDraw, cppViewDraw, BoolArray, bool);
size_t arrlen = cppViewDraw.size() > DgnPlatform::MAX_VIEWS ? DgnPlatform::MAX_VIEWS : cppViewDraw.size();
for (int i = 0; i < arrlen; i++)
isdraw[i] = cppViewDraw[i];

return mdlView_updateMultiEx(isdraw, incremental, drawMode, modelRefList, startEndMsg, updateViewTitle);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local isdraw array is only assigned for indices < arrlen; the remaining elements are left uninitialized but still passed to mdlView_updateMultiEx. Initialize the full MAX_VIEWS array (e.g., fill with false) before copying list entries.

Copilot uses AI. Check for mistakes.
Comment on lines +1848 to +1854
bool isdraw[DgnPlatform::MAX_VIEWS];
CONVERT_PYLIST_TO_NEW_CPPARRAY(viewList, cppViewList, BoolArray, bool);
size_t arrlen = cppViewList.size() > DgnPlatform::MAX_VIEWS ? DgnPlatform::MAX_VIEWS : cppViewList.size();
for (int i = 0; i < arrlen; i++)
isdraw[i] = cppViewList[i];

return mdlView_setLevelDisplayMaskMulti(modelRef, isdraw, viewLevelMask, doUpdate);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local isdraw array is only assigned for indices < arrlen; the remaining elements are left uninitialized but still passed to mdlView_setLevelDisplayMaskMulti. Initialize the full MAX_VIEWS array (e.g., fill with false) before copying list entries.

Copilot uses AI. Check for mistakes.
Comment on lines +1869 to +1876
bool isdraw[DgnPlatform::MAX_VIEWS];
CONVERT_PYLIST_TO_NEW_CPPARRAY(viewList, cppViewList, BoolArray, bool);
size_t arrlen = cppViewList.size() > DgnPlatform::MAX_VIEWS ? DgnPlatform::MAX_VIEWS : cppViewList.size();
for (int i = 0; i < arrlen; i++)
isdraw[i] = cppViewList[i];

return mdlView_changeLevelDisplayMaskMulti(modelRef, isdraw, levelMask, operation, doUpdate);
}, "modelRef"_a, "viewList"_a, "levelMask"_a, "operation"_a, "doUpdate"_a, DOC(mdlView, changeLevelDisplayMaskMulti));
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local isdraw array is only assigned for indices < arrlen; the remaining elements are left uninitialized but still passed to mdlView_changeLevelDisplayMaskMulti. Initialize the full MAX_VIEWS array (e.g., fill with false) before copying list entries.

Copilot uses AI. Check for mistakes.
Comment on lines 1068 to 1074
WString function(funcName);
WString arg;
localCtx->getAs(L"PyKeyinArg", arg);
function.append(L" (PyKeyinArg)");

function.append (L" ()");
mdlErrno = 0;
py::exec(py::cast(function.c_str ()) ,globalDict, localDict);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

localCtx->getAs(L"PyKeyinArg", arg); ignores the return value and the retrieved arg is unused, while the code always invokes the function as funcName(PyKeyinArg). If PyKeyinArg is not present in localDict this will raise a NameError. Consider: (1) ensure PyKeyinArg is defined in localDict (set to "" when missing), and/or (2) only append/call with the argument when it is actually present, and remove the unused arg variable.

Copilot uses AI. Check for mistakes.
Comment on lines +127 to +128
doc = DgnDocument.CreateFromFileName ('ChangeTrack.dgn', dataDir, -101, DgnDocument.FetchMode.eWrite)[1]
ISessionMgr.GetManager().SwitchToNewFile(doc[1], '', GraphicsFileType.eGRAPHICSFILE_WildCard, True, True)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc is assigned to a single tuple element (CreateFromFileName(...)[1]), but then indexed again (doc[1]) when passed to SwitchToNewFile. This will raise at runtime. Either unpack the tuple into (status, doc) and pass doc, or keep doc as the document object and pass it directly.

Copilot uses AI. Check for mistakes.
Comment on lines 1478 to 1480
c1.def("FactorRotateScaleRotate", &RotMatrix::FactorRotateScaleRotate, "rotation1"_a, "scalePoint"_a, "rotation2"_a, DOC(Bentley, Geom, RotMatrix, FactorRotateScaleRotate));
c1.def("RotateAndSkewFactors", &RotMatrix::RotateAndSkewFactors, "rotation"_a, "skewFactor"_a = 0, "primiaryAxis"_a, "secondaryAxis"_a, DOC(Bentley, Geom, RotMatrix, RotateAndSkewFactors));
c1.def("RotateAndSkewFactors", &RotMatrix::RotateAndSkewFactors, "rotation"_a, "skewFactor"_a, "primiaryAxis"_a, "secondaryAxis"_a, DOC(Bentley, Geom, RotMatrix, RotateAndSkewFactors));
c1.def("FactorOrthogonalColumns", &RotMatrix::FactorOrthogonalColumns, "matrixB"_a, "maxtrixV"_a, DOC(Bentley, Geom, RotMatrix, FactorOrthogonalColumns));
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This binding removed the default value for skewFactor, which is a breaking change for Python callers that previously relied on the optional argument. To preserve the old signature, consider adding an overload/wrapper that calls RotateAndSkewFactors with skewFactor=0 when omitted.

Copilot uses AI. Check for mistakes.
void ScriptEngineManager::InitPySessionInfo()
{
if (nullptr == s_sessionInfo)
s_sessionInfo = new PythonSessionInfo();
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InitPySessionInfo allocates s_sessionInfo with new but it is never freed (ScriptEngineManager::Shutdown only deletes s_EngineManager). Prefer a smart pointer/static value, or ensure s_sessionInfo is deleted during shutdown to avoid a persistent leak (especially in test runners or plugin reload scenarios).

Suggested change
s_sessionInfo = new PythonSessionInfo();
{
static PythonSessionInfo sessionInfo;
s_sessionInfo = &sessionInfo;
}

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +44
keyinXml = os.path.dirname(__file__) + '/ReportExample.commands.xml'
PythonKeyinManager.GetManager().LoadCommandTableFromXml(WString(__file__), WString(keyinXml))

MessageCenter.ShowInfoMessage(f"Loaded key-in commands. /n REPORTSEXAMPLE CREATE ITEMTYPES /nREPORTSEXAMPLE ATTACH ITEMTYPES /n REPORTSEXAMPLE GENERATE REPORT", "", False)
return True
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The info message uses "/n" sequences instead of newline escape "\n", so it will display the literal characters rather than line breaks. Replace "/n" with "\n" in the message string.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants