Skip to content

Commit dc5b43c

Browse files
committed
Implement simple new loading using clr_loader
1 parent dce064b commit dc5b43c

File tree

5 files changed

+297
-240
lines changed

5 files changed

+297
-240
lines changed

pythonnet/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,20 @@ def load():
4646
_FFI = cffi.FFI()
4747
_FFI.dlopen(libpython, posix.RTLD_NODELETE | posix.RTLD_LOCAL)
4848

49+
print("Loading from", dll_path)
4950
_LOADER_ASSEMBLY = _RUNTIME.get_assembly(dll_path)
5051

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

5556
import atexit
5657
atexit.register(unload)
5758

5859

5960
def unload():
61+
return
6062
if _LOADER_ASSEMBLY is not None:
61-
func = _LOADER_ASSEMBLY["Python.Loader.Internal.Shutdown"]
63+
func = _LOADER_ASSEMBLY["Python.Runtime.Loader.Shutdown"]
6264
if func(b"") != 0:
6365
raise RuntimeError("Failed to call Python.NET shutdown")

src/domain_tests/test_domain_reload.py

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,90 +12,73 @@ def _run_test(testname):
1212
if platform.system() != 'Windows':
1313
args = ['mono'] + args
1414

15-
proc = subprocess.Popen(args)
15+
from pythonnet.util import find_libpython
16+
libpython = find_libpython()
17+
18+
proc = subprocess.Popen(args, env={"PYTHONNET_PYDLL": libpython})
1619
proc.wait()
1720

1821
assert proc.returncode == 0
1922

20-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
2123
def test_rename_class():
2224
_run_test('class_rename')
2325

24-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
2526
def test_rename_class_member_static_function():
2627
_run_test('static_member_rename')
2728

28-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
2929
def test_rename_class_member_function():
3030
_run_test('member_rename')
3131

32-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
3332
def test_rename_class_member_field():
3433
_run_test('field_rename')
3534

36-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
3735
def test_rename_class_member_property():
3836
_run_test('property_rename')
3937

40-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
4138
def test_rename_namespace():
4239
_run_test('namespace_rename')
4340

44-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
4541
def test_field_visibility_change():
4642
_run_test("field_visibility_change")
4743

48-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
4944
def test_method_visibility_change():
5045
_run_test("method_visibility_change")
5146

52-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
5347
def test_property_visibility_change():
5448
_run_test("property_visibility_change")
5549

56-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
5750
def test_class_visibility_change():
5851
_run_test("class_visibility_change")
5952

6053
@pytest.mark.skip(reason='FIXME: Domain reload fails when Python points to a .NET object which points back to Python objects')
61-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
6254
def test_method_parameters_change():
6355
_run_test("method_parameters_change")
6456

65-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
6657
def test_method_return_type_change():
6758
_run_test("method_return_type_change")
6859

69-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
7060
def test_field_type_change():
7161
_run_test("field_type_change")
7262

73-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
7463
@pytest.mark.xfail(reason="Events not yet serializable")
7564
def test_rename_event():
7665
_run_test('event_rename')
7766

78-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
7967
@pytest.mark.xfail(reason="newly instanced object uses PyType_GenericAlloc")
8068
def test_construct_removed_class():
8169
_run_test("construct_removed_class")
8270

83-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
8471
def test_out_to_ref_param():
8572
_run_test("out_to_ref_param")
8673

87-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
8874
def test_ref_to_out_param():
8975
_run_test("ref_to_out_param")
9076

91-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
9277
def test_ref_to_in_param():
9378
_run_test("ref_to_in_param")
9479

95-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
9680
def test_in_to_ref_param():
9781
_run_test("in_to_ref_param")
9882

99-
@pytest.mark.skipif(platform.system() == 'Darwin', reason='FIXME: macos can\'t find the python library')
10083
def test_nested_type():
10184
_run_test("nested_type")

