1
1
using System ;
2
+ using System . Collections . Generic ;
2
3
using System . Runtime . InteropServices ;
3
4
4
5
namespace Python . Runtime
@@ -18,9 +19,6 @@ import sys
18
19
19
20
class DotNetLoader(importlib.abc.Loader):
20
21
21
- def __init__(self):
22
- super().__init__()
23
-
24
22
@classmethod
25
23
def exec_module(klass, mod):
26
24
# This method needs to exist.
@@ -32,13 +30,13 @@ import clr
32
30
return clr._load_clr_module(spec)
33
31
34
32
class DotNetFinder(importlib.abc.MetaPathFinder):
35
-
36
- def __init__(self):
37
- super().__init__()
38
-
33
+
39
34
@classmethod
40
35
def find_spec(klass, fullname, paths=None, target=None):
41
- import clr
36
+ # Don't import, we might call ourselves recursively!
37
+ if 'clr' not in sys.modules:
38
+ return None
39
+ clr = sys.modules['clr']
42
40
if clr._available_namespaces and fullname in clr._available_namespaces:
43
41
return importlib.machinery.ModuleSpec(fullname, DotNetLoader(), is_package=True)
44
42
return None
@@ -64,13 +62,10 @@ internal static unsafe void Initialize()
64
62
BorrowedReference dict = Runtime . PyImport_GetModuleDict ( ) ;
65
63
Runtime . PyDict_SetItemString ( dict , "CLR" , ClrModuleReference ) ;
66
64
Runtime . PyDict_SetItemString ( dict , "clr" , ClrModuleReference ) ;
67
-
68
- // Add/create the MetaPathLoader
69
65
SetupNamespaceTracking ( ) ;
70
66
SetupImportHook ( ) ;
71
67
}
72
68
73
-
74
69
/// <summary>
75
70
/// Cleanup resources upon shutdown of the Python runtime.
76
71
/// </summary>
@@ -81,11 +76,10 @@ internal static void Shutdown()
81
76
return ;
82
77
}
83
78
84
- bool shouldFreeDef = Runtime . Refcount ( py_clr_module ) == 1 ;
79
+ TeardownNameSpaceTracking ( ) ;
85
80
Runtime . XDecref ( py_clr_module ) ;
86
81
py_clr_module = IntPtr . Zero ;
87
82
88
- TeardownNameSpaceTracking ( ) ;
89
83
Runtime . XDecref ( root . pyHandle ) ;
90
84
root = null ;
91
85
CLRModule . Reset ( ) ;
@@ -107,62 +101,42 @@ internal static void RestoreRuntimeData(RuntimeDataStorage storage)
107
101
var rootHandle = storage . GetValue < IntPtr > ( "root" ) ;
108
102
root = ( CLRModule ) ManagedType . GetManagedObject ( rootHandle ) ;
109
103
BorrowedReference dict = Runtime . PyImport_GetModuleDict ( ) ;
110
- Runtime . PyDict_SetItemString ( dict . DangerousGetAddress ( ) , "CLR" , py_clr_module ) ;
111
104
Runtime . PyDict_SetItemString ( dict . DangerousGetAddress ( ) , "clr" , py_clr_module ) ;
112
105
SetupNamespaceTracking ( ) ;
113
106
}
114
107
115
108
static void SetupImportHook ( )
116
109
{
117
110
// Create the import hook module
118
- var import_hook_module_def = ModuleDefOffset . AllocModuleDef ( "clr.loader" ) ;
119
- var import_hook_module = Runtime . PyModule_Create2 ( import_hook_module_def , 3 ) ;
111
+ var import_hook_module = Runtime . PyModule_New ( "clr.loader" ) ;
120
112
121
113
// Run the python code to create the module's classes.
122
- var mod_dict = Runtime . PyModule_GetDict ( new BorrowedReference ( import_hook_module ) ) ;
123
114
var builtins = Runtime . PyEval_GetBuiltins ( ) ;
124
115
var exec = Runtime . PyDict_GetItemString ( builtins , "exec" ) ;
125
116
using var args = NewReference . DangerousFromPointer ( Runtime . PyTuple_New ( 2 ) ) ;
126
117
127
- var codeStr = Runtime . PyString_FromString ( LoaderCode ) ;
118
+ IntPtr codeStr = Runtime . PyString_FromString ( LoaderCode ) ;
128
119
Runtime . PyTuple_SetItem ( args . DangerousGetAddress ( ) , 0 , codeStr ) ;
129
120
// PyTuple_SetItem steals a reference, mod_dict is borrowed.
121
+ var mod_dict = Runtime . PyModule_GetDict ( import_hook_module ) ;
130
122
Runtime . XIncref ( mod_dict . DangerousGetAddress ( ) ) ;
131
123
Runtime . PyTuple_SetItem ( args . DangerousGetAddress ( ) , 1 , mod_dict . DangerousGetAddress ( ) ) ;
132
124
Runtime . PyObject_Call ( exec . DangerousGetAddress ( ) , args . DangerousGetAddress ( ) , IntPtr . Zero ) ;
133
125
134
- var loader = Runtime . PyDict_GetItemString ( mod_dict , "DotNetLoader" ) . DangerousGetAddressOrNull ( ) ;
135
- Runtime . XIncref ( loader ) ;
136
-
137
- // Add the classes to the module
138
- // PyModule_AddObject steals a reference only on success
139
- if ( Runtime . PyModule_AddObject ( import_hook_module , "DotNetLoader" , loader ) != 0 )
140
- {
141
- Runtime . XDecref ( loader ) ;
142
- throw new PythonException ( ) ;
143
- }
144
-
145
- var finder = Runtime . PyDict_GetItemString ( mod_dict , "DotNetFinder" ) . DangerousGetAddressOrNull ( ) ;
146
- Runtime . XIncref ( finder ) ;
147
- if ( Runtime . PyModule_AddObject ( import_hook_module , "DotNetFinder" , finder ) != 0 )
148
- {
149
- Runtime . XDecref ( finder ) ;
150
- throw new PythonException ( ) ;
151
- }
152
-
153
126
// Set as a sub-module of clr.
154
- Runtime . XIncref ( import_hook_module ) ;
155
- if ( Runtime . PyModule_AddObject ( py_clr_module , "loader" , import_hook_module ) != 0 )
127
+ if ( Runtime . PyModule_AddObject ( ClrModuleReference , "loader" , import_hook_module ) != 0 )
156
128
{
157
- Runtime . XDecref ( import_hook_module ) ;
129
+ Runtime . XDecref ( import_hook_module . DangerousGetAddress ( ) ) ;
158
130
throw new PythonException ( ) ;
159
131
}
160
132
161
133
// Finally, add the hook to the meta path
162
- var finder_inst = Runtime . PyDict_GetItemString ( mod_dict , "finder_inst" ) . DangerousGetAddressOrNull ( ) ;
163
- Runtime . XIncref ( finder ) ;
134
+ var findercls = Runtime . PyDict_GetItemString ( mod_dict , "DotNetFinder" ) ;
135
+ var finderCtorArgs = Runtime . PyTuple_New ( 0 ) ;
136
+ var finder_inst = Runtime . PyObject_CallObject ( findercls . DangerousGetAddress ( ) , finderCtorArgs ) ;
137
+ Runtime . XDecref ( finderCtorArgs ) ;
164
138
var metapath = Runtime . PySys_GetObject ( "meta_path" ) ;
165
- Runtime . PyList_Append ( metapath , finder ) ;
139
+ Runtime . PyList_Append ( metapath , finder_inst ) ;
166
140
}
167
141
168
142
/// <summary>
@@ -268,7 +242,8 @@ public static unsafe NewReference GetCLRModule()
268
242
}
269
243
270
244
/// <summary>
271
- /// The hook to import a CLR module into Python
245
+ /// The hook to import a CLR module into Python. Returns a new reference
246
+ /// to the module.
272
247
/// </summary>
273
248
public static ModuleObject Import ( string modname )
274
249
{
@@ -305,7 +280,7 @@ public static ModuleObject Import(string modname)
305
280
tail . LoadNames ( ) ;
306
281
}
307
282
}
308
-
283
+ tail . IncrRefCount ( ) ;
309
284
return tail ;
310
285
}
311
286
0 commit comments