- Notifications
You must be signed in to change notification settings - Fork749
Description
Environment
- Pythonnet version: 3.0.0-preview2021-06-04
- Python version: 3.9.1 (tags/v3.9.1:1e5d33e, Dec 7 2020, 17:08:21) [MSC v.1927 64 bit (AMD64)]
- Operating System: Windows 10 20H2
- .NET Runtime: 5.0.301
Details
according to#984 .NET Core is supported, which I hope includes .NET 5.0
according to#1389 Python 3.9 is supported in pythonnet 2.5, though I was unable to find 2.5 on nuget, so I went with a 3.0 preview in the hopes that it will work too.
Describe what you were trying to get done.
Embed python in a C# application with a virtual environment (venv) and import a module from it.
I have set up a virtual environment atC:\Users\felk\venv39
and verified that it works and I can use modules that are available in the venv but not globally:
PS C:\Users\felk> python -c 'import chat_downloader; print(True)'Traceback (most recent call last): File "<string>", line 1, in <module>ModuleNotFoundError: No module named 'chat_downloader'PS C:\Users\felk> .\venv39\Scripts\Activate.ps1(venv39) PS C:\Users\felk> python -c 'import chat_downloader; print(True)'True
According to thewiki this is the code to get virtual environments working:
varpathToVirtualEnv=@"path\to\env";// be sure not to overwrite your existing "PATH" environmental variable.varpath=Environment.GetEnvironmentVariable("PATH").TrimEnd(';');path=string.IsNullOrEmpty(path)?pathToVirtualEnv:path+";"+pathToVirtualEnv;Environment.SetEnvironmentVariable("PATH",path,EnvironmentVariableTarget.Process);Environment.SetEnvironmentVariable("PATH",pathToVirtualEnv,EnvironmentVariableTarget.Process);Environment.SetEnvironmentVariable("PYTHONHOME",pathToVirtualEnv,EnvironmentVariableTarget.Process);Environment.SetEnvironmentVariable("PYTHONPATH",$"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib",EnvironmentVariableTarget.Process);PythonEngine.PythonHome=pathToVirtualEnv;PythonEngine.PythonPath=Environment.GetEnvironmentVariable("PYTHONPATH",EnvironmentVariableTarget.Process);
However it is not clear to me what comes after that, most importantly where do I callPythonEngine.Initialize();
, so I attempted to piecemeal something together:
- Calling
PythonEngine.Initialize();
after the above snipped causes the application to crash without an exception, which I suspected is a segfault due to threading issues - Not calling it at all crashes the program in the same way upon first usage of any python within C#
- Calling it just before setting
PythonEngine.PythonHome
andPythonEngine.PythonPath
seems to work, in a sense that the application does not crash and calls into python from C# are possible.
However, when I try to import a module present in the virtual environment, it is not being found. I can observe that the venv path is part ofPythonEngine.PythonPath
but not part ofsys.path
by checking after settingPythonEngine.PythonPath
:
dynamicsys=Py.Import("sys");Console.WriteLine(sys.path);Console.WriteLine(PythonEngine.PythonPath);
this results in
['C:\\Program Files\\Python39\\python39.zip', 'C:\\Program Files\\Python39\\Lib', 'C:\\Program Files\\Python39\\DLLs', 'S:\\projects\\myproject\\bin\\Debug\\net5.0', 'C:\\Users\\felk\\AppData\\Roaming\\Python\\Python39\\site-packages', 'C:\\Program Files\\Python39', 'C:\\Program Files\\Python39\\lib\\site-packages', 'C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\5.0.7\\']C:/Users/felk/venv39/Lib/site-packages;C:/Users/felk/venv39/Lib;
This seems to be unrelated, but I also removed this line from the wiki's example as it seems nonsensical to override thePATH
with the venv path if it was just set to the correctly appended one a line above, and since the comment above literally just saidbe sure not to overwrite your existing "PATH" environmental variable
:
Environment.SetEnvironmentVariable("PATH",pathToVirtualEnv,EnvironmentVariableTarget.Process);
I also tried appending toPythonEngine.PythonPath
instead of replacing it, as described in#1348 but that had no effect either.