src/runtime/loader.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using System.Text;
4+
using System.Threading;
5+
6+
namespace Python.Runtime
7+
{
8+
using static Runtime;
9+
10+
[Obsolete("Only to be used from within Python")]
11+
static class Loader
12+
{
13+
public static int Initialize(IntPtr data, int size)
14+
{
15+
IntPtr gs = IntPtr.Zero;
16+
try
17+
{
18+
var buf = new byte[size];
19+
Marshal.Copy(data, buf, 0, size);
20+
var dllPath = Encoding.UTF8.GetString(buf);
21+
22+
PythonDLL = dllPath;
23+
// PythonDLL = null;
24+
25+
gs = PyGILState_Ensure();
26+
27+
// Console.WriteLine("Startup thread");
28+
PythonEngine.InitExt();
29+
// Console.WriteLine("Startup finished");
30+
}
31+
catch (Exception exc)
32+
{
33+
Console.Error.Write(
34+
$"Failed to initialize pythonnet: {exc}\n{exc.StackTrace}"
35+
);
36+
return 1;
37+
}
38+
finally {
39+
if (gs != IntPtr.Zero) {
40+
PyGILState_Release(gs);
41+
}
42+
}
43+
return 0;
44+
}
45+
46+
public static int Shutdown(IntPtr data, int size)
47+
{
48+
IntPtr gs = IntPtr.Zero;
49+
try
50+
{
51+
gs = PyGILState_Ensure();
52+
PythonEngine.Shutdown();
53+
}
54+
catch (Exception exc)
55+
{
56+
Console.Error.Write(
57+
$"Failed to initialize pythonnet: {exc}\n{exc.StackTrace}"
58+
);
59+
return 1;
60+
}
61+
finally {
62+
if (gs != IntPtr.Zero) {
63+
PyGILState_Release(gs);
64+
}
65+
}
66+
return 0;
67+
}
68+
}
69+
}

src/runtime/pythonengine.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@ public static void Initialize()
155155
Initialize(setSysArgv: true);
156156
}
157157

158-
public static void Initialize(bool setSysArgv = true, bool initSigs = false, ShutdownMode mode = ShutdownMode.Default)
158+
public static void Initialize(bool setSysArgv = true, bool initSigs = false, ShutdownMode mode = ShutdownMode.Default, bool ensureGIL = true)
159159
{
160-
Initialize(Enumerable.Empty<string>(), setSysArgv: setSysArgv, initSigs: initSigs, mode);
160+
Initialize(Enumerable.Empty<string>(), setSysArgv: setSysArgv, initSigs: initSigs, mode, ensureGIL);
161161
}
162162

163163
/// <summary>
@@ -170,7 +170,7 @@ public static void Initialize(bool setSysArgv = true, bool initSigs = false, Shu
170170
/// interpreter lock (GIL) to call this method.
171171
/// initSigs can be set to 1 to do default python signal configuration. This will override the way signals are handled by the application.
172172
/// </remarks>
173-
public static void Initialize(IEnumerable<string> args, bool setSysArgv = true, bool initSigs = false, ShutdownMode mode = ShutdownMode.Default)
173+
public static void Initialize(IEnumerable<string> args, bool setSysArgv = true, bool initSigs = false, ShutdownMode mode = ShutdownMode.Default, bool ensureGIL = true)
174174
{
175175
if (initialized)
176176
{
@@ -182,7 +182,7 @@ public static void Initialize(IEnumerable<string> args, bool setSysArgv = true,
182182
// during an initial "import clr", and the world ends shortly thereafter.
183183
// This is probably masking some bad mojo happening somewhere in Runtime.Initialize().
184184
delegateManager = new DelegateManager();
185-
Runtime.Initialize(initSigs, mode);
185+
Runtime.Initialize(initSigs, mode, ensureGIL: ensureGIL);
186186
initialized = true;
187187
Exceptions.Clear();
188188

@@ -266,7 +266,7 @@ public static IntPtr InitExt()
266266
{
267267
try
268268
{
269-
Initialize(setSysArgv: false);
269+
Initialize(setSysArgv: false, ensureGIL: false);
270270

271271
// Trickery - when the import hook is installed into an already
272272
// running Python, the standard import machinery is still in

0 commit comments

Comments
 (0)