{
"extension": ".h",
"source": "// Written by retoor@molodetz.nl\n\n// This source code initializes a Python interpreter within a plugin, executes a provided Python script with some basic imports, and finalizes the Python environment when done.\n\n// This code does not use any non-standard imports or includes aside from Python.h and structmember.h which are part of Python's C API.\n\n// MIT License\n\n\n#include <python3.14/Python.h>\n#include <python3.14/structmember.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nbool plugin_initialized = false;\n\nbool plugin_construct() {\n if (plugin_initialized)\n return true;\n\n Py_Initialize();\n\n if (!Py_IsInitialized()) {\n fprintf(stderr, \"Failed to initialize Python interpreter\\n\");\n return plugin_initialized;\n }\n plugin_initialized = true;\n return plugin_initialized;\n}\n\nvoid plugin_run(char *src) {\n plugin_construct();\n const char *basics = \n \"import sys\\n\"\n \"import os\\n\"\n \"import math\\n\"\n \"import pathlib\\n\"\n \"import subprocess\\n\"\n \"import time\\n\"\n \"from datetime import datetime\\n\"\n \"%s\";\n size_t length = strlen(basics) + strlen(src);\n char *script = (char *)malloc(length + 1);\n sprintf(script, basics, src);\n script[length] = '\\0';\n PyRun_SimpleString(script);\n free(script);\n}\n\nvoid plugin_destruct() {\n if (plugin_initialized)\n Py_Finalize();\n}",
"review": "## 5\n\n### Bugs\n- There is no check to see if `PyRun_SimpleString` runs successfully.\n- The allocation with `malloc` is not checked for a `NULL` return, which may lead to a segmentation fault if memory allocation fails.\n \n### Optimizations\n- Check for successful memory allocation after calling `malloc`.\n- `Py_Initialize()` should ideally be paired with `PyErr_Occurred()` to detect initialization errors.\n- Consider using modern C string formatting functions like `snprintf` to prevent buffer overflow.\n- Ensure the script is valid Python code by checking with `PyErr_Occurred()` after `PyRun_SimpleString`.\n- Use `Py_FinalizeEx()` instead of `Py_Finalize()` when available, as it provides better error handling.\n\n### Good points\n- The plugin checks whether the Python interpreter is already initialized, preventing redundant initialization.\n- Use of `fprintf` for error reporting ensures error messages are printed to the standard error stream.\n- Dynamic construction of the Python script with basic imports is done neatly.\n\n### Summary\nThe code provides a basic mechanism to run a Python interpreter from a C plugin, dynamically constructing the script with necessary imports. Although functionally correct, there are areas requiring error handling and optimization, such as checking memory allocations and Python interpreter errors. These improvements enhance stability and reliability.\n\n### Open source alternatives\n- **CPython** serves as a standard environment to execute Python code embedded in C programs.\n- **Boost.Python** provides a framework for interfacing C++ and Python.\n- **SWIG** simplifies the task of interfacing different languages, including C/C++ with Python.",
"filename": "plugin.h",
"path": "plugin.h",
"directory": "",
"grade": 5,
"size": 1427,
"line_count": 55
}