11using System ;
2+ using System . Collections . Generic ;
23using System . Runtime . InteropServices ;
34
45namespace Python . Runtime
@@ -18,9 +19,6 @@ import sys
1819
1920class DotNetLoader(importlib.abc.Loader):
2021
21- def __init__(self):
22- super().__init__()
23-
2422 @classmethod
2523 def exec_module(klass, mod):
2624 # This method needs to exist.
@@ -32,13 +30,13 @@ import clr
3230 return clr._load_clr_module(spec)
3331
3432class DotNetFinder(importlib.abc.MetaPathFinder):
35-
36- def __init__(self):
37- super().__init__()
38-
33+
3934 @classmethod
4035 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']
4240 if clr._available_namespaces and fullname in clr._available_namespaces:
4341 return importlib.machinery.ModuleSpec(fullname, DotNetLoader(), is_package=True)
4442 return None
@@ -64,13 +62,10 @@ internal static unsafe void Initialize()
6462 BorrowedReference dict = Runtime . PyImport_GetModuleDict ( ) ;
6563 Runtime . PyDict_SetItemString ( dict , "CLR" , ClrModuleReference ) ;
6664 Runtime . PyDict_SetItemString ( dict , "clr" , ClrModuleReference ) ;
67-
68- // Add/create the MetaPathLoader
6965 SetupNamespaceTracking ( ) ;
7066 SetupImportHook ( ) ;
7167 }
7268
73-
7469 /// <summary>
7570 /// Cleanup resources upon shutdown of the Python runtime.
7671 /// </summary>
@@ -81,11 +76,10 @@ internal static void Shutdown()
8176 return ;
8277 }
8378
84- bool shouldFreeDef = Runtime . Refcount ( py_clr_module ) == 1 ;
79+ TeardownNameSpaceTracking ( ) ;
8580 Runtime . XDecref ( py_clr_module ) ;
8681 py_clr_module = IntPtr . Zero ;
8782
88- TeardownNameSpaceTracking ( ) ;
8983 Runtime . XDecref ( root . pyHandle ) ;
9084 root = null ;
9185 CLRModule . Reset ( ) ;
@@ -107,62 +101,42 @@ internal static void RestoreRuntimeData(RuntimeDataStorage storage)
107101 var rootHandle = storage . GetValue < IntPtr > ( "root" ) ;
108102 root = ( CLRModule ) ManagedType . GetManagedObject ( rootHandle ) ;
109103 BorrowedReference dict = Runtime . PyImport_GetModuleDict ( ) ;
110- Runtime . PyDict_SetItemString ( dict . DangerousGetAddress ( ) , "CLR" , py_clr_module ) ;
111104 Runtime . PyDict_SetItemString ( dict . DangerousGetAddress ( ) , "clr" , py_clr_module ) ;
112105 SetupNamespaceTracking ( ) ;
113106 }
114107
115108 static void SetupImportHook ( )
116109 {
117110 // 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" ) ;
120112
121113 // Run the python code to create the module's classes.
122- var mod_dict = Runtime . PyModule_GetDict ( new BorrowedReference ( import_hook_module ) ) ;
123114 var builtins = Runtime . PyEval_GetBuiltins ( ) ;
124115 var exec = Runtime . PyDict_GetItemString ( builtins , "exec" ) ;
125116 using var args = NewReference . DangerousFromPointer ( Runtime . PyTuple_New ( 2 ) ) ;
126117
127- var codeStr = Runtime . PyString_FromString ( LoaderCode ) ;
118+ IntPtr codeStr = Runtime . PyString_FromString ( LoaderCode ) ;
128119 Runtime . PyTuple_SetItem ( args . DangerousGetAddress ( ) , 0 , codeStr ) ;
129120 // PyTuple_SetItem steals a reference, mod_dict is borrowed.
121+ var mod_dict = Runtime . PyModule_GetDict ( import_hook_module ) ;
130122 Runtime . XIncref ( mod_dict . DangerousGetAddress ( ) ) ;
131123 Runtime . PyTuple_SetItem ( args . DangerousGetAddress ( ) , 1 , mod_dict . DangerousGetAddress ( ) ) ;
132124 Runtime . PyObject_Call ( exec . DangerousGetAddress ( ) , args . DangerousGetAddress ( ) , IntPtr . Zero ) ;
133125
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-
153126 // 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 )
156128 {
157- Runtime . XDecref ( import_hook_module ) ;
129+ Runtime . XDecref ( import_hook_module . DangerousGetAddress ( ) ) ;
158130 throw new PythonException ( ) ;
159131 }
160132
161133 // 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 ) ;
164138 var metapath = Runtime . PySys_GetObject ( "meta_path" ) ;
165- Runtime . PyList_Append ( metapath , finder ) ;
139+ Runtime . PyList_Append ( metapath , finder_inst ) ;
166140 }
167141
168142 /// <summary>
@@ -268,7 +242,8 @@ public static unsafe NewReference GetCLRModule()
268242 }
269243
270244 /// <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.
272247 /// </summary>
273248 public static ModuleObject Import ( string modname )
274249 {
@@ -305,7 +280,7 @@ public static ModuleObject Import(string modname)
305280 tail . LoadNames ( ) ;
306281 }
307282 }
308-
283+ tail . IncrRefCount ( ) ;
309284 return tail ;
310285 }
311286
0 commit comments