@@ -49,18 +49,8 @@ QgsPythonUtilsImpl::~QgsPythonUtilsImpl()
49
49
#endif
50
50
}
51
51
52
- void QgsPythonUtilsImpl::initPython ( QgisInterface* interface )
53
- {
54
- // initialize python
55
- Py_Initialize ();
56
-
57
- // initialize threading AND acquire GIL
58
- PyEval_InitThreads ();
59
-
60
- mPythonEnabled = true ;
52
+ bool QgsPythonUtilsImpl::checkSystemImports () {
61
53
62
- mMainModule = PyImport_AddModule ( " __main__" ); // borrowed reference
63
- mMainDict = PyModule_GetDict ( mMainModule ); // borrowed reference
64
54
65
55
runString ( " import sys" ); // import sys module (for display / exception hooks)
66
56
runString ( " import os" ); // import os module (for user paths)
@@ -116,8 +106,7 @@ void QgsPythonUtilsImpl::initPython( QgisInterface* interface )
116
106
if ( !runString ( " import sip" ,
117
107
QObject::tr ( " Couldn't load SIP module." ) + " \n " + QObject::tr ( " Python support will be disabled." ) ) )
118
108
{
119
- exitPython ();
120
- return ;
109
+ return false ;
121
110
}
122
111
123
112
// set PyQt4 api versions
@@ -128,36 +117,40 @@ void QgsPythonUtilsImpl::initPython( QgisInterface* interface )
128
117
if ( !runString ( QString ( " sip.setapi('%1', 2)" ).arg ( clsName ),
129
118
QObject::tr ( " Couldn't set SIP API versions." ) + " \n " + QObject::tr ( " Python support will be disabled." ) ) )
130
119
{
131
- exitPython ();
132
- return ;
120
+ return false ;
133
121
}
134
122
}
135
123
136
124
// import Qt bindings
137
125
if ( !runString ( " from PyQt4 import QtCore, QtGui" ,
138
126
QObject::tr ( " Couldn't load PyQt4." ) + " \n " + QObject::tr ( " Python support will be disabled." ) ) )
139
127
{
140
- exitPython ();
141
- return ;
128
+ return false ;
142
129
}
143
130
144
131
// import QGIS bindings
145
132
QString error_msg = QObject::tr ( " Couldn't load PyQGIS." ) + " \n " + QObject::tr ( " Python support will be disabled." );
146
133
if ( !runString ( " from qgis.core import *" , error_msg ) || !runString ( " from qgis.gui import *" , error_msg ) )
147
134
{
148
- exitPython ();
149
- return ;
135
+ return false ;
150
136
}
151
137
138
+ #ifdef HAVE_SERVER_PYTHON_PLUGINS
139
+ // This is the main difference with initInterface() for desktop plugins
140
+ // import QGIS Server bindings
141
+ error_msg = QObject::tr ( " Couldn't load PyQGIS Server." ) + " \n " + QObject::tr ( " Python support will be disabled." );
142
+ if ( !runString ( " from qgis.server import *" , error_msg ) )
143
+ {
144
+ return false ;
145
+ }
146
+ #endif
152
147
// import QGIS utils
153
148
error_msg = QObject::tr ( " Couldn't load QGIS utils." ) + " \n " + QObject::tr ( " Python support will be disabled." );
154
149
if ( !runString ( " import qgis.utils" , error_msg ) )
155
150
{
156
- exitPython ();
157
- return ;
151
+ return false ;
158
152
}
159
153
160
-
161
154
// tell the utils script where to look for the plugins
162
155
runString ( " qgis.utils.plugin_paths = [" + pluginpaths.join ( " ," ) + " ]" );
163
156
runString ( " qgis.utils.sys_plugin_path = \" " + pluginsPath () + " \" " );
@@ -167,167 +160,81 @@ void QgsPythonUtilsImpl::initPython( QgisInterface* interface )
167
160
runString ( " if oldhome: os.environ['HOME']=oldhome\n " );
168
161
#endif
169
162
170
- // initialize 'iface' object
171
- runString ( " qgis.utils.initInterface(" + QString::number (( unsigned long ) interface ) + " )" );
172
-
173
- // import QGIS user
174
- error_msg = QObject::tr ( " Couldn't load qgis.user." ) + " \n " + QObject::tr ( " Python support will be disabled." );
175
- if ( !runString ( " import qgis.user" , error_msg ) )
176
- {
177
- // Should we really bail because of this?!
178
- exitPython ();
179
- return ;
180
- }
181
-
182
- // release GIL!
183
- // Later on, we acquire GIL just before doing some Python calls and
184
- // release GIL again when the work with Python API is done.
185
- // (i.e. there must be PyGILState_Ensure + PyGILState_Release pair
186
- // around any calls to Python API, otherwise we may segfault!)
187
- _mainState = PyEval_SaveThread ();
163
+ return true ;
188
164
}
189
-
190
-
191
- #ifdef HAVE_SERVER_PYTHON_PLUGINS
192
- void QgsPythonUtilsImpl::initServerPython ( QgsServerInterface* interface )
193
- {
165
+ void QgsPythonUtilsImpl::init () {
194
166
// initialize python
195
167
Py_Initialize ();
196
-
197
168
// initialize threading AND acquire GIL
198
169
PyEval_InitThreads ();
199
170
200
171
mPythonEnabled = true ;
201
172
202
173
mMainModule = PyImport_AddModule ( " __main__" ); // borrowed reference
203
174
mMainDict = PyModule_GetDict ( mMainModule ); // borrowed reference
175
+ }
204
176
205
- runString ( " import sys" ); // import sys module (for display / exception hooks)
206
- runString ( " import os" ); // import os module (for user paths)
207
-
208
- // support for PYTHONSTARTUP-like environment variable: PYQGIS_STARTUP
209
- // (unlike PYTHONHOME and PYTHONPATH, PYTHONSTARTUP is not supported for embedded interpreter by default)
210
- // this is different than user's 'startup.py' (below), since it is loaded just after Py_Initialize
211
- // it is very useful for cleaning sys.path, which may have undesireable paths, or for
212
- // isolating/loading the initial environ without requiring a virt env, e.g. homebrew or MacPorts installs on Mac
213
- runString ( " pyqgstart = os.getenv('PYQGIS_STARTUP')\n " );
214
- runString ( " if pyqgstart is not None and os.path.exists(pyqgstart): execfile(pyqgstart)\n " );
215
-
216
- #ifdef Q_OS_WIN
217
- runString ( " oldhome=None" );
218
- runString ( " if os.environ.has_key('HOME'): oldhome=os.environ['HOME']\n " );
219
- runString ( " os.environ['HOME']=os.environ['USERPROFILE']\n " );
220
- #endif
177
+ void QgsPythonUtilsImpl::finish () {
178
+ // release GIL!
179
+ // Later on, we acquire GIL just before doing some Python calls and
180
+ // release GIL again when the work with Python API is done.
181
+ // (i.e. there must be PyGILState_Ensure + PyGILState_Release pair
182
+ // around any calls to Python API, otherwise we may segfault!)
183
+ _mainState = PyEval_SaveThread ();
184
+ }
221
185
222
- // construct a list of plugin paths
223
- // plugin dirs passed in QGIS_PLUGINPATH env. variable have highest priority (usually empty)
224
- // locally installed plugins have priority over the system plugins
225
- // use os.path.expanduser to support usernames with special characters (see #2512)
226
- QStringList pluginpaths;
227
- foreach ( QString p, extraPluginsPaths () )
186
+ bool QgsPythonUtilsImpl::checkQgisUser () {
187
+ // import QGIS user
188
+ QString error_msg = QObject::tr ( " Couldn't load qgis.user." ) + " \n " + QObject::tr ( " Python support will be disabled." );
189
+ if ( !runString ( " import qgis.user" , error_msg ) )
228
190
{
229
- if ( !QDir ( p ).exists () )
230
- {
231
- QgsMessageOutput* msg = QgsMessageOutput::createMessageOutput ();
232
- msg->setTitle ( QObject::tr ( " Python error" ) );
233
- msg->setMessage ( QString ( QObject::tr ( " The extra plugin path '%1' does not exist !" ) ).arg ( p ), QgsMessageOutput::MessageText );
234
- msg->showMessage ();
235
- }
236
- #ifdef Q_OS_WIN
237
- p = p.replace ( ' \\ ' , " \\\\ " );
238
- #endif
239
- // we store here paths in unicode strings
240
- // the str constant will contain utf8 code (through runString)
241
- // so we call '...'.decode('utf-8') to make a unicode string
242
- pluginpaths << ' "' + p + " \" .decode('utf-8')" ;
191
+ // Should we really bail because of this?!
192
+ return false ;
243
193
}
244
- pluginpaths << homePluginsPath () ;
245
- pluginpaths << ' " ' + pluginsPath () + ' " ' ;
194
+ return true ;
195
+ }
246
196
247
- // expect that bindings are installed locally, so add the path to modules
248
- // also add path to plugins
249
- QStringList newpaths;
250
- newpaths << ' "' + pythonPath () + ' "' ;
251
- newpaths << homePythonPath ();
252
- newpaths << pluginpaths;
253
- runString ( " sys.path = [" + newpaths.join ( " ," ) + " ] + sys.path" );
197
+ void QgsPythonUtilsImpl::doUserImports () {
254
198
255
- // import SIP
256
- if ( !runString ( " import sip" ,
257
- QObject::tr ( " Couldn't load SIP module." ) + " \n " + QObject::tr ( " Python support will be disabled." ) ) )
258
- {
259
- exitPython ();
260
- return ;
261
- }
199
+ QString startuppath = homePythonPath () + " + \" /startup.py\" " ;
200
+ runString ( " if os.path.exists(" + startuppath + " ): from startup import *\n " );
201
+ }
262
202
263
- // set PyQt4 api versions
264
- QStringList apiV2classes;
265
- apiV2classes << " QDate" << " QDateTime" << " QString" << " QTextStream" << " QTime" << " QUrl" << " QVariant" ;
266
- foreach ( const QString& clsName, apiV2classes )
267
- {
268
- if ( !runString ( QString ( " sip.setapi('%1', 2)" ).arg ( clsName ),
269
- QObject::tr ( " Couldn't set SIP API versions." ) + " \n " + QObject::tr ( " Python support will be disabled." ) ) )
270
- {
203
+ void QgsPythonUtilsImpl::initPython ( QgisInterface* interface )
204
+ {
205
+ init ();
206
+ if (!checkSystemImports ()){
271
207
exitPython ();
272
208
return ;
273
- }
274
209
}
275
-
276
- // import Qt bindings
277
- if ( !runString ( " from PyQt4 import QtCore, QtGui" ,
278
- QObject::tr ( " Couldn't load PyQt4." ) + " \n " + QObject::tr ( " Python support will be disabled." ) ) )
279
- {
280
- exitPython ();
281
- return ;
282
- }
283
-
284
- // import QGIS bindings
285
- QString error_msg = QObject::tr ( " Couldn't load PyQGIS." ) + " \n " + QObject::tr ( " Python support will be disabled." );
286
- if ( !runString ( " from qgis.core import *" , error_msg ) || !runString ( " from qgis.gui import *" , error_msg ) )
287
- {
288
- exitPython ();
289
- return ;
210
+ // initialize 'iface' object
211
+ runString ( " qgis.utils.initInterface(" + QString::number (( unsigned long ) interface ) + " )" );
212
+ if (!checkQgisUser ()) {
213
+ exitPython ();
214
+ return ;
290
215
}
216
+ doUserImports ();
217
+ finish ();
218
+ }
291
219
292
- // This is the main difference with initInterface() for desktop plugins
293
- // import QGIS Server bindings
294
- error_msg = QObject::tr ( " Couldn't load PyQGIS Server." ) + " \n " + QObject::tr ( " Python support will be disabled." );
295
- if ( !runString ( " from qgis.server import *" , error_msg ) )
296
- {
297
- exitPython ();
298
- return ;
299
- }
300
220
221
+ #ifdef HAVE_SERVER_PYTHON_PLUGINS
222
+ void QgsPythonUtilsImpl::initServerPython ( QgsServerInterface* interface )
223
+ {
301
224
302
- // import QGIS utils
303
- error_msg = QObject::tr ( " Couldn't load QGIS utils." ) + " \n " + QObject::tr ( " Python support will be disabled." );
304
- if ( !runString ( " import qgis.utils" , error_msg ) )
305
- {
306
- exitPython ();
307
- return ;
225
+ init ();
226
+ if (!checkSystemImports ()){
227
+ exitPython ();
228
+ return ;
308
229
}
309
-
310
- // tell the utils script where to look for the plugins
311
- runString ( " qgis.utils.plugin_paths = [" + pluginpaths.join ( " ," ) + " ]" );
312
- runString ( " qgis.utils.sys_plugin_path = \" " + pluginsPath () + " \" " );
313
- runString ( " qgis.utils.home_plugin_path = " + homePluginsPath () );
314
-
315
- #ifdef Q_OS_WIN
316
- runString ( " if oldhome: os.environ['HOME']=oldhome\n " );
317
- #endif
318
-
319
230
// This is the other main difference with initInterface() for desktop plugins
320
231
runString ( " qgis.utils.initServerInterface(" + QString::number (( unsigned long ) interface ) + " )" );
321
-
322
- QString startuppath = homePythonPath () + " + \" /startup.py\" " ;
323
- runString ( " if os.path.exists(" + startuppath + " ): from startup import *\n " );
324
-
325
- // release GIL!
326
- // Later on, we acquire GIL just before doing some Python calls and
327
- // release GIL again when the work with Python API is done.
328
- // (i.e. there must be PyGILState_Ensure + PyGILState_Release pair
329
- // around any calls to Python API, otherwise we may segfault!)
330
- _mainState = PyEval_SaveThread ();
232
+ if (!checkQgisUser ()){
233
+ exitPython ();
234
+ return ;
235
+ }
236
+ doUserImports ();
237
+ finish ();
331
238
}
332
239
333
240
bool QgsPythonUtilsImpl::startServerPlugin ( QString packageName )
0 commit comments