Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7ae19e2

Browse files
committed
Remove deprecated implicit assembly loading
Legacy behavior: `import Company.Product.Namespace` would search for `Company.Product.Namespace.dll` .NET assmebly, load it, and import the namespace. New behavior: User must always explicitly add assembly reference using `clr.AddReference` to `Company.Product.Namespace` prior to attempting import
1 parent 73ddf8b commit 7ae19e2

File tree

4 files changed

+4
-125
lines changed

4 files changed

+4
-125
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ details about the cause of the failure
3333
- Fixed a bug where indexers could not be used if they were inherited
3434
- Made it possible to use `__len__` also on `ICollection<>` interface objects
3535

36+
### Removed
37+
38+
- implicit assembly loading (you have to explicitly `clr.AddReference` before doing import)
39+
3640
## [2.5.0][] - 2020-06-14
3741

3842
This version improves performance on benchmarks significantly compared to 2.3.

src/runtime/assemblymanager.cs

-69
Original file line numberDiff line numberDiff line change
@@ -252,75 +252,6 @@ public static Assembly FindLoadedAssembly(string name)
252252
return null;
253253
}
254254

255-
/// <summary>
256-
/// Given a qualified name of the form A.B.C.D, attempt to load
257-
/// an assembly named after each of A.B.C.D, A.B.C, A.B, A. This
258-
/// will only actually probe for the assembly once for each unique
259-
/// namespace. Returns true if any assemblies were loaded.
260-
/// </summary>
261-
/// <remarks>
262-
/// TODO item 3 "* Deprecate implicit loading of assemblies":
263-
/// Set the fromFile flag if the name of the loaded assembly matches
264-
/// the fully qualified name that was requested if the framework
265-
/// actually loads an assembly.
266-
/// Call ONLY for namespaces that HAVE NOT been cached yet.
267-
/// </remarks>
268-
public static bool LoadImplicit(string name, Action<Exception> assemblyLoadErrorHandler, bool warn = true)
269-
{
270-
string[] names = name.Split('.');
271-
var loaded = false;
272-
var s = "";
273-
Assembly lastAssembly = null;
274-
HashSet<Assembly> assembliesSet = null;
275-
for (var i = 0; i < names.Length; i++)
276-
{
277-
s = i == 0 ? names[0] : s + "." + names[i];
278-
if (!probed.ContainsKey(s))
279-
{
280-
if (assembliesSet == null)
281-
{
282-
assembliesSet = new HashSet<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
283-
}
284-
Assembly a = FindLoadedAssembly(s);
285-
try
286-
{
287-
if (a == null)
288-
{
289-
a = LoadAssemblyPath(s);
290-
}
291-
292-
if (a == null)
293-
{
294-
a = LoadAssembly(s);
295-
}
296-
}
297-
catch (FileLoadException e) { assemblyLoadErrorHandler(e); }
298-
catch (BadImageFormatException e) { assemblyLoadErrorHandler(e); }
299-
catch (System.Security.SecurityException e) { assemblyLoadErrorHandler(e); }
300-
catch (PathTooLongException e) { assemblyLoadErrorHandler(e); }
301-
302-
if (a != null && !assembliesSet.Contains(a))
303-
{
304-
loaded = true;
305-
lastAssembly = a;
306-
}
307-
probed[s] = 1;
308-
}
309-
}
310-
311-
// Deprecation warning
312-
if (warn && loaded)
313-
{
314-
string location = Path.GetFileNameWithoutExtension(lastAssembly.Location);
315-
string deprWarning = "The module was found, but not in a referenced namespace.\n" +
316-
$"Implicit loading is deprecated. Please use clr.AddReference('{location}').";
317-
Exceptions.deprecation(deprWarning);
318-
}
319-
320-
return loaded;
321-
}
322-
323-
324255
/// <summary>
325256
/// Scans an assembly for exported namespaces, adding them to the
326257
/// mapping of valid namespaces. Note that for a given namespace

src/runtime/importhook.cs

-32
Original file line numberDiff line numberDiff line change
@@ -310,38 +310,6 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
310310

311311
string[] names = realname.Split('.');
312312

313-
// Now we need to decide if the name refers to a CLR module,
314-
// and may have to do an implicit load (for b/w compatibility)
315-
// using the AssemblyManager. The assembly manager tries
316-
// really hard not to use Python objects or APIs, because
317-
// parts of it can run recursively and on strange threads.
318-
//
319-
// It does need an opportunity from time to time to check to
320-
// see if sys.path has changed, in a context that is safe. Here
321-
// we know we have the GIL, so we'll let it update if needed.
322-
323-
AssemblyManager.UpdatePath();
324-
if (!AssemblyManager.IsValidNamespace(realname))
325-
{
326-
var loadExceptions = new List<Exception>();
327-
if (!AssemblyManager.LoadImplicit(realname, assemblyLoadErrorHandler: loadExceptions.Add))
328-
{
329-
// May be called when a module being imported imports a module.
330-
// In particular, I've seen decimal import copy import org.python.core
331-
IntPtr importResult = Runtime.PyObject_Call(py_import, args, kw);
332-
// TODO: use ModuleNotFoundError in Python 3.6+
333-
if (importResult == IntPtr.Zero && loadExceptions.Count > 0
334-
&& Exceptions.ExceptionMatches(Exceptions.ImportError))
335-
{
336-
loadExceptions.Add(new PythonException());
337-
var importError = new PyObject(new BorrowedReference(Exceptions.ImportError));
338-
importError.SetAttr("__cause__", new AggregateException(loadExceptions).ToPython());
339-
Runtime.PyErr_SetObject(new BorrowedReference(Exceptions.ImportError), importError.Reference);
340-
}
341-
return importResult;
342-
}
343-
}
344-
345313
// See if sys.modules for this interpreter already has the
346314
// requested module. If so, just return the existing module.
347315
IntPtr modules = Runtime.PyImport_GetModuleDict();

src/runtime/moduleobject.cs

-24
Original file line numberDiff line numberDiff line change
@@ -118,30 +118,6 @@ public ManagedType GetAttribute(string name, bool guess)
118118
return c;
119119
}
120120

121-
// This is a little repetitive, but it ensures that the right
122-
// thing happens with implicit assembly loading at a reasonable
123-
// cost. Ask the AssemblyManager to do implicit loading for each
124-
// of the steps in the qualified name, then try it again.
125-
bool ignore = name.StartsWith("__");
126-
if (AssemblyManager.LoadImplicit(qname, assemblyLoadErrorHandler: ImportWarning, !ignore))
127-
{
128-
if (AssemblyManager.IsValidNamespace(qname))
129-
{
130-
m = new ModuleObject(qname);
131-
StoreAttribute(name, m);
132-
m.DecrRefCount();
133-
return m;
134-
}
135-
136-
type = AssemblyManager.LookupTypes(qname).FirstOrDefault(t => t.IsPublic);
137-
if (type != null)
138-
{
139-
c = ClassManager.GetClass(type);
140-
StoreAttribute(name, c);
141-
return c;
142-
}
143-
}
144-
145121
// We didn't find the name, so we may need to see if there is a
146122
// generic type with this base name. If so, we'll go ahead and
147123
// return it. Note that we store the mapping of the unmangled

0 commit comments

Comments
 (0)