Skip to content

Loader #1322

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

Closed
wants to merge 8 commits into from
Closed

Loader #1322

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 2 additions & 34 deletions clr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,8 @@
Legacy Python.NET loader for backwards compatibility
"""

def _get_netfx_path():
import os, sys

if sys.maxsize > 2 ** 32:
arch = "amd64"
else:
arch = "x86"

return os.path.join(os.path.dirname(__file__), "pythonnet", "netfx", arch, "clr.pyd")


def _get_mono_path():
import os, glob

paths = glob.glob(os.path.join(os.path.dirname(__file__), "pythonnet", "mono", "clr.*so"))
return paths[0]


def _load_clr():
import sys
from importlib import util

if sys.platform == "win32":
path = _get_netfx_path()
else:
path = _get_mono_path()

del sys.modules[__name__]

spec = util.spec_from_file_location("clr", path)
clr = util.module_from_spec(spec)
spec.loader.exec_module(clr)

sys.modules[__name__] = clr

from pythonnet import load
load()

_load_clr()
28 changes: 26 additions & 2 deletions pythonnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ VisualStudioVersion = 16.0.30717.126
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.Runtime", "src\runtime\Python.Runtime.csproj", "{4E8C8FE2-0FB8-4517-B2D9-5FB2D5FC849B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Console", "src\console\Console.csproj", "{E6B01706-00BA-4144-9029-186AC42FBE9A}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Python.Loader", "src\loader\Python.Loader.csproj", "{B9F0A702-A977-47E3-88FF-6082E9614F40}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "clrmodule", "src\clrmodule\clrmodule.csproj", "{F9F5FA13-BC52-4C0B-BC1C-FE3C0B8FCCDD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Console", "src\console\Console.csproj", "{E6B01706-00BA-4144-9029-186AC42FBE9A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.EmbeddingTest", "src\embed_tests\Python.EmbeddingTest.csproj", "{819E089B-4770-400E-93C6-4F7A35F0EA12}"
EndProject
Expand Down Expand Up @@ -129,6 +129,30 @@ Global
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x64.Build.0 = Release|x64
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x86.ActiveCfg = Release|x86
{4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x86.Build.0 = Release|x86
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Debug|x64.ActiveCfg = Debug|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Debug|x64.Build.0 = Debug|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Debug|x86.ActiveCfg = Debug|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Debug|x86.Build.0 = Debug|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Release|Any CPU.Build.0 = Release|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Release|x64.ActiveCfg = Release|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Release|x64.Build.0 = Release|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Release|x86.ActiveCfg = Release|Any CPU
{16288AA7-EB9F-45CC-90C0-3AFA7715BA8A}.Release|x86.Build.0 = Release|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Debug|x64.ActiveCfg = Debug|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Debug|x64.Build.0 = Debug|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Debug|x86.ActiveCfg = Debug|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Debug|x86.Build.0 = Debug|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Release|Any CPU.Build.0 = Release|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Release|x64.ActiveCfg = Release|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Release|x64.Build.0 = Release|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Release|x86.ActiveCfg = Release|Any CPU
{B9F0A702-A977-47E3-88FF-6082E9614F40}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
67 changes: 64 additions & 3 deletions pythonnet/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,64 @@
def get_assembly_path():
import os
return os.path.dirname(__file__) + "/runtime/Python.Runtime.dll"
import os
import sys
import clr_loader

_RUNTIME = None
_LOADER_ASSEMBLY = None
_FFI = None
_LOADED = False


def set_runtime(runtime):
global _RUNTIME
_RUNTIME = runtime


def set_default_runtime():
if sys.platform == 'win32':
set_runtime(clr_loader.get_netfx())
else:
set_runtime(clr_loader.get_mono(gc=""))


def load():
global _FFI, _LOADED, _LOADER_ASSEMBLY

if _LOADED:
return

from .util import find_libpython
from os.path import join, dirname, basename

if _RUNTIME is None:
# TODO: Warn, in the future the runtime must be set explicitly, either as a
# config/env variable or via set_runtime
set_default_runtime()

dll_path = join(dirname(__file__), "runtime", "Python.Loader.dll")
runtime_dll_path = join(dirname(dll_path), "Python.Runtime.dll")
libpython = basename(find_libpython())
# TODO: Add dirname of libpython to (DY)LD_LIBRARY_PATH or PATH

if _FFI is None and libpython != "__Internal" and sys.platform != "win32":
# Load and leak libpython handle s.t. the .NET runtime doesn't dlcloses it
import posix

import cffi
_FFI = cffi.FFI()
_FFI.dlopen(libpython, posix.RTLD_NODELETE | posix.RTLD_LOCAL)

_LOADER_ASSEMBLY = _RUNTIME.get_assembly(dll_path)

func = _LOADER_ASSEMBLY["Python.Loader.Internal.Initialize"]
if func(f"{runtime_dll_path};{libpython}".encode("utf8")) != 0:
raise RuntimeError("Failed to initialize Python.Runtime.dll")

import atexit
atexit.register(unload)


def unload():
if _LOADER_ASSEMBLY is not None:
func = _LOADER_ASSEMBLY["Python.Loader.Internal.Shutdown"]
if func(b"") != 0:
raise RuntimeError("Failed to call Python.NET shutdown")
1 change: 1 addition & 0 deletions pythonnet/util/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .find_libpython import find_libpython
Loading