Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

builtin modules have no __file__ attribute? #302

Open
minesworld opened this issue Oct 30, 2024 · 2 comments
Open

builtin modules have no __file__ attribute? #302

minesworld opened this issue Oct 30, 2024 · 2 comments

Comments

@minesworld
Copy link

minesworld commented Oct 30, 2024

Python code like

import os
os.__file__

fails as there is no __file__ set.

Don't know why - in pythonnet the attribute is created on the builtin modules...

minesworld added a commit to minesworld/CSnakes that referenced this issue Oct 30, 2024
@minesworld
Copy link
Author

minesworld commented Oct 31, 2024

"Interesting" - the main difference between CSnakes CAPI and pythonnet's PythonEngine is how the PYTHONPATH is set.

After Py_InitializeEx pytonnet changes sys.path on the module. the builtin modules have __file__ set.

CSnake does a Py_SetPath before Py_Initalize . the builtin do not have __file__ set.

By changing runtime.cs to

private void InitializeEmbeddedPython()
{
    lock (initLock)
    {
        /*
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            Py_SetPath_UCS2_UTF16(PythonPath);
        else
            Py_SetPath_UCS4_UTF32(PythonPath);
        Debug.WriteLine($"Initializing Python on thread {GetNativeThreadId()}");
        */
        Py_Initialize();

  }
}

and adding the virtuel environment path to the sys module like:

  using (CSnakes.Runtime.Python.GIL.Acquire())
  {
      var pyoPtrSysName = CAPI.AsPyUnicodeObject("sys");
      var pyoPtrSysModule = CAPI.PyImport_Import(pyoPtrSysName);
      var pyoPtrPathAttr = CAPI.AsPyUnicodeObject("path");
      var pyoPtrPathList = CAPI.PyObject_GetAttr(pyoPtrSysModule, pyoPtrPathAttr);
      var pyoPtrPathValue = CAPI.AsPyUnicodeObject(venvSitePackagesPath);
      CAPI.PyList_Append(pyoPtrPathList, pyoPtrPathValue);

     // doesn't care about referencing ...
  }

  // maybe a Runtime.Exec($"import sys\nsys.path.append(r\"{venvSitePackagesPath}\")") would be simpler solution...

CSnakes works correctly. Maybe its a bug in the nuget python package (3.12.7) ...

PS: please think about making the whole CAPI stuff public. My branch of CSnakes does so and without it would be a hard task writing and testing such changes... . Maybe there is some C# magic which enables to use it as public and those who are more concerned just have APIs above and such can not do "unsafe" stuff...

minesworld added a commit to minesworld/CSnakes that referenced this issue Oct 31, 2024
@minesworld
Copy link
Author

The code in the pull request append the missing paths from PytonPath to sys.path . This way the CPython's default remain untouched and in order. Maybe the DLL implementors did the right thing...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant