Skip to content

Commit

Permalink
Add some more Python error handling, logging, and search paths
Browse files Browse the repository at this point in the history
  • Loading branch information
stephengtuggy committed Jan 15, 2025
1 parent 481a838 commit ce9c51f
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 16 deletions.
29 changes: 27 additions & 2 deletions engine/src/python/config/python_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
#include <boost/python.hpp>
#include <boost/filesystem.hpp>

//#include "vsfilesystem.h"
//#include "vs_logging.h"

using namespace boost::python;
using namespace boost::filesystem;

Expand All @@ -55,6 +58,7 @@ std::string GetPythonPath() {
PyObject* GetClassFromPython(
const std::string build_path,
const std::string path_string,
const std::string datadir,
const std::string module_name,
const std::string function_name) {
boost::filesystem::path full_path = boost::filesystem::path(path_string);
Expand All @@ -72,6 +76,7 @@ PyObject* GetClassFromPython(

status = Py_PreInitialize(&py_pre_config);
if (PyStatus_Exception(status)) {
std::cerr << "Python pre-initialization failed" << std::endl << std::flush;
Py_ExitStatusException(status);
}

Expand All @@ -81,21 +86,39 @@ PyObject* GetClassFromPython(
const std::string python_sitelib_path = QUOTE(Python_SITELIB);
const std::wstring python_sitelib_path_wstring = std::wstring(python_sitelib_path.begin(), python_sitelib_path.end());
const std::wstring build_path_w = std::wstring(build_path.begin(), build_path.end());
const std::wstring data_path_w = std::wstring(datadir.begin(), datadir.end());

PyWideStringList python_path_py_wide_string_list{};
status = PyWideStringList_Append(&python_path_py_wide_string_list, python_path_w.c_str());
if (PyStatus_Exception(status)) {
std::cerr << "Python path list append 1 failed" << std::endl << std::flush;
PyErr_Print();
Py_ExitStatusException(status);
}
status = PyWideStringList_Append(&python_path_py_wide_string_list, path_string_w.c_str());
if (PyStatus_Exception(status)) {
std::cerr << "Python path list append 2 failed" << std::endl << std::flush;
PyErr_Print();
Py_ExitStatusException(status);
}
status = PyWideStringList_Append(&python_path_py_wide_string_list, python_sitelib_path_wstring.c_str());
if (PyStatus_Exception(status)) {
std::cerr << "Python path list append 3 failed" << std::endl << std::flush;
PyErr_Print();
Py_ExitStatusException(status);
}
status = PyWideStringList_Append(&python_path_py_wide_string_list, build_path_w.c_str());
if (PyStatus_Exception(status)) {
std::cerr << "Python path list append 4 failed" << std::endl << std::flush;
PyErr_Print();
Py_ExitStatusException(status);
}
status = PyWideStringList_Append(&python_path_py_wide_string_list, data_path_w.c_str());
if (PyStatus_Exception(status)) {
std::cerr << "Python path list append 5 failed" << std::endl << std::flush;
PyErr_Print();
Py_ExitStatusException(status);
}

PyConfig config;
PyConfig_InitPythonConfig(&config);
Expand All @@ -105,14 +128,16 @@ PyObject* GetClassFromPython(

status = Py_InitializeFromConfig(&config);
if (PyStatus_Exception(status)) {
std::cerr << "Python config initialization failed" << std::endl << std::flush;
PyErr_Print();
PyConfig_Clear(&config);
Py_ExitStatusException(status);
}

PyObject* module = PyImport_ImportModule(module_name.c_str());

if(!module) {
std::cerr << "PyImport_ImportModule is null\n" << std::flush;
std::cerr << "Python module import failed (PyImport_ImportModule is null)" << std::endl << std::flush;
PyErr_Print();
Py_Finalize();
// TODO: throw exception
Expand All @@ -121,7 +146,7 @@ PyObject* GetClassFromPython(

PyObject* function = PyObject_GetAttrString(module,function_name.c_str());
if(!function) {
std::cerr << "PyObject_GetAttrString is null\n" << std::flush;
std::cerr << "PyObject_GetAttrString is null" << std::endl << std::flush;
PyErr_Print();
Py_Finalize();
// TODO: throw exception
Expand Down
3 changes: 2 additions & 1 deletion engine/src/python/config/python_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ std::string GetPythonPath();
PyObject* GetClassFromPython(
std::string build_path,
std::wstring path_string,
std::string datadir,
std::string module_name,
std::string function_name);


#endif //VEGA_STRIKE_ENGINE_RESOURCE_PYTHON_UTILS_H
#endif //VEGA_STRIKE_ENGINE_RESOURCE_PYTHON_UTILS_H
19 changes: 12 additions & 7 deletions engine/src/python/infra/get_string.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
/*
* get_string.cpp
*
* Copyright (c) 2001-2002 Daniel Horn
* Copyright (c) 2002-2019 pyramid3d and other Vega Strike Contributors
* Copyright (c) 2019-2023 Stephen G. Tuggy, Benjamen R. Meyer, Roy Falk and other Vega Strike Contributors
* Copyright (c) 2001-2025 Daniel Horn, pyramid3d, Stephen G. Tuggy,
* Benjamen R. Meyer, Roy Falk and other Vega Strike Contributors
*
* https://github.com/vegastrike/Vega-Strike-Engine-Source
*
* This file is part of Vega Strike.
*
* Vega Strike is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Vega Strike is distributed in the hope that it will be useful,
Expand All @@ -20,7 +19,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Vega Strike. If not, see <https://www.gnu.org/licenses/>.
* along with Vega Strike. If not, see <https://www.gnu.org/licenses/>.
*/

// -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
Expand All @@ -45,25 +44,33 @@ const std::string GetString(const std::string function_name,
PyObject* module = PyImport_ImportModule(module_name.c_str());

if(!module) {
VS_LOG_AND_FLUSH(error, "Error: PyImport_ImportModule failed");
PyErr_Print();
PyErr_Clear();
return "Error: PyImport_ImportModule is null";
}

PyObject* function = PyObject_GetAttrString(module, function_name.c_str());
if(!function) {
VS_LOG_AND_FLUSH(error, "Error: PyObject_GetAttrString failed");
PyErr_Print();
PyErr_Clear();
return "Error: PyObject_GetAttrString is null";
}

if(args == nullptr) {
VS_LOG_AND_FLUSH(error, "Error: args is null");
PyErr_Print();
PyErr_Clear();
return "Error: PyTuple_Pack is null";
}

PyObject* pyResult = PyObject_CallObject(function, args);

if(!pyResult) {
VS_LOG_AND_FLUSH(error, "Error: PyObject_CallObject failed");
PyErr_Print();
PyErr_Clear();
return "Error: PyObject_CallObject is null";
}

Expand All @@ -86,5 +93,3 @@ const std::string GetString(const std::string function_name,

return GetString(function_name, module_name, file_name, args);
}


52 changes: 46 additions & 6 deletions engine/src/python/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class Unit;
#define PATHSEP "/"
#endif

#define Q(x) #x
#define QUOTE(x) Q(x)

void Python::initpaths() {
/*
* char pwd[2048];
Expand Down Expand Up @@ -163,43 +166,73 @@ void Python::init() {
return;
}
isinit = true;
//initialize python library

// initialize python library
PyPreConfig py_pre_config;
PyPreConfig_InitPythonConfig(&py_pre_config);

PyStatus status;

status = Py_PreInitialize(&py_pre_config);
if (PyStatus_Exception(status)) {
VS_LOG_AND_FLUSH(fatal, "Python::init(): PyPreInitialize failed");
PyErr_Print();
VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting();
Py_ExitStatusException(status);
}

Py_NoSiteFlag = 1;

// These functions add these modules to the builtin package
// These functions add these modules to the builtin package
InitVS();
InitBriefing();
InitBase();
InitDirector();

// Add relevant paths to python path
// Add relevant paths to python path
const std::string python_path = GetPythonPath();
const std::wstring python_path_w(python_path.begin(), python_path.end());
const std::wstring program_dir_w = std::wstring(VSFileSystem::programdir.begin(), VSFileSystem::programdir.end());
const std::string base_computer_path = VSFileSystem::datadir + "/python/base_computer/";
const std::wstring base_computer_path_w = std::wstring(base_computer_path.begin(), base_computer_path.end());
const std::string python_sitelib_path = QUOTE(Python_SITELIB);
const std::wstring python_sitelib_path_wstring = std::wstring(python_sitelib_path.begin(), python_sitelib_path.end());
const std::wstring data_path_w = std::wstring(VSFileSystem::datadir.begin(), VSFileSystem::datadir.end());

PyWideStringList python_path_py_wide_string_list{};
status = PyWideStringList_Append(&python_path_py_wide_string_list, python_path_w.c_str());
if (PyStatus_Exception(status)) {
VS_LOG_AND_FLUSH(fatal, "Python::init(): PyWideStringList_Append 1 failed");
PyErr_Print();
VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting();
Py_ExitStatusException(status);
}
status = PyWideStringList_Append(&python_path_py_wide_string_list, program_dir_w.c_str());
if (PyStatus_Exception(status)) {
VS_LOG_AND_FLUSH(fatal, "Python::init(): PyWideStringList_Append 2 failed");
PyErr_Print();
VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting();
Py_ExitStatusException(status);
}
status = PyWideStringList_Append(&python_path_py_wide_string_list, base_computer_path_w.c_str());
if (PyStatus_Exception(status)) {
VS_LOG_AND_FLUSH(fatal, "Python::init(): PyWideStringList_Append 3 failed");
PyErr_Print();
VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting();
Py_ExitStatusException(status);
}
status = PyWideStringList_Append(&python_path_py_wide_string_list, python_sitelib_path_wstring.c_str());
if (PyStatus_Exception(status)) {
VS_LOG_AND_FLUSH(fatal, "Python::init(): PyWideStringList_Append 4 failed");
PyErr_Print();
VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting();
Py_ExitStatusException(status);
}
status = PyWideStringList_Append(&python_path_py_wide_string_list, data_path_w.c_str());
if (PyStatus_Exception(status)) {
VS_LOG_AND_FLUSH(fatal, "Python::init(): PyWideStringList_Append 5 failed");
PyErr_Print();
VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting();
Py_ExitStatusException(status);
}

Expand All @@ -209,8 +242,17 @@ void Python::init() {
config.module_search_paths = python_path_py_wide_string_list;
config.isolated = 0;

// Now we can do python things about them and initialize them
// Now we can do python things about them and initialize them
Py_Initialize();
status = Py_InitializeFromConfig(&config);
if (PyStatus_Exception(status)) {
VS_LOG_AND_FLUSH(fatal, "Python::init(): Py_InitializeFromConfig failed");
PyErr_Print();
VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting();
PyConfig_Clear(&config);
Py_ExitStatusException(status);
}

initpaths();

#if BOOST_VERSION != 102800
Expand All @@ -224,7 +266,6 @@ void Python::init() {
InitVS2();
#endif
VS_LOG(important_info, "testing Python integration");
// VS_LOG(info, "testing VS random");
std::string python_snippet_to_run_1("import sys\nprint(sys.path)\n");
VegaPyRunString(python_snippet_to_run_1);

Expand Down Expand Up @@ -285,4 +326,3 @@ void Python::test() {
}

#endif

0 comments on commit ce9c51f

Please sign in to comment.