Skip to content

Commit 698120f

Browse files
committed
ENH: Prefer ...
1 parent ef9ff07 commit 698120f

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

Base/QTCore/qSlicerCoreApplication.cxx

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,32 @@ void qSlicerCoreApplication::handleURIArguments(const QStringList& fileNames)
11971197
CTK_GET_CPP(qSlicerCoreApplication, bool, isURIArgumentHandlingEnabled, URIArgumentHandlingEnabled);
11981198
CTK_SET_CPP(qSlicerCoreApplication, bool, setURIArgumentHandlingEnabled, URIArgumentHandlingEnabled);
11991199

1200+
//-----------------------------------------------------------------------------
1201+
namespace
1202+
{
1203+
1204+
// Mirrors CPython's PyWideStringList_Clear only available internally:
1205+
// Items in PyWideStringList are allocated with the "raw" allocator;
1206+
// free them with PyMem_RawFree (mirrors CPython).
1207+
void ClearWideStringList(PyWideStringList* list)
1208+
{
1209+
if (!list || !list->items)
1210+
{
1211+
list->length = 0;
1212+
list->items = nullptr;
1213+
return;
1214+
}
1215+
for (Py_ssize_t i = 0; i < list->length; ++i)
1216+
{
1217+
PyMem_RawFree(list->items[i]);
1218+
}
1219+
PyMem_RawFree(list->items);
1220+
list->length = 0;
1221+
list->items = nullptr;
1222+
}
1223+
1224+
} // namespace
1225+
12001226
//-----------------------------------------------------------------------------
12011227
void qSlicerCoreApplication::handleCommandLineArguments()
12021228
{
@@ -1218,9 +1244,9 @@ void qSlicerCoreApplication::handleCommandLineArguments()
12181244
#else
12191245
if (!qSlicerCoreApplication::testAttribute(qSlicerCoreApplication::AA_DisablePython))
12201246
{
1221-
// Snapshot current sys.path BEFORE applying the config
1222-
// Rationale: _PyInterpreterState_SetConfig will replace sys.path from config.
1223-
// We want an exact restore of the sys.path augmented during Slicer module discovery.
1247+
// Snapshot current sys.path BEFORE applying the config.
1248+
// Rationale: _PyInterpreterState_SetConfig replaces sys.path from the config.
1249+
// We capture the runtime-augmented sys.path so we can install it into the config.
12241250
PythonQtObjectPtr sys;
12251251
sys.setNewRef(PyImport_ImportModule("sys"));
12261252
PythonQtObjectPtr sysPath;
@@ -1275,6 +1301,23 @@ void qSlicerCoreApplication::handleCommandLineArguments()
12751301
qSlicerCoreApplication::terminate(EXIT_FAILURE);
12761302
}
12771303

1304+
// Preserve runtime-augmented sys.path in the config itself.
1305+
// Set module_search_paths_set=1 BEFORE PyConfig_SetArgv so argv changes
1306+
// won't trigger a path recompute that drops Slicer inserts.
1307+
ClearWideStringList(&config.module_search_paths);
1308+
config.module_search_paths_set = 1;
1309+
1310+
for (const QString& path : savedSysPath)
1311+
{
1312+
const std::wstring w = path.toStdWString();
1313+
PyStatus status = PyWideStringList_Append(&config.module_search_paths, w.c_str());
1314+
if (PyStatus_Exception(status))
1315+
{
1316+
PyConfig_Clear(&config);
1317+
Py_ExitStatusException(status);
1318+
}
1319+
}
1320+
12781321
// Apply updated command-line arguments to the interpreter.
12791322
PyStatus status = PyConfig_SetArgv(&config, pythonArgc, pythonArgv);
12801323
if (PyStatus_Exception(status))
@@ -1292,9 +1335,6 @@ void qSlicerCoreApplication::handleCommandLineArguments()
12921335
qSlicerCoreApplication::terminate(EXIT_FAILURE);
12931336
}
12941337

1295-
// Restore sys.path exactly as it was before calling "_PyInterpreterState_SetConfig"
1296-
PythonQt::self()->overwriteSysPath(savedSysPath);
1297-
12981338
PyConfig_Clear(&config);
12991339

13001340
// Set 'sys.executable' so that Slicer can be used as a "regular" python interpreter

0 commit comments

Comments
 (0)