comparison Sources/PythonModule.cpp @ 0:7ed502b17b8f

initial commit
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 26 Mar 2020 18:47:01 +0100
parents
children fd58eb5749ed
comparison
equal deleted inserted replaced
-1:000000000000 0:7ed502b17b8f
1 /**
2 * Python plugin for Orthanc
3 * Copyright (C) 2017-2020 Osimis S.A., Belgium
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 "PythonModule.h"
21
22 #include "PythonString.h"
23
24 #include <OrthancPluginCppWrapper.h>
25
26 #include <boost/thread/mutex.hpp>
27 #include <set>
28
29
30 #if PY_VERSION_HEX < 0x03070000 /* 3.7.0 */
31 static PythonObject* GetModule(PythonLock& lock,
32 const std::string& utf8Name)
33 {
34 static boost::mutex mutex_;
35 static std::set<std::string> loadedModules_;
36
37 boost::mutex::scoped_lock l(mutex_);
38
39 if (loadedModules_.find(utf8Name) == loadedModules_.end())
40 {
41 PythonString tmp(lock, utf8Name);
42
43 // The module is not imported yet
44 loadedModules_.insert(utf8Name);
45 return new PythonObject(lock, PyImport_Import(tmp.GetPyObject()), false);
46 }
47 else
48 {
49 // PyImport_AddModule returns a borrowed reference
50 return new PythonObject(lock, PyImport_AddModule(utf8Name.c_str()), true);
51 }
52 }
53
54 #else
55 // The "PyImport_GetModule()" function was introduced in Python
56 // 3.7.0
57 static PythonObject* GetModule(PythonLock& lock,
58 const std::string& utf8Name)
59 {
60 PythonString tmp(lock, utf8Name);
61
62 PyObject* module = PyImport_GetModule(tmp.GetPyObject());
63 if (module != NULL)
64 {
65 // The module was already imported by a previous call: Reuse it
66 return new PythonObject(lock, module);
67 }
68 else
69 {
70 // This is the first time this module is used: Import it
71 return new PythonObject(lock, PyImport_Import(tmp.GetPyObject()));
72 }
73 }
74 #endif
75
76
77 PythonModule::PythonModule(PythonLock& lock,
78 const std::string& utf8Name) :
79 lock_(lock),
80 name_(utf8Name)
81 {
82 module_.reset(GetModule(lock, utf8Name));
83 }
84
85
86 bool PythonModule::IsValid() const
87 {
88 return (module_.get() != NULL &&
89 module_->IsValid());
90 }
91
92
93 PythonObject& PythonModule::GetObject() const
94 {
95 if (!IsValid())
96 {
97 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls);
98 }
99 else
100 {
101 return *module_;
102 }
103 }
104
105
106 PyObject* PythonModule::GetPyObject() const
107 {
108 if (!IsValid())
109 {
110 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls);
111 }
112 else
113 {
114 return module_->GetPyObject();
115 }
116 }