ATLAS Offline Software
initPyInterpreter.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // initPyInterpreter.cxx
8 // state of the art initialization of the python interpreter
9 // Author: S.Binet<binet@cern.ch>
11 
12 // Python
13 #include "Python.h"
14 // fixes 'dereferencing type-punned pointer will break strict-aliasing rules'
15 #ifdef Py_True
16 #undef Py_True
17 #define Py_True ( (PyObject*)(void*)&_Py_TrueStruct )
18 #endif
19 #ifdef Py_False
20 #undef Py_False
21 #define Py_False ( (PyObject*)(void*)&_Py_ZeroStruct )
22 #endif
23 
25 
26 // gaudi
27 #include "GaudiKernel/System.h"
28 #include "GaudiKernel/StatusCode.h"
29 
30 #include <locale>
31 #include <codecvt>
32 
33 namespace {
36  void report_py_exception (bool display = true)
37  {
38  if (display) {
39  // fetch error
40  PyObject* pytype = nullptr, *pyvalue = nullptr, *pytrace = nullptr;
41  PyErr_Fetch (&pytype, &pyvalue, &pytrace);
42  Py_XINCREF (pytype);
43  Py_XINCREF (pyvalue);
44  Py_XINCREF (pytrace);
45  // restore...
46  PyErr_Restore (pytype, pyvalue, pytrace);
47  // and print
48  PyErr_Print();
49  }
50  }
51 }
52 
53 namespace AthenaInternal {
58 
61 {
62  if (Py_IsInitialized()) {
63  return StatusCode::SUCCESS;
64  }
65 
66  /*
67  * The GIL is initialized by Py_Initialize() since Python 3.7."
68  */
69 
70 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 11
71  Py_Initialize();
72 
73  if (!Py_IsInitialized()) {
74  ::report_py_exception();
75  return StatusCode::FAILURE;
76  }
77 
78  // init the sys.argv...
79  auto wargsinit =
80  []() { std::vector<std::wstring> wargs;
81  int argc = System::argc();
82  char** argv = System::argv();
83  wargs.reserve (argc);
84  using convert_t = std::codecvt_utf8<wchar_t>;
85  std::wstring_convert<convert_t, wchar_t> strconverter;
86  for (int i=0; i < argc; ++i) {
87  wargs.push_back (strconverter.from_bytes (argv[i]));
88  }
89  return wargs;
90  };
91  static const std::vector<std::wstring> wargs = wargsinit();
92 
93  auto wargvinit =
94  [](const std::vector<std::wstring>& wargs)
95  { std::vector<const wchar_t*> wargv;
96  int argc = System::argc();
97  for (int i=0; i < argc; ++i) {
98  wargv.push_back (wargs[i].data());
99  }
100  return wargv;
101  };
102  static const std::vector<const wchar_t*> wargv = wargvinit (wargs);
103 
104  // Bleh --- python takes non-const argv pointers.
105  wchar_t** wargv_nc ATLAS_THREAD_SAFE = const_cast<wchar_t**> (wargv.data());
106  PySys_SetArgv(System::argc(), wargv_nc);
107 #else
108  PyConfig config;
109  PyConfig_InitPythonConfig (&config);
110  PyStatus status = PyConfig_SetBytesArgv (&config, System::argc(),
111  System::argv());
112  if (PyStatus_Exception (status)) {
113  report_py_exception();
114  PyConfig_Clear (&config);
115  return StatusCode::FAILURE;
116  }
117 
118  status = Py_InitializeFromConfig (&config);
119  if (PyStatus_Exception (status)) {
120  report_py_exception();
121  PyConfig_Clear (&config);
122  return StatusCode::FAILURE;
123  }
124  PyConfig_Clear (&config);
125 #endif
126  return StatusCode::SUCCESS;
127 }
128 
129 } //> !AthenaInternal
130 
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
AthenaInternal::initPyInterpreter
StatusCode initPyInterpreter()
correctly initialize the python interpreter in case it hasn't been done yet.
Definition: initPyInterpreter.cxx:60
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
AthenaInternal
Definition: AthenaPythonDict.h:31
lumiFormat.i
int i
Definition: lumiFormat.py:92
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
pyroot.display
display
Definition: pyroot.py:44
config
std::vector< std::string > config
Definition: fbtTestBasics.cxx:72
merge.status
status
Definition: merge.py:17
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
checker_macros.h
Define macros for attributes used to control the static checker.
PyObject
_object PyObject
Definition: IPyComponent.h:26