@@ -18,7 +18,7 @@ namespace NppPythonScript
18
18
PythonHandler::PythonHandler (TCHAR *pluginsDir, TCHAR *configDir, HINSTANCE hInst, HWND nppHandle, HWND scintilla1Handle, HWND scintilla2Handle, boost::shared_ptr<PythonConsole> pythonConsole)
19
19
: PyProducerConsumer<RunScriptArgs>(),
20
20
m_nppHandle (nppHandle),
21
- m_scintilla1Handle (scintilla1Handle),
21
+ m_scintilla1Handle (scintilla1Handle),
22
22
m_scintilla2Handle (scintilla2Handle),
23
23
m_hInst (hInst),
24
24
m_machineBaseDir (pluginsDir),
@@ -89,99 +89,179 @@ void PythonHandler::initPython()
89
89
90
90
preinitScintillaModule ();
91
91
92
+ PyStatus status;
93
+
94
+ PyConfig config;
95
+ PyConfig_InitPythonConfig (&config);
96
+
97
+ // Read all configuration at once
98
+ // implicit pre config python
99
+ status = PyConfig_Read (&config);
100
+ if (PyStatus_Exception (status))
101
+ {
102
+ PyConfig_Clear (&config);
103
+ }
104
+
92
105
// Don't import site - if Python 2.7 doesn't find it as part of Py_Initialize,
93
106
// it does an exit(1) - AGH!
94
107
Py_NoSiteFlag = 1 ;
95
108
Py_IgnoreEnvironmentFlag = 1 ;
96
109
Py_NoUserSiteDirectory = 1 ;
97
110
98
- Py_Initialize ();
99
- // Initialise threading and create & acquire Global Interpreter Lock
100
- PyEval_InitThreads ();
111
+ # ifdef DEBUG
112
+ Py_VerboseFlag = 1 ;
113
+ # endif
101
114
115
+ bool configSetFailed = false ;
102
116
103
- std::shared_ptr<char > machineBaseDir = WcharMbcsConverter::tchar2char (m_machineBaseDir.c_str ());
104
- std::shared_ptr<char > configDir = WcharMbcsConverter::tchar2char (m_userBaseDir.c_str ());
117
+ // appended or prepended below in this order
118
+ std::wstring machinelib = m_machineBaseDir + std::wstring (L" lib" );
119
+ std::wstring userlib = m_userBaseDir + std::wstring (L" lib" );
120
+ std::wstring machineScripts = m_machineBaseDir + std::wstring (L" scripts" );
121
+ std::wstring userScripts = m_userBaseDir + std::wstring (L" scripts" );
122
+ std::wstring machinelibTK = m_machineBaseDir + std::wstring (L" lib\\ lib-tk" );
105
123
106
- bool machineIsUnicode = containsExtendedChars (machineBaseDir.get ());
107
- bool userIsUnicode = containsExtendedChars (configDir.get ());
124
+ // If the user wants to use their installed python version, append the paths.
125
+ // If not (and they want to use the bundled python install), the default, then prepend the paths
126
+ if (ConfigFile::getInstance ()->getSetting (_T (" PREFERINSTALLEDPYTHON" )) == _T (" 1" ))
127
+ {
128
+ /* Append our custom search path to sys.path */
129
+ status = PyWideStringList_Append (&config.module_search_paths ,
130
+ machinelib.c_str ());
108
131
132
+ if (PyStatus_Exception (status))
133
+ {
134
+ configSetFailed = true ;
135
+ }
109
136
110
- std::string smachineDir (machineBaseDir.get ());
111
- std::string suserDir (configDir.get ());
137
+ /* Append our custom search path to sys.path */
138
+ status = PyWideStringList_Append (&config.module_search_paths ,
139
+ userlib.c_str ());
112
140
141
+ if (PyStatus_Exception (status))
142
+ {
143
+ configSetFailed = true ;
144
+ }
113
145
114
- // Init paths
115
- char initBuffer[ 1024 ];
116
- char pathCommands[ 500 ] ;
146
+ /* Append our custom search path to sys.path */
147
+ status = PyWideStringList_Append (&config. module_search_paths ,
148
+ machineScripts. c_str ()) ;
117
149
118
- // If the user wants to use their installed python version, append the paths.
119
- // If not (and they want to use the bundled python install), the default, then prepend the paths
120
- if (ConfigFile::getInstance ()->getSetting (_T (" PREFERINSTALLEDPYTHON" )) == _T (" 1" )) {
121
- strcpy_s<500 >(pathCommands, " import sys\n "
122
- " sys.path.append(r'%slib'%s)\n "
123
- " sys.path.append(r'%slib'%s)\n "
124
- " sys.path.append(r'%sscripts'%s)\n "
125
- " sys.path.append(r'%sscripts'%s)\n "
126
- " sys.path.append(r'%slib\\ lib-tk'%s)\n " );
127
- } else {
128
- strcpy_s<500 >(pathCommands, " import sys\n "
129
- " sys.path.insert(0,r'%slib'%s)\n "
130
- " sys.path.insert(1,r'%slib'%s)\n "
131
- " sys.path.insert(2,r'%sscripts'%s)\n "
132
- " sys.path.insert(3,r'%sscripts'%s)\n "
133
- " sys.path.insert(4,r'%slib\\ lib-tk'%s)\n "
134
- );
150
+ if (PyStatus_Exception (status))
151
+ {
152
+ configSetFailed = true ;
153
+ }
154
+
155
+ /* Append our custom search path to sys.path */
156
+ status = PyWideStringList_Append (&config.module_search_paths ,
157
+ userScripts.c_str ());
158
+
159
+ if (PyStatus_Exception (status))
160
+ {
161
+ configSetFailed = true ;
162
+ }
163
+
164
+ /* Append our custom search path to sys.path */
165
+ status = PyWideStringList_Append (&config.module_search_paths ,
166
+ machinelibTK.c_str ());
167
+
168
+ if (PyStatus_Exception (status))
169
+ {
170
+ configSetFailed = true ;
171
+ }
135
172
}
173
+ else
174
+ {
175
+ /* Prepend via insert our custom search path to sys.path */
176
+ status = PyWideStringList_Insert (&config.module_search_paths , 0 ,
177
+ machinelib.c_str ());
136
178
137
- _snprintf_s (initBuffer, 1024 , 1024 ,
138
- pathCommands,
139
- smachineDir. c_str (),
140
- machineIsUnicode ? " .decode('utf8') " : " " ,
179
+ if ( PyStatus_Exception (status))
180
+ {
181
+ configSetFailed = true ;
182
+ }
141
183
142
- suserDir.c_str (),
143
- userIsUnicode ? " .decode('utf8')" : " " ,
184
+ /* Prepend via insert our custom search path to sys.path */
185
+ status = PyWideStringList_Insert (&config.module_search_paths , 1 ,
186
+ userlib.c_str ());
144
187
145
- smachineDir.c_str (),
146
- machineIsUnicode ? " .decode('utf8')" : " " ,
188
+ if (PyStatus_Exception (status))
189
+ {
190
+ PyConfig_Clear (&config);
191
+ }
192
+
193
+ /* Prepend via insert our custom search path to sys.path */
194
+ status = PyWideStringList_Insert (&config.module_search_paths , 2 ,
195
+ machineScripts.c_str ());
196
+
197
+ if (PyStatus_Exception (status))
198
+ {
199
+ configSetFailed = true ;
200
+ }
201
+
202
+ /* Prepend via insert our custom search path to sys.path */
203
+ status = PyWideStringList_Insert (&config.module_search_paths , 3 ,
204
+ userScripts.c_str ());
205
+
206
+ if (PyStatus_Exception (status))
207
+ {
208
+ PyConfig_Clear (&config);
209
+ }
210
+
211
+ /* Prepend via insert our custom search path to sys.path */
212
+ status = PyWideStringList_Insert (&config.module_search_paths , 4 ,
213
+ machinelibTK.c_str ());
214
+
215
+ if (PyStatus_Exception (status))
216
+ {
217
+ configSetFailed = true ;
218
+ }
219
+ }
220
+
221
+ if (!configSetFailed)
222
+ {
223
+ status = Py_InitializeFromConfig (&config);
224
+ if (PyStatus_Exception (status))
225
+ {
226
+ PyConfig_Clear (&config);
227
+ }
228
+ }
147
229
148
- suserDir. c_str (),
149
- userIsUnicode ? " .decode('utf8') " : " " ,
230
+ // Initialise threading and create & acquire Global Interpreter Lock
231
+ PyEval_InitThreads ();
150
232
151
- smachineDir.c_str (),
152
- machineIsUnicode ? " .decode('utf8')" : " "
153
- );
233
+ std::string importSys (" import sys\n " );
154
234
155
- PyRun_SimpleString (initBuffer );
235
+ PyRun_SimpleString (importSys. c_str () );
156
236
157
- initSysArgv ();
237
+ initSysArgv ();
158
238
159
239
160
240
// Init Notepad++/Scintilla modules
161
241
initModules ();
162
242
163
- mp_mainThreadState = PyEval_SaveThread ();
243
+ mp_mainThreadState = PyEval_SaveThread ();
164
244
165
245
}
166
246
167
247
void PythonHandler::initSysArgv ()
168
248
{
169
- LPWSTR commandLine = ::GetCommandLineW ();
170
- int argc;
171
- LPWSTR* argv = ::CommandLineToArgvW (commandLine, &argc);
249
+ LPWSTR commandLine = ::GetCommandLineW ();
250
+ int argc;
251
+ LPWSTR* argv = ::CommandLineToArgvW (commandLine, &argc);
172
252
173
253
174
- boost::python::list argvList;
175
- for (int currentArg = 0 ; currentArg != argc; ++currentArg)
254
+ boost::python::list argvList;
255
+ for (int currentArg = 0 ; currentArg != argc; ++currentArg)
176
256
{
177
- std::shared_ptr<char > argInUtf8 = WcharMbcsConverter::wchar2char (argv[currentArg]);
178
- PyObject* unicodeArg = PyUnicode_FromString (argInUtf8.get ());
257
+ std::shared_ptr<char > argInUtf8 = WcharMbcsConverter::wchar2char (argv[currentArg]);
258
+ PyObject* unicodeArg = PyUnicode_FromString (argInUtf8.get ());
179
259
180
260
argvList.append (boost::python::handle<>(unicodeArg));
181
- }
261
+ }
182
262
183
- boost::python::object sysModule (boost::python::handle<>(boost::python::borrowed (PyImport_AddModule (" sys" ))));
184
- sysModule.attr (" argv" ) = argvList;
263
+ boost::python::object sysModule (boost::python::handle<>(boost::python::borrowed (PyImport_AddModule (" sys" ))));
264
+ sysModule.attr (" argv" ) = argvList;
185
265
186
266
187
267
}
@@ -286,7 +366,7 @@ void PythonHandler::consume(std::shared_ptr<RunScriptArgs> args)
286
366
void PythonHandler::runScriptWorker (const std::shared_ptr<RunScriptArgs>& args)
287
367
{
288
368
289
- GILLock gilLock;
369
+ GILLock gilLock;
290
370
291
371
if (args->m_isStatement )
292
372
{
@@ -296,7 +376,7 @@ void PythonHandler::runScriptWorker(const std::shared_ptr<RunScriptArgs>& args)
296
376
{
297
377
mp_console->writeText (boost::python::str (" \n " ));
298
378
}
299
-
379
+
300
380
if (ConfigFile::getInstance ()->getSetting (_T (" OPENCONSOLEONERROR" )) == _T (" 1" ))
301
381
{
302
382
mp_console->pythonShowDialog ();
@@ -314,7 +394,7 @@ void PythonHandler::runScriptWorker(const std::shared_ptr<RunScriptArgs>& args)
314
394
{
315
395
mp_console->writeText (boost::python::str (" \n " ));
316
396
}
317
-
397
+
318
398
if (ConfigFile::getInstance ()->getSetting (_T (" OPENCONSOLEONERROR" )) == _T (" 1" ))
319
399
{
320
400
mp_console->pythonShowDialog ();
@@ -368,7 +448,7 @@ void PythonHandler::stopScript()
368
448
369
449
void PythonHandler::stopScriptWorker (PythonHandler *handler)
370
450
{
371
- GILLock gilLock;
451
+ GILLock gilLock;
372
452
373
453
PyThreadState_SetAsyncExc ((long )handler->getExecutingThreadID (), PyExc_KeyboardInterrupt);
374
454
0 commit comments