public IPythonModule ImportModule(string name) { if (string.IsNullOrWhiteSpace(name)) { return(null); } if (name == _builtinModule?.Name) { return(_builtinModule); } IPythonModule mod; if (_modules.TryGetValue(name, out mod)) { return(mod); } var handle = Remote.LookupNamespace(name); if (!handle.IsNull) { mod = MakeObject(handle) as IPythonModule; if (mod != null) { return(_modules.GetOrAdd(name, mod)); } } if (_factory is AstPythonInterpreterFactory apf) { var ctxt = new AstPythonInterpreterFactory.TryImportModuleContext { Interpreter = this, BuiltinModule = _builtinModule, ModuleCache = _modules }; for (int retries = 5; retries > 0; --retries) { // The call should be cancelled by the cancellation token, but since we // are blocking here we wait for slightly longer. Timeouts are handled // gracefully by TryImportModuleAsync(), so we want those to trigger if // possible, but if all else fails then we'll abort and treat it as an // error. // (And if we've got a debugger attached, don't time out at all.) Task <AstPythonInterpreterFactory.TryImportModuleResult> impTask; #if DEBUG if (Debugger.IsAttached) { impTask = apf.TryImportModuleAsync(name, ctxt, CancellationToken.None); } else { #endif var cts = new CancellationTokenSource(5000); impTask = apf.TryImportModuleAsync(name, ctxt, cts.Token); try { if (!impTask.Wait(10000)) { throw new OperationCanceledException(); } } catch (OperationCanceledException) { Debug.Fail("Import timeout"); return(null); } #if DEBUG } #endif var result = impTask.Result; mod = result.Module; switch (result.Status) { case AstPythonInterpreterFactory.TryImportModuleResultCode.Success: if (mod == null) { _modules.TryRemove(name, out _); break; } return(mod); case AstPythonInterpreterFactory.TryImportModuleResultCode.ModuleNotFound: retries = 0; _modules.TryRemove(name, out _); break; case AstPythonInterpreterFactory.TryImportModuleResultCode.NotSupported: retries = 0; break; case AstPythonInterpreterFactory.TryImportModuleResultCode.NeedRetry: case AstPythonInterpreterFactory.TryImportModuleResultCode.Timeout: break; } } } var nameParts = name.Split('.'); mod = null; if (nameParts.Length > 1 && (mod = ImportModule(nameParts[0])) != null) { for (int i = 1; i < nameParts.Length && mod != null; ++i) { mod = mod.GetMember(IronPythonModuleContext.ShowClrInstance, nameParts[i]) as IPythonModule; } } return(_modules.GetOrAdd(name, mod)); }
public IPythonModule ImportModule(string name) { if (string.IsNullOrWhiteSpace(name)) { return(null); } if (name == _builtinModule?.Name) { return(_builtinModule); } IPythonModule mod; if (_modules.TryGetValue(name, out mod)) { return(mod); } var handle = Remote.LookupNamespace(name); if (!handle.IsNull) { mod = MakeObject(handle) as IPythonModule; if (mod != null) { return(_modules.GetOrAdd(name, mod)); } } if (_typeDb != null) { var res = _typeDb.GetModule(name); if (res != null) { return(res); } } else if (_factory is AstPythonInterpreterFactory apf) { var ctxt = new AstPythonInterpreterFactory.TryImportModuleContext { Interpreter = this, BuiltinModule = _builtinModule, ModuleCache = _modules }; for (int retries = 5; retries > 0; --retries) { switch (apf.TryImportModule(name, out mod, ctxt)) { case AstPythonInterpreterFactory.TryImportModuleResult.Success: if (mod == null) { _modules.TryRemove(name, out _); break; } return(mod); case AstPythonInterpreterFactory.TryImportModuleResult.ModuleNotFound: retries = 0; _modules.TryRemove(name, out _); break; case AstPythonInterpreterFactory.TryImportModuleResult.NotSupported: retries = 0; break; case AstPythonInterpreterFactory.TryImportModuleResult.NeedRetry: case AstPythonInterpreterFactory.TryImportModuleResult.Timeout: break; } } } var nameParts = name.Split('.'); mod = null; if (nameParts.Length > 1 && (mod = ImportModule(nameParts[0])) != null) { for (int i = 1; i < nameParts.Length && mod != null; ++i) { mod = mod.GetMember(IronPythonModuleContext.ShowClrInstance, nameParts[i]) as IPythonModule; } } return(_modules.GetOrAdd(name, mod)); }