Mercurial > hg > orthanc-python
annotate Sources/PythonLock.cpp @ 75:cbfc72a53970
refactoring calls to PythonLock::RaiseException()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 09 Aug 2021 16:59:59 +0200 |
parents | 32de70a1e4c7 |
children | e7ff5efb100d |
rev | line source |
---|---|
0 | 1 /** |
2 * Python plugin for Orthanc | |
56
23f3099bed47
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
45
diff
changeset
|
3 * Copyright (C) 2020-2021 Osimis S.A., Belgium |
0 | 4 * |
5 * This program is free software: you can redistribute it and/or | |
6 * modify it under the terms of the GNU Affero General Public License | |
7 * as published by the Free Software Foundation, either version 3 of | |
8 * the License, or (at your option) any later version. | |
9 * | |
10 * This program is distributed in the hope that it will be useful, but | |
11 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Affero General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Affero General Public License | |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 **/ | |
18 | |
19 | |
20 #include "PythonLock.h" | |
21 | |
22 #include "PythonFunction.h" | |
23 #include "PythonModule.h" | |
45
ee76cced46a5
Fix issue #185 (segfaults on non-UTF8 special characters in request URI)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
24 #include "PythonString.h" |
0 | 25 |
36
fd58eb5749ed
CMake simplification using DownloadOrthancFramework.cmake
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
26 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" |
fd58eb5749ed
CMake simplification using DownloadOrthancFramework.cmake
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
27 |
fd58eb5749ed
CMake simplification using DownloadOrthancFramework.cmake
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
28 #include <Compatibility.h> // For std::unique_ptr<> |
0 | 29 |
30 #include <boost/thread/mutex.hpp> | |
31 | |
32 static boost::mutex mutex_; | |
33 static PyThreadState* interpreterState_ = NULL; | |
34 static PythonLock::ModuleFunctionsInstaller moduleFunctions_ = NULL; | |
35 static PythonLock::ModuleClassesInstaller moduleClasses_ = NULL; | |
36 static std::string moduleName_; | |
37 static std::string exceptionName_; | |
28
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
38 static bool verbose_ = false; |
0 | 39 |
40 | |
41 struct module_state | |
42 { | |
43 PyObject *exceptionClass_ = NULL; | |
44 }; | |
45 | |
46 #if PY_MAJOR_VERSION >= 3 | |
47 # define GETSTATE(module) ((struct module_state*) PyModule_GetState(module)) | |
48 #else | |
49 # define GETSTATE(module) (&_state) | |
50 static struct module_state _state; | |
51 #endif | |
52 | |
53 | |
13 | 54 PythonLock::PythonLock() : |
55 gstate_(PyGILState_Ensure()) | |
0 | 56 { |
57 //OrthancPlugins::LogInfo("Python lock (GIL) acquired"); | |
58 } | |
59 | |
60 | |
61 PythonLock::~PythonLock() | |
62 { | |
63 PyGILState_Release(gstate_); | |
64 //OrthancPlugins::LogInfo("Python lock (GIL) released"); | |
65 } | |
66 | |
67 | |
68 void PythonLock::ExecuteCommand(const std::string& s) | |
69 { | |
70 if (PyRun_SimpleString(s.c_str()) != 0) | |
71 { | |
72 OrthancPlugins::LogError("Error while executing a Python command"); | |
73 ORTHANC_PLUGINS_THROW_EXCEPTION(Plugin); | |
74 } | |
75 } | |
76 | |
77 | |
78 void PythonLock::ExecuteFile(const std::string& path) | |
79 { | |
80 OrthancPlugins::MemoryBuffer buffer; | |
81 buffer.ReadFile(path); | |
82 | |
83 std::string script; | |
84 buffer.ToString(script); | |
85 | |
86 ExecuteCommand(script); | |
87 } | |
88 | |
89 | |
90 bool PythonLock::HasErrorOccurred(std::string& target) | |
91 { | |
92 if (PyErr_Occurred()) | |
93 { | |
94 PyObject *exceptionType = NULL; | |
95 PyObject *exceptionValue = NULL; | |
96 PyObject *traceback = NULL; | |
97 PyErr_Fetch(&exceptionType, &exceptionValue, &traceback); | |
98 | |
99 if (exceptionType == NULL) | |
100 { | |
101 return false; | |
102 } | |
103 | |
104 PyErr_NormalizeException(&exceptionType, &exceptionValue, &traceback); | |
105 | |
106 #if PY_MAJOR_VERSION >= 3 | |
107 if (traceback != NULL) | |
108 { | |
109 PyException_SetTraceback(exceptionValue, traceback); | |
110 } | |
111 #endif | |
112 | |
113 if (exceptionType != NULL) | |
114 { | |
115 PythonObject temp(*this, PyObject_Str(exceptionType)); | |
116 std::string s; | |
117 if (temp.ToUtf8String(s)) | |
118 { | |
119 target += s + "\n"; | |
120 } | |
121 } | |
122 | |
123 if (exceptionValue != NULL) | |
124 { | |
125 PythonObject temp(*this, PyObject_Str(exceptionValue)); | |
126 std::string s; | |
127 if (temp.ToUtf8String(s)) | |
128 { | |
129 target += s + "\n"; | |
130 } | |
131 } | |
132 | |
133 { | |
134 PythonModule module(*this, "traceback"); | |
135 PythonFunction f(*this, module, "format_tb"); | |
136 | |
137 if (traceback != NULL && | |
138 f.IsValid()) | |
139 { | |
140 PythonObject args(*this, PyTuple_New(1)); | |
141 PyTuple_SetItem(args.GetPyObject(), 0, traceback); | |
142 | |
36
fd58eb5749ed
CMake simplification using DownloadOrthancFramework.cmake
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
143 std::unique_ptr<PythonObject> value(f.CallUnchecked(args.GetPyObject())); |
0 | 144 |
145 if (value->IsValid()) | |
146 { | |
147 Py_ssize_t len = PyList_Size(value->GetPyObject()); | |
148 for (Py_ssize_t i = 0; i < len; i++) | |
149 { | |
150 PythonObject item(*this, PyList_GetItem(value->GetPyObject(), i), true /* borrowed */); | |
151 std::string line; | |
152 if (item.ToUtf8String(line)) | |
153 { | |
154 target += "\n" + line; | |
155 } | |
156 } | |
157 } | |
158 } | |
159 } | |
160 | |
161 | |
162 /** | |
163 * "This call takes away a reference to each object: you must own | |
164 * a reference to each object before the call and after the call | |
165 * you no longer own these references. (If you don't understand | |
166 * this, don't use this function. I warned you.)" | |
167 * => I don't use PyErr_Restore() | |
168 **/ | |
169 | |
170 //PyErr_Restore(exceptionType, exceptionValue, traceback); | |
171 //PyErr_Clear(); | |
172 | |
173 return true; | |
174 } | |
175 else | |
176 { | |
177 return false; | |
178 } | |
179 } | |
180 | |
181 | |
182 static void RegisterException(PyObject* module, | |
183 const std::string& name) | |
184 { | |
185 struct module_state *state = GETSTATE(module); | |
186 | |
187 state->exceptionClass_ = PyErr_NewException(const_cast<char*>(name.c_str()), NULL, NULL); | |
188 if (state->exceptionClass_ == NULL) | |
189 { | |
190 Py_DECREF(module); | |
191 OrthancPlugins::LogError("Cannot create the Python exception class"); | |
192 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
193 } | |
194 | |
195 #if 1 | |
196 Py_XINCREF(state->exceptionClass_); | |
197 if (PyModule_AddObject(module, "Exception", state->exceptionClass_) < 0) | |
198 { | |
199 Py_XDECREF(state->exceptionClass_); | |
200 Py_CLEAR(state->exceptionClass_); | |
201 OrthancPlugins::LogError("Cannot create the Python exception class"); | |
202 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
203 } | |
204 #else | |
205 // Install the exception class | |
206 PyObject* dict = PyModule_GetDict(module); | |
207 PyDict_SetItemString(dict, "Exception", state->exceptionClass); | |
208 #endif | |
209 } | |
210 | |
211 | |
212 | |
213 #if PY_MAJOR_VERSION >= 3 | |
214 | |
215 static int sdk_traverse(PyObject *module, visitproc visit, void *arg) | |
216 { | |
217 Py_VISIT(GETSTATE(module)->exceptionClass_); | |
218 return 0; | |
219 } | |
220 | |
221 static int sdk_clear(PyObject *module) | |
222 { | |
223 Py_CLEAR(GETSTATE(module)->exceptionClass_); | |
224 return 0; | |
225 } | |
226 | |
227 static struct PyModuleDef moduledef = | |
228 { | |
229 PyModuleDef_HEAD_INIT, | |
230 NULL, /* m_name => TO BE FILLED */ | |
231 NULL, | |
232 sizeof(struct module_state), | |
233 NULL, /* m_methods => TO BE FILLED */ | |
234 NULL, | |
235 sdk_traverse, | |
236 sdk_clear, | |
237 NULL | |
238 }; | |
239 | |
240 | |
241 PyMODINIT_FUNC InitializeModule() | |
242 { | |
243 if (moduleFunctions_ == NULL || | |
244 moduleClasses_ == NULL || | |
245 moduleName_.empty() || | |
246 exceptionName_.empty()) | |
247 { | |
248 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
249 } | |
250 | |
251 moduledef.m_name = moduleName_.c_str(); | |
252 moduledef.m_methods = moduleFunctions_(); | |
253 | |
254 PyObject *module = PyModule_Create(&moduledef); | |
255 if (module == NULL) | |
256 { | |
257 OrthancPlugins::LogError("Cannot create a Python module"); | |
258 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
259 } | |
260 | |
261 RegisterException(module, moduleName_ + "." + exceptionName_); | |
262 moduleClasses_(module); | |
263 | |
264 return module; | |
265 } | |
266 | |
267 #else | |
268 | |
269 void InitializeModule() | |
270 { | |
271 if (moduleFunctions_ == NULL || | |
272 moduleClasses_ == NULL || | |
273 moduleName_.empty() || | |
274 exceptionName_.empty()) | |
275 { | |
276 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
277 } | |
278 | |
279 PyObject *module = Py_InitModule(moduleName_.c_str(), moduleFunctions_()); | |
280 if (module == NULL) | |
281 { | |
282 OrthancPlugins::LogError("Cannot create a Python module"); | |
283 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
284 } | |
285 | |
286 RegisterException(module, moduleName_ + "." + exceptionName_); | |
287 moduleClasses_(module); | |
288 } | |
289 | |
290 #endif | |
291 | |
292 | |
293 | |
63
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
294 OrthancPluginErrorCode PythonLock::CheckCallbackSuccess(const std::string& callbackDetails) |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
295 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
296 std::string traceback; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
297 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
298 if (HasErrorOccurred(traceback)) |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
299 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
300 OrthancPlugins::LogError("Error in the " + callbackDetails + ", traceback:\n" + traceback); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
301 return OrthancPluginErrorCode_Plugin; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
302 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
303 else |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
304 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
305 return OrthancPluginErrorCode_Success; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
306 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
307 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
308 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
309 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
310 |
0 | 311 void PythonLock::GlobalInitialize(const std::string& moduleName, |
312 const std::string& exceptionName, | |
313 ModuleFunctionsInstaller moduleFunctions, | |
314 ModuleClassesInstaller moduleClasses, | |
315 bool verbose) | |
316 { | |
317 boost::mutex::scoped_lock lock(mutex_); | |
318 | |
319 if (interpreterState_ != NULL) | |
320 { | |
321 OrthancPlugins::LogError("Cannot initialize twice the Python interpreter"); | |
322 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); | |
323 } | |
324 | |
325 if (moduleClasses == NULL || | |
326 moduleFunctions == NULL) | |
327 { | |
328 ORTHANC_PLUGINS_THROW_EXCEPTION(NullPointer); | |
329 } | |
330 | |
331 if (moduleName.empty() || | |
332 exceptionName.empty()) | |
333 { | |
334 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
335 } | |
336 | |
337 if (exceptionName.find('.') != std::string::npos) | |
338 { | |
339 OrthancPlugins::LogError("The name of the exception cannot contain \".\", found: " + | |
340 exceptionName); | |
341 ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange); | |
342 } | |
343 | |
344 moduleClasses_ = moduleClasses; | |
345 moduleFunctions_ = moduleFunctions; | |
346 moduleName_ = moduleName; | |
347 exceptionName_ = exceptionName; | |
348 | |
349 std::string executable; | |
350 | |
351 { | |
352 OrthancPlugins::OrthancString str; | |
353 str.Assign(OrthancPluginGetOrthancPath(OrthancPlugins::GetGlobalContext())); | |
354 str.ToString(executable); | |
355 } | |
356 | |
357 OrthancPlugins::LogWarning("Program name: " + executable); | |
358 | |
359 #if PY_MAJOR_VERSION == 2 | |
360 Py_SetProgramName(&executable[0]); /* optional but recommended */ | |
361 #else | |
362 std::wstring wide(executable.begin(), executable.end()); | |
363 Py_SetProgramName(&wide[0]); /* optional but recommended */ | |
364 Py_UnbufferedStdioFlag = 1; // Write immediately to stdout after "sys.stdout.flush()" (only in Python 3.x) | |
365 #endif | |
366 | |
367 Py_InspectFlag = 1; // Don't exit the Orthanc process on Python error | |
368 | |
28
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
369 verbose_ = verbose; |
0 | 370 if (verbose) |
371 { | |
372 Py_VerboseFlag = 1; | |
373 } | |
374 | |
375 #if PY_MAJOR_VERSION >= 3 | |
376 PyImport_AppendInittab(moduleName_.c_str(), InitializeModule); | |
377 #endif | |
378 | |
379 #if PY_VERSION_HEX < 0x03020000 /* 3.2.0 */ | |
380 /** | |
381 * "Changed in version 3.2: This function cannot be called before | |
382 * Py_Initialize() anymore." | |
383 **/ | |
384 if (!PyEval_ThreadsInitialized()) | |
385 { | |
386 PyEval_InitThreads(); | |
387 } | |
388 #endif | |
389 | |
390 Py_InitializeEx(0 /* Python is embedded, skip signal handlers */); | |
391 | |
12 | 392 #if 0 |
0 | 393 #if PY_MAJOR_VERSION == 2 |
394 std::cout << Py_GetPath() << std::endl; | |
395 std::cout << Py_GetProgramName() << std::endl; | |
396 std::cout << Py_GetProgramFullPath() << std::endl; | |
397 #else | |
398 std::wcout << Py_GetPath() << std::endl; | |
399 std::wcout << Py_GetProgramName() << std::endl; | |
400 std::wcout << Py_GetProgramFullPath() << std::endl; | |
401 #endif | |
12 | 402 #endif |
0 | 403 |
404 #if (PY_VERSION_HEX >= 0x03020000 /* 3.2.0 */ && \ | |
405 PY_VERSION_HEX < 0x03070000 /* 3.7.0 */) | |
406 /** | |
407 * Changed in version 3.7: This function is now called by | |
408 * Py_Initialize(), so you don't have to call it yourself anymore. | |
409 **/ | |
410 if (!PyEval_ThreadsInitialized()) | |
411 { | |
412 PyEval_InitThreads(); | |
413 } | |
414 #endif | |
415 | |
416 | |
417 #if PY_MAJOR_VERSION == 2 | |
418 InitializeModule(); | |
419 #endif | |
420 | |
421 // https://fr.slideshare.net/YiLungTsai/embed-python => slide 26 | |
422 interpreterState_ = PyEval_SaveThread(); | |
423 } | |
424 | |
425 | |
426 void PythonLock::AddSysPath(const std::string& path) | |
427 { | |
428 /** | |
429 * "It is recommended that applications embedding the Python | |
430 * interpreter for purposes other than executing a single script | |
431 * pass 0 as updatepath, and update sys.path themselves if | |
432 * desired. See CVE-2008-5983." | |
433 * => Set "sys.path.append()" to the directory of the configuration file by default | |
434 **/ | |
435 | |
436 PythonLock lock; | |
437 | |
438 /** | |
439 * Initialization of "sys.path.append()" must be done before loading | |
440 * any module. | |
441 **/ | |
442 | |
443 PyObject *sysPath = PySys_GetObject(const_cast<char*>("path")); | |
444 if (sysPath == NULL) | |
445 { | |
446 OrthancPlugins::LogError("Cannot find sys.path"); | |
447 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
448 } | |
449 | |
45
ee76cced46a5
Fix issue #185 (segfaults on non-UTF8 special characters in request URI)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
450 PythonString pyPath(lock, path); |
ee76cced46a5
Fix issue #185 (segfaults on non-UTF8 special characters in request URI)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
451 int result = PyList_Insert(sysPath, 0, pyPath.Release()); |
0 | 452 |
453 if (result != 0) | |
454 { | |
455 OrthancPlugins::LogError("Cannot run sys.path.append()"); | |
456 ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError); | |
457 } | |
458 } | |
459 | |
460 | |
461 void PythonLock::GlobalFinalize() | |
462 { | |
463 boost::mutex::scoped_lock lock(mutex_); | |
464 | |
465 if (interpreterState_ != NULL) | |
466 { | |
467 PyEval_RestoreThread(interpreterState_); | |
468 interpreterState_ = NULL; | |
469 } | |
470 | |
471 Py_Finalize(); | |
472 } | |
473 | |
474 | |
75
cbfc72a53970
refactoring calls to PythonLock::RaiseException()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
63
diff
changeset
|
475 void PythonLock::RaiseException(OrthancPluginErrorCode code) |
0 | 476 { |
477 if (code != OrthancPluginErrorCode_Success) | |
478 { | |
75
cbfc72a53970
refactoring calls to PythonLock::RaiseException()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
63
diff
changeset
|
479 PyErr_SetString(PyExc_ValueError, "Internal error"); |
cbfc72a53970
refactoring calls to PythonLock::RaiseException()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
63
diff
changeset
|
480 |
cbfc72a53970
refactoring calls to PythonLock::RaiseException()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
63
diff
changeset
|
481 #if 0 |
0 | 482 const char* message = OrthancPluginGetErrorDescription(OrthancPlugins::GetGlobalContext(), code); |
483 | |
484 struct module_state *state = GETSTATE(module); | |
485 if (state->exceptionClass_ == NULL) | |
486 { | |
487 OrthancPlugins::LogError("No Python exception has been registered"); | |
488 } | |
489 else | |
490 { | |
491 PyErr_SetString(state->exceptionClass_, message); | |
492 } | |
75
cbfc72a53970
refactoring calls to PythonLock::RaiseException()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
63
diff
changeset
|
493 #endif |
0 | 494 } |
495 } | |
28
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
496 |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
497 |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
498 void PythonLock::LogCall(const std::string& message) |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
499 { |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
500 /** |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
501 * For purity, this function should lock the global "mutex_", but |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
502 * "verbose_" cannot change after the initial call to |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
503 * "GlobalInitialize()". |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
504 **/ |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
505 |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
506 if (verbose_) |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
507 { |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
508 OrthancPlugins::LogInfo(message); |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
509 } |
b2bbb516056e
The "Calling Python..." info logs are disabled if "PythonVerbose" is "false"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
510 } |