ATLAS Offline Software
Loading...
Searching...
No Matches
initPyInterpreter.cxx
Go to the documentation of this file.
1
2
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
33namespace {
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
53namespace 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
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
_object PyObject
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
StatusCode initPyInterpreter()
correctly initialize the python interpreter in case it hasn't been done yet.
::StatusCode StatusCode
StatusCode definition for legacy code.