Skip to content

Commit

Permalink
Merge pull request #42 from pythonnet/netfx-domain
Browse files Browse the repository at this point in the history
.NET Framework domains
  • Loading branch information
filmor committed Aug 7, 2023
2 parents 000bc78 + 59f47f9 commit a88b6a1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 29 deletions.
11 changes: 9 additions & 2 deletions clr_loader/netfx.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ def __init__(
):
initialize()
if config_file is not None:
config_file_s = str(config_file)
config_file_s = str(config_file).encode("utf8")
else:
config_file_s = ffi.NULL

domain_s = domain.encode("utf8") if domain else ffi.NULL

self._domain_name = domain
self._config_file = config_file
self._domain = _FW.pyclr_create_appdomain(domain or ffi.NULL, config_file_s)
self._domain = _FW.pyclr_create_appdomain(domain_s, config_file_s)

def info(self) -> RuntimeInfo:
return RuntimeInfo(
Expand All @@ -41,6 +43,11 @@ def _get_callable(self, assembly_path: StrOrPath, typename: str, function: str):
function.encode("utf8"),
)

if func == ffi.NULL:
raise RuntimeError(
f"Failed to resolve {typename}.{function} from {assembly_path}"
)

return func

def shutdown(self):
Expand Down
2 changes: 2 additions & 0 deletions netfx_loader/ClrLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ public static void Initialize()
{
var setup = new AppDomainSetup
{
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
ConfigurationFile = configFile
};
Print($"Base: {AppDomain.CurrentDomain.BaseDirectory}");
var domain = AppDomain.CreateDomain(name, null, setup);

Print($"Located domain {domain}");
Expand Down
57 changes: 30 additions & 27 deletions tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,15 @@ def test_coreclr(example_netcore: Path):


def test_coreclr_properties(example_netcore: Path):
from multiprocessing import get_context

p = get_context("spawn").Process(
target=_do_test_coreclr_autogenerated_runtimeconfig,
args=(example_netstandard,),
kwargs=dict(properties=dict(APP_CONTEXT_BASE_DIRECTORY=str(example_netcore))),
run_in_subprocess(
_do_test_coreclr_autogenerated_runtimeconfig,
example_netstandard,
properties=dict(APP_CONTEXT_BASE_DIRECTORY=str(example_netcore)),
)
p.start()
p.join()
p.close()


def test_coreclr_autogenerated_runtimeconfig(example_netstandard: Path):
from multiprocessing import get_context

p = get_context("spawn").Process(
target=_do_test_coreclr_autogenerated_runtimeconfig, args=(example_netstandard,)
)
p.start()
p.join()
p.close()
run_in_subprocess(_do_test_coreclr_autogenerated_runtimeconfig, example_netstandard)


def _do_test_coreclr_autogenerated_runtimeconfig(
Expand All @@ -114,25 +102,31 @@ def _do_test_coreclr_autogenerated_runtimeconfig(
sys.platform != "win32", reason=".NET Framework only exists on Windows"
)
def test_netfx(example_netstandard: Path):
from clr_loader import get_netfx

netfx = get_netfx()
asm = netfx.get_assembly(example_netstandard / "example.dll")

run_tests(asm)
run_in_subprocess(_do_test_netfx, example_netstandard)


@pytest.mark.skipif(
sys.platform != "win32", reason=".NET Framework only exists on Windows"
)
def test_netfx_chinese_path(example_netstandard: Path, tmpdir_factory):
from clr_loader import get_netfx

tmp_path = Path(tmpdir_factory.mktemp("example-中国"))
shutil.copytree(example_netstandard, tmp_path, dirs_exist_ok=True)

netfx = get_netfx()
asm = netfx.get_assembly(os.path.join(example_netstandard, "example.dll"))
run_in_subprocess(_do_test_netfx, tmp_path)


@pytest.mark.skipif(
sys.platform != "win32", reason=".NET Framework only exists on Windows"
)
def test_netfx_separate_domain(example_netstandard):
run_in_subprocess(_do_test_netfx, example_netstandard, domain="some domain")


def _do_test_netfx(example_netstandard, **kwargs):
from clr_loader import get_netfx

netfx = get_netfx(**kwargs)
asm = netfx.get_assembly(example_netstandard / "example.dll")

run_tests(asm)

Expand All @@ -142,3 +136,12 @@ def run_tests(asm):
test_data = b"testy mctestface"
res = func(test_data)
assert res == len(test_data)


def run_in_subprocess(func, *args, **kwargs):
from multiprocessing import get_context

p = get_context("spawn").Process(target=func, args=args, kwargs=kwargs)
p.start()
p.join()
p.close()

0 comments on commit a88b6a1

Please sign in to comment.