0

I'm trying to run a Python module from within C# by using an existing (and working) virtualenv. I get ModuleNotFoundError: No module named 'encodings', maybe due to an incorrect loading of the Python DLL.

I tried every possible order combo when executing Runtime.PythonDLL = @"C:\Users\ardiiva\AppData\Local\Programs\Python\Python38\python38.dll";. What I've noticed is that the python38.dll file is not present under my virtualenv folder, so I tried to copy it from my local windows machine user installation of Python, but also trying to reference it directly. The venv was created using the 3.8.9 Python version. Do you have any idea? Why I don't have the python.dll? Should it be generated in some way?

    var pathToVirtualEnv = @"C:\rebrandingmanager\CFGRebrandingPythonManager\codice\venv";
            Environment.SetEnvironmentVariable("PYTHONNET_PYDLL", @"C:\Users\ardiiva\AppData\Local\Programs\Python\Python38\python38.dll", EnvironmentVariableTarget.Process);
            Runtime.PythonDLL = @"C:\Users\ardiiva\AppData\Local\Programs\Python\Python38\python38.dll";

            var path = Environment.GetEnvironmentVariable("PATH").TrimEnd(';');
            path = string.IsNullOrEmpty(path) ? pathToVirtualEnv : path + ";" + pathToVirtualEnv;
            Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Process);
            Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);            
            Environment.SetEnvironmentVariable("PYTHONPATH", $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib", EnvironmentVariableTarget.Process);            
            //PYTHONNET_PYDLL 
            
            PythonEngine.PythonHome = pathToVirtualEnv;
            PythonEngine.PythonPath = Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process);

            PythonEngine.Initialize();
            using (Py.GIL())
            {
                dynamic aaaa = Py.Import("TestPy.py");
                aaaa.add_watermark("CIAOOOOO", "KAKAKAKAKAKAK.pdf", "RG-39119_002_A_001.pdf");
            }

The traceback is:

Exit code is 1 (Python path configuration:
  PYTHONHOME = 'C:\rebrandingmanager\CFGRebrandingPythonManager\codice\venv'
  PYTHONPATH = 'C:\rebrandingmanager\CFGRebrandingPythonManager\codice\venv\Lib\site-packages;C:\rebrandingmanager\CFGRebrandingPythonManager\codice\venv\Lib'
  program name = 'python'
  isolated = 0
  environment = 1
  user site = 1
  import site = 1
  sys._base_executable = 'C:\\Users\\ardiiva\\AppData\\Local\\JetBrains\\Installations\\Rider221\\lib\\ReSharperHost\\TestRunner\\net461\\ReSharperTestRunner.exe'
  sys.base_prefix = ''
  sys.base_exec_prefix = ''
  sys.executable = 'C:\\Users\\ardiiva\\AppData\\Local\\JetBrains\\Installations\\Rider221\\lib\\ReSharperHost\\TestRunner\\net461\\ReSharperTestRunner.exe'
  sys.prefix = ''
  sys.exec_prefix = ''
  sys.path = [
    'C:\\rebrandingmanager\\CFGRebrandingPythonManager\\codice\\venv\\Lib\\site-packages',
    'C:\\rebrandingmanager\\CFGRebrandingPythonManager\\codice\\venv\\Lib',
  ]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

exrezzo
  • 497
  • 1
  • 5
  • 24

1 Answers1

0

It appears that the standard PYTHONPATH is not set with the use of the dll. In my case, I took the dll dir (@"C:\Users\ardiiva\AppData\Local\Programs\Python\Python38"; in your case) and added the proper folders to PythonEngine.PythonPath, using the function:

string PythonPath(string pythonDir)
{
    return $"{pythonDir};{pythonDir}\\DLLs;{pythonDir}\\Lib;{pythonDir}\\Lib\\site-packages";
}

and then:

string pythonPath = PythonPath(Path.GetDirectoryName(pythonDll) ?? ".");
PythonEngine.PythonPath += $";{pythonPath}";

Did the same for the virtual environment:

string additional = PythonPath(pathToVirtualEnv);
PythonEngine.PythonPath +=  $";{additional}";

where pathToVirtualEnv is my .venv path.