5

I am not able to load a virtual environment I have using virtual-env in the same directory as the C# file.

Here is my code

var eng = IronPython.Hosting.Python.CreateEngine();
var scope = eng.CreateScope();

// Load Virtual Env
ICollection<string> searchPaths = eng.GetSearchPaths();
searchPaths.Add(@"/Users/Desktop/CSharpProjects/demo1/.venv/lib");
searchPaths.Add(@"/Users/Desktop/CSharpProjects/demo1/.venv/lib/site-packages");
searchPaths.Add(AppDomain.CurrentDomain.BaseDirectory);
eng.SetSearchPaths(searchPaths);

string file = @"script.py";

eng.ExecuteFile(file, scope);

Unhandled exception. IronPython.Runtime.Exceptions.ImportException: No module named 'numpy'

Python code is which I can execute on the terminal of the virtualenv created.

import numpy as np

def name(a, b=1):
    return np.add(a,b)

UPDATE:

Seems like IronPython3 is quite hopeless, I will accept an implementation in Pythonnet!

Here is my current code on Pythonnet and I am using NuGet - Pythonnet prerelease 3.0.0-preview2022-06-27

The following works fine as it uses the system@s python 3.7, however I would like it to use the virtualenv located in C:\envs\venv2. How can I modify the below code to use the virtual environment located in C:\envs\venv2?

My class1.cs is:

using Python.Runtime;
using System;
namespace ConsoleApp1
{
    public class PythonOperation
    {
        PyModule scope;

        public void Initialize()
    {
        Runtime.PythonDLL = @"C:\\Python37\python37.dll";


        string pathToVirtualEnv = @"C:\envs\venv2";
        string pathToPython = @"C:\Python37\";


        Environment.SetEnvironmentVariable("PATH", pathToPython, 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);
    

        PythonEngine.Initialize();
        scope = Py.CreateScope();
        PythonEngine.BeginAllowThreads();
        }

        public void Execute()
        {
            using (Py.GIL())
            {

            }}}}

Error:

Fatal Python error: initfsencoding: unable to load the file system codec ModuleNotFoundError: No module named 'encodings'

Cardstdani
  • 4,999
  • 3
  • 12
  • 31
Joseph Adam
  • 1,341
  • 3
  • 21
  • 47
  • Have you tried using the path to your venv's python DLL in Runtime.PythonDLL ? – dosas Jun 27 '22 at 19:49
  • @dosas I am not aware of python DLL existing in virtual venv. Where is that located? – Joseph Adam Jun 27 '22 at 20:25
  • https://code.tutsplus.com/tutorials/understanding-virtual-environments-in-python--cms-28272 – dosas Jun 28 '22 at 07:32
  • @dosas there are no DLLs in virtualenv by design. They use the main python DLL file. Please do more research before posting. – Joseph Adam Jun 28 '22 at 07:36
  • SInce the nature of the question has changed after I dropped out IronPython, I managed to solve it using -> https://github.com/pythonnet/pythonnet/wiki/Using-Python.NET-with-Virtual-Environments – Joseph Adam Jun 28 '22 at 19:02

1 Answers1

1

You may need to try this way of setting up the PythonEngine.PythonPath:

string pathToVirtualEnv = /path/to/venv/;

var path = 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 = PythonEngine.PythonPath + ";" + Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process);

As you can see above, you can reference PythonPath while assigning a new value.

Cardstdani
  • 4,999
  • 3
  • 12
  • 31