-
Notifications
You must be signed in to change notification settings - Fork 23
/
netfx.py
75 lines (57 loc) · 1.84 KB
/
netfx.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import atexit
from pathlib import Path
from typing import Any, Optional
from .ffi import ffi, load_netfx
from .types import Runtime, RuntimeInfo, StrOrPath
_FW: Any = None
class NetFx(Runtime):
def __init__(
self, domain: Optional[str] = None, config_file: Optional[Path] = None
):
self._domain = None
initialize()
if config_file is not None:
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_s, config_file_s)
def info(self) -> RuntimeInfo:
return RuntimeInfo(
kind=".NET Framework",
version="<undefined>",
initialized=True,
shutdown=_FW is None,
properties=dict(
domain=self._domain_name or "", config_file=str(self._config_file)
),
)
def _get_callable(self, assembly_path: StrOrPath, typename: str, function: str):
func = _FW.pyclr_get_function(
self._domain,
str(Path(assembly_path)).encode("utf8"),
typename.encode("utf8"),
function.encode("utf8"),
)
if func == ffi.NULL:
raise RuntimeError(
f"Failed to resolve {typename}.{function} from {assembly_path}"
)
return func
def shutdown(self):
if self._domain and _FW:
_FW.pyclr_close_appdomain(self._domain)
def initialize():
global _FW
if _FW is not None:
return
_FW = load_netfx()
_FW.pyclr_initialize()
atexit.register(_release)
def _release():
global _FW
if _FW is not None:
_FW.pyclr_finalize()
_FW = None