Skip to content

Simplify assembly ResolveHandler, and use official assembly name parsing #1570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fixed ImportHook not seeing namespaces in assemblies loaded via direc…
…t call to Assembly.Load* methods
  • Loading branch information
lostmsu committed Sep 24, 2021
commit 904fe328cc4a89dc471a61b7b0ce5a9cbd8ee06a
5 changes: 4 additions & 1 deletion src/runtime/assemblymanager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,10 @@ internal static void ScanAssembly(Assembly assembly)
for (var n = 0; n < names.Length; n++)
{
s = n == 0 ? names[0] : s + "." + names[n];
namespaces.TryAdd(s, new ConcurrentDictionary<Assembly, string>());
if (namespaces.TryAdd(s, new ConcurrentDictionary<Assembly, string>()))
{
ImportHook.AddNamespace(s);
}
}
}

Expand Down
24 changes: 20 additions & 4 deletions src/runtime/importhook.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Collections.Concurrent;

namespace Python.Runtime
{
Expand Down Expand Up @@ -37,6 +36,9 @@ def find_spec(klass, fullname, paths=None, target=None):
if 'clr' not in sys.modules:
return None
clr = sys.modules['clr']

clr._add_pending_namespaces()

if clr._available_namespaces and fullname in clr._available_namespaces:
return importlib.machinery.ModuleSpec(fullname, DotNetLoader(), is_package=True)
return None
Expand Down Expand Up @@ -169,12 +171,26 @@ static void TeardownNameSpaceTracking()
Runtime.PyDict_SetItemString(root.dict, availableNsKey, Runtime.PyNone);
}

public static void AddNamespace(string name)
static readonly ConcurrentQueue<string> addPending = new();
public static void AddNamespace(string name) => addPending.Enqueue(name);

internal static int AddPendingNamespaces()
{
int added = 0;
while (addPending.TryDequeue(out string ns))
{
AddNamespaceWithGIL(ns);
added++;
}
return added;
}

internal static void AddNamespaceWithGIL(string name)
{
var pyNs = Runtime.PyString_FromString(name);
try
{
var nsSet = Runtime.PyDict_GetItemString(new BorrowedReference(root.dict), availableNsKey);
var nsSet = Runtime.PyDict_GetItemString(root.DictRef, availableNsKey);
if (!(nsSet.IsNull || nsSet.DangerousGetAddress() == Runtime.PyNone))
{
if (Runtime.PySet_Add(nsSet, new BorrowedReference(pyNs)) != 0)
Expand Down
9 changes: 7 additions & 2 deletions src/runtime/moduleobject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,9 @@ public static Assembly AddReference(string name)
// method because it may be called from other threads, leading to deadlocks
// if it is called while Python code is executing.
var currNs = AssemblyManager.GetNamespaces().Except(origNs);
foreach(var ns in currNs){
ImportHook.AddNamespace(ns);
foreach(var ns in currNs)
{
ImportHook.AddNamespaceWithGIL(ns);
}
return assembly;
}
Expand Down Expand Up @@ -602,5 +603,9 @@ public static ModuleObject _load_clr_module(PyObject spec)
mod = ImportHook.Import(modname.ToString());
return mod;
}

[ModuleFunction]
[ForbidPythonThreads]
public static int _add_pending_namespaces() => ImportHook.AddPendingNamespaces();
}
}
3 changes: 2 additions & 1 deletion src/runtime/native/TypeOffset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ static void ValidateRequiredOffsetsPresent(PropertyInfo[] offsetProperties)
"Initialize",
"InitializeSlots",
"ListAssemblies",
"_load_clr_module",
nameof(CLRModule._load_clr_module),
nameof(CLRModule._add_pending_namespaces),
"Release",
"Reset",
"set_SuppressDocs",
Expand Down