diff --git a/src/runtime/assemblymanager.cs b/src/runtime/assemblymanager.cs index 5d9759375..70134db5f 100644 --- a/src/runtime/assemblymanager.cs +++ b/src/runtime/assemblymanager.cs @@ -338,6 +338,38 @@ public static bool LoadImplicit(string name, bool warn = true) return loaded; } + //=================================================================== + // Return the Assembly for a given name + //=================================================================== + internal static Assembly GetAssembly(string name) + { + string[] names = name.Split('.'); + string s = ""; + HashSet assembliesSet = null; + for (int i = 0; i < names.Length; i++) + { + s = (i == 0) ? names[0] : s + "." + names[i]; + if (assembliesSet == null) + { + assembliesSet = new HashSet(AppDomain.CurrentDomain.GetAssemblies()); + } + Assembly a = FindLoadedAssembly(s); + if (a == null) + { + a = LoadAssemblyPath(s); + } + if (a == null) + { + a = LoadAssembly(s); + } + if (a != null && assembliesSet.Contains(a)) + { + return a; + } + } + return null; + } + //=================================================================== // Scans an assembly for exported namespaces, adding them to the diff --git a/src/runtime/importhook.cs b/src/runtime/importhook.cs index 8f8f032db..0da6431dd 100644 --- a/src/runtime/importhook.cs +++ b/src/runtime/importhook.cs @@ -278,7 +278,35 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) { // May be called when a module being imported imports a module. // In particular, I've seen decimal import copy import org.python.core - return Runtime.PyObject_Call(py_import, args, kw); + var res = Runtime.PyObject_Call(py_import, args, kw); + + // Check if there is an ImportError Exception if so + // determine which dependencies are missing + if(Exceptions.ExceptionMatches(Exceptions.ImportError)) + { + var target_assembly = AssemblyManager.GetAssembly(realname); + if (target_assembly != null) + { + System.Collections.Generic.List missing_dependencies = + new System.Collections.Generic.List(); + foreach (var assembly in target_assembly.GetReferencedAssemblies()) + { + var depedentAssembly = AssemblyManager.LoadAssembly(assembly.Name); + if (depedentAssembly == null) + missing_dependencies.Add(assembly.Name); + } + + if (missing_dependencies.Count > 0) + { + // We found missing dependencies + string error = String.Format("No module named {0} missing dependencies {1}", + realname, String.Join(", ", missing_dependencies)); + Exceptions.SetError(Exceptions.ImportError, error); + } + } + } + return res; + } } diff --git a/src/tests/test_suite/TestDependencyAssembly.dll b/src/tests/test_suite/TestDependencyAssembly.dll new file mode 100644 index 000000000..d33ce392a Binary files /dev/null and b/src/tests/test_suite/TestDependencyAssembly.dll differ diff --git a/src/tests/test_suite/_missing_import_dependency.py b/src/tests/test_suite/_missing_import_dependency.py new file mode 100644 index 000000000..bc69663dc --- /dev/null +++ b/src/tests/test_suite/_missing_import_dependency.py @@ -0,0 +1,5 @@ +import os +import clr +path_to_dll = os.path.join(os.path.dirname(__file__), "TestDependencyAssembly.dll") +clr.AddReference(path_to_dll) +from TestDependencyAssembly import TestDependency \ No newline at end of file diff --git a/src/tests/test_suite/test_import.py b/src/tests/test_suite/test_import.py index b6d155af3..5a9af0843 100644 --- a/src/tests/test_suite/test_import.py +++ b/src/tests/test_suite/test_import.py @@ -9,6 +9,12 @@ def testRealtiveMissingImport(self): from . import _missing_import except ImportError: pass + + def testMissingImportDepencency(self): + missing_dependency_name = "MissingDependencyAssembly" + with self.assertRaisesRegexp(ImportError, missing_dependency_name): + from . import _missing_import_dependency + def test_suite():