Repository: pythonnet/pythonnet

Issue #2469: BinaryFormatter deprecation issue while using PythonEngine.Shutdown()
Created: 2024-10-01T09:58:21Z
Environment

Pythonnet version: 3.0.4
Python version: 3.11
Operating System: Windows 10
.NET Runtime: .NET8/netstandard 2.0

Details
Hi, I am facing a known issue with PythonEngine.Shutdown() that should have been solved. I saw looking around here that many others have had a problem while using the Shutdown function since it caused an exception due to the deprecation of BinaryFormatter in .NET8.
Here the exception I am getting:
System.NotSupportedException: 'BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.'
I am aware of the workarounds already provided such as the management of "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization" parameter, if I manually manage this set the issue is not presenting anymore, but it seems to me that is more of a patch than a fix.
Since .NET9 will totally get rid of BinaryFormatter, and since I read in other threads that this issue should have been fixed, I was wondering if I was missing something or if the only way to manage this is by manually managing the serialization parameter.
Here follows the code I am using (in a project that targets netstandard2.0, while it is called by a .NET8 project).
using Python.Runtime;
using System;
using System.IO;

namespace ExecutePython
{
    public class Class1
    {
        string filePath;
        
        public Class1(string FilePath) 
        { 
            filePath = FilePath;
            Initialize();
        }

        public void Initialize()
        {
            string pythonDll = @"C:\Users\MyUser\AppData\Local\Programs\Python\Python311\python311.dll";
            Environment.SetEnvironmentVariable("PYTHONNET_PYDLL", pythonDll);
            PythonEngine.Initialize();
        }
        public void ExecutePython()
        {
            string pyCode = File.ReadAllText(filePath);

            using (Py.GIL())
            {
                try
                {
                    PythonEngine.Exec(pyCode);
                }
                catch (Exception ex)
                {
                    //log error
                }
            }
            
            try
            {
                //AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", true);
                PythonEngine.Shutdown();  
                //AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", false);
            }
            catch (Exception e)
            { }
        }
    }
}
The code that is executing correctly in my python script is a sample code, in my case it just pops up a window to see that the script is executing correctly

Duplicate issue #2532: .net8.0 System.AggregateException:BinaryFormatter serialization and deserialization are disabled within this application.
Created: 2024-12-18T07:41:03Z
Environment

Pythonnet version: 3.1.0-preview2024-09-06
Python version: 3.8.10
Operating System: Win10
.NET Runtime: dotnet8.0 core

Details


Describe what you were trying to get done.
I want use python in dotnet ,but this dotnet evenment can not exit ,so i use func shutdown,but the C# evenment have an Exception:System.AggregateException: One or more errors occurred. (BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.)
---> System.NotSupportedException: BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
at Python.Runtime.RuntimeData.Stash() in D:\work\vsprj\HDC_Instrament2024new\HDC_InstramentForPythonTkinter\pythonnet-master\src\runtime\StateSerialization\RuntimeData.cs:line 96
at Python.Runtime.Runtime.Shutdown() in D:\work\vsprj\HDC_Instrament2024new\HDC_InstramentForPythonTkinter\pythonnet-master\src\runtime\Runtime.cs:line 272
at Python.Runtime.PythonEngine.Shutdown() in D:\work\vsprj\HDC_Instrament2024new\HDC_InstramentForPythonTkinter\pythonnet-master\src\runtime\PythonEngine.cs:line 392


What commands did you run to trigger this issue? If you can provide a
Minimal, Complete, and Verifiable example
this will help us understand the issue.


//功能测试
bool taskrun = true;
Task.Run(async () =>
{
    // install in local directory
    Installer.InstallPath = Path.GetFullPath(".");
    // see what the installer is doing
    Installer.LogMessage += Console.WriteLine;
    bool loadend = false;

    await Installer.SetupPython();
    if (!Installer.IsPipInstalled())
    {
        await Installer.TryInstallPip();
    }
    if (!Installer.IsModuleInstalled("numpy"))
    {
        await Installer.PipInstallModule("numpy");
    }
    loadend = true;

    while (!loadend) ;
    PythonEngine.Initialize();


    try
    {
        // call Python's sys.version to prove we are executing the right version
        dynamic sys = Py.Import("sys");
        Console.WriteLine("### Python version:\n\t" + sys.version);

        // call os.getcwd() to prove we are executing the locally installed embedded python distribution
        dynamic os = Py.Import("os");
        Console.WriteLine("### Current working directory:\n\t" + os.getcwd());
        Console.WriteLine("### PythonPath:\n\t" + PythonEngine.PythonPath);

        dynamic np = Py.Import("numpy"); // 导入numpy模块
        dynamic sin = np.sin;
        int[] data = new int[] { 0, 1, 2, 3 };
        var a = np.array(data);
        var result = sin(a);
        Console.WriteLine("Numpy sin:");
        Console.WriteLine(result);


        dynamic tkinter = Py.Import("tkinter"); // 导入tkinter模块
        var top = tkinter.Tk();
        // 进入消息循环
        top.mainloop();

    }
    catch (PythonException e)
    {
        Console.WriteLine($"{e}");
    }
   
    PythonEngine.Shutdown();
}).ContinueWith((e) => {
    Console.WriteLine($"{e.Exception}");
    taskrun = false;
});
while (taskrun) ;

If there was a crash, please include the traceback here.

     One or more errors occurred. (BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.)
 ---> System.NotSupportedException: BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
   at Python.Runtime.RuntimeData.Stash() in D:\work\vsprj\HDC_Instrament2024new\HDC_InstramentForPythonTkinter\pythonnet-master\src\runtime\StateSerialization\RuntimeData.cs:line 96
   at Python.Runtime.Runtime.Shutdown() in D:\work\vsprj\HDC_Instrament2024new\HDC_InstramentForPythonTkinter\pythonnet-master\src\runtime\Runtime.cs:line 272
   at Python.Runtime.PythonEngine.Shutdown() in D:\work\vsprj\HDC_Instrament2024new\HDC_InstramentForPythonTkinter\pythonnet-master\src\runtime\PythonEngine.cs:line 392

Closing comment (2024-12-18T08:02:10Z): This is a duplicate of #2469.