Skip to content

Commit 000bc78

Browse files
authored
Delay actually loading the runtime to fix property setting (#63)
* Delay actually loading the runtime to fix property setting * Launch test for properties in separate process
1 parent 63d7f69 commit 000bc78

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

Diff for: clr_loader/hostfxr.py

+9-11
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ def __init__(self, runtime_config: Path, dotnet_root: Path, **params: str):
2020

2121
self._dotnet_root = Path(dotnet_root)
2222
self._dll = load_hostfxr(self._dotnet_root)
23-
self._is_initialized = False
2423
self._handle = _get_handle(self._dll, self._dotnet_root, runtime_config)
25-
self._load_func = _get_load_func(self._dll, self._handle)
24+
self._load_func = None
2625

2726
for key, value in params.items():
2827
self[key] = value
@@ -36,7 +35,7 @@ def dotnet_root(self) -> Path:
3635

3736
@property
3837
def is_initialized(self) -> bool:
39-
return self._is_initialized
38+
return self._load_func is not None
4039

4140
@property
4241
def is_shutdown(self) -> bool:
@@ -81,18 +80,23 @@ def __iter__(self) -> Generator[Tuple[str, str], None, None]:
8180
for i in range(size_ptr[0]):
8281
yield (decode(keys_ptr[i]), decode(values_ptr[i]))
8382

83+
def _get_load_func(self):
84+
if self._load_func is None:
85+
self._load_func = _get_load_func(self._dll, self._handle)
86+
87+
return self._load_func
88+
8489
def _get_callable(self, assembly_path: StrOrPath, typename: str, function: str):
8590
# TODO: Maybe use coreclr_get_delegate as well, supported with newer API
8691
# versions of hostfxr
87-
self._is_initialized = True
8892

8993
# Append assembly name to typename
9094
assembly_path = Path(assembly_path)
9195
assembly_name = assembly_path.stem
9296
typename = f"{typename}, {assembly_name}"
9397

9498
delegate_ptr = ffi.new("void**")
95-
res = self._load_func(
99+
res = self._get_load_func()(
96100
encode(str(assembly_path)),
97101
encode(typename),
98102
encode(function),
@@ -103,12 +107,6 @@ def _get_callable(self, assembly_path: StrOrPath, typename: str, function: str):
103107
check_result(res)
104108
return ffi.cast("component_entry_point_fn", delegate_ptr[0])
105109

106-
def _check_initialized(self) -> None:
107-
if self._handle is None:
108-
raise RuntimeError("Runtime is shut down")
109-
elif not self._is_initialized:
110-
raise RuntimeError("Runtime is not initialized")
111-
112110
def shutdown(self) -> None:
113111
if self._handle is not None:
114112
self._dll.hostfxr_close(self._handle)

Diff for: tests/test_common.py

+18-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def example_netcore(tmpdir_factory):
1818

1919
def build_example(tmpdir_factory, framework):
2020
out = Path(tmpdir_factory.mktemp(f"example-{framework}"))
21-
proj_path = Path(__file__).parent.parent / "example"
21+
proj_path = Path(__file__).parent.parent / "example" / "example.csproj"
2222

2323
check_call(["dotnet", "build", str(proj_path), "-o", str(out), "-f", framework])
2424

@@ -75,6 +75,19 @@ def test_coreclr(example_netcore: Path):
7575
run_tests(asm)
7676

7777

78+
def test_coreclr_properties(example_netcore: Path):
79+
from multiprocessing import get_context
80+
81+
p = get_context("spawn").Process(
82+
target=_do_test_coreclr_autogenerated_runtimeconfig,
83+
args=(example_netstandard,),
84+
kwargs=dict(properties=dict(APP_CONTEXT_BASE_DIRECTORY=str(example_netcore))),
85+
)
86+
p.start()
87+
p.join()
88+
p.close()
89+
90+
7891
def test_coreclr_autogenerated_runtimeconfig(example_netstandard: Path):
7992
from multiprocessing import get_context
8093

@@ -86,10 +99,12 @@ def test_coreclr_autogenerated_runtimeconfig(example_netstandard: Path):
8699
p.close()
87100

88101

89-
def _do_test_coreclr_autogenerated_runtimeconfig(example_netstandard: Path):
102+
def _do_test_coreclr_autogenerated_runtimeconfig(
103+
example_netstandard: Path, **properties
104+
):
90105
from clr_loader import get_coreclr
91106

92-
coreclr = get_coreclr()
107+
coreclr = get_coreclr(properties=properties)
93108
asm = coreclr.get_assembly(example_netstandard / "example.dll")
94109

95110
run_tests(asm)

0 commit comments

Comments
 (0)