Jack Liu added the comment: I wrote the test code as below. I also attached the files in attachment. Python =========================================================
class Simple: def __init__( self ): print('Simple__init__') def __del__( self ): print('Simple__del__') simple = None def run(): global simple simple = Simple() if __name__ == '__main__': run() ============================================================== C++ ========================================================================= #include "stdafx.h" #include <Python.h> #include <string> #include <iostream> #include <fstream> #include <codecvt> #include <map> using namespace std; namespace { wstring readfile(const wchar_t *filename) { wifstream wifs; wifs.open(filename); //wifs.imbue(locale(wifs.getloc(), new codecvt_utf8<wchar_t, 0x10ffff, consume_header>())); wstring wstr((std::istreambuf_iterator<wchar_t>(wifs)), std::istreambuf_iterator<wchar_t>()); return wstr; } string wstrtostr(const wstring& ws) { std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; return converter.to_bytes(ws); } } int main() { cout << "Input py file full path:" << endl; wstring filePath; wcin >> filePath; //filePath = L"L:\\Dev\\PyTest\\SimpleTest.py"; string moduleName = "__main__"; string script = wstrtostr(readfile(filePath.c_str())); if (script.empty()) { cout << "Invalid python file path" << endl; return 1; } string sfileName = wstrtostr(filePath); // Initialize the Python Interpreter Py_Initialize(); PyObject *py_module = PyImport_AddModule(moduleName.c_str()); PyObject *py_dict = PyModule_GetDict(py_module); PyObject* res = nullptr; auto arena = PyArena_New(); if (arena) { auto mod = PyParser_ASTFromString(script.c_str(), sfileName.c_str(), Py_file_input, nullptr, arena); if (mod) { auto co = PyAST_Compile(mod, sfileName.c_str(), nullptr, arena); if (co) { res = PyEval_EvalCode((PyObject*)(co), py_dict, py_dict); Py_DECREF(co); } } PyArena_Free(arena); } if (res) { Py_DECREF(res); } // Delete the module from sys.modules PyObject* modules = PyImport_GetModuleDict(); cout << "PyDict_DelItemString" << endl; PyDict_DelItemString(modules, moduleName.c_str()); // May run many scripts here // Finish the Python Interpreter cout << "Py_Finalize" << endl; Py_Finalize(); return 0; } =================================================================== The expected output in console should be: Simple__init__ PyDict_DelItemString Simple__del__ Py_Finalize I tested with Python 3.2.5, 3.3.5, 3.5.1 and 3.6.0 beta. It worked as expected with Python 3.2.5 and 3.3.5, but did not work Python 3.5.1 and 3.6.0 beta. On Python 3.5.1 and 3.6.0 beta, the output is: Simple__init__ PyDict_DelItemString Py_Finalize Simple__del__ That means the Simple object is not released at PyDict_DelItemString, it's released at Py_Finalize. So it it a regression bug since Python 3.5? I wish there is a solution to resolve memory leak issue. ---------- Added file: http://bugs.python.org/file44748/PyTest.zip _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue28202> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com