|
@@ -210,22 +210,41 @@ static class Python27GlobalState
|
|
|
public:
|
|
|
Python27GlobalState()
|
|
|
{
|
|
|
+#ifndef _WIN32
|
|
|
+ // If Py_Initialize is called when stdin is set to a directory, it calls exit()
|
|
|
+ // We don't want that to happen - just disable Python support in such situations
|
|
|
+ struct stat sb;
|
|
|
+ if (fstat(fileno(stdin), &sb) == 0 && S_ISDIR(sb.st_mode))
|
|
|
+ {
|
|
|
+ initialized = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+#endif
|
|
|
// Initialize the Python Interpreter
|
|
|
Py_Initialize();
|
|
|
PyEval_InitThreads();
|
|
|
tstate = PyEval_SaveThread();
|
|
|
+ initialized = true;
|
|
|
}
|
|
|
~Python27GlobalState()
|
|
|
{
|
|
|
if (threadContext)
|
|
|
delete threadContext; // The one on the main thread won't get picked up by the thread hook mechanism
|
|
|
threadContext = NULL;
|
|
|
- PyEval_RestoreThread(tstate);
|
|
|
- // Finish the Python Interpreter
|
|
|
- Py_Finalize();
|
|
|
+ if (initialized)
|
|
|
+ {
|
|
|
+ PyEval_RestoreThread(tstate);
|
|
|
+ // Finish the Python Interpreter
|
|
|
+ Py_Finalize();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bool isInitialized()
|
|
|
+ {
|
|
|
+ return initialized;
|
|
|
}
|
|
|
protected:
|
|
|
PyThreadState *tstate;
|
|
|
+ bool initialized;
|
|
|
} globalState;
|
|
|
|
|
|
// Each call to a Python function will use a new Python27EmbedFunctionContext object
|
|
@@ -704,6 +723,8 @@ public:
|
|
|
{
|
|
|
if (!threadContext)
|
|
|
{
|
|
|
+ if (!globalState.isInitialized())
|
|
|
+ rtlFail(0, "Python not initialized");
|
|
|
threadContext = new PythonThreadContext;
|
|
|
threadHookChain = addThreadTermFunc(releaseContext);
|
|
|
}
|