Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
28 changes: 12 additions & 16 deletions src/runtime/arrayobject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
}


//====================================================================
// Implements __getitem__ for array types.
//====================================================================

/// <summary>
/// Implements __getitem__ for array types.
/// </summary>
public static IntPtr mp_subscript(IntPtr ob, IntPtr idx)
{
CLRObject obj = (CLRObject)ManagedType.GetManagedObject(ob);
Expand Down Expand Up @@ -131,10 +130,9 @@ public static IntPtr mp_subscript(IntPtr ob, IntPtr idx)
}


//====================================================================
// Implements __setitem__ for array types.
//====================================================================

/// <summary>
/// Implements __setitem__ for array types.
/// </summary>
public static int mp_ass_subscript(IntPtr ob, IntPtr idx, IntPtr v)
{
CLRObject obj = (CLRObject)ManagedType.GetManagedObject(ob);
Expand Down Expand Up @@ -226,10 +224,9 @@ public static int mp_ass_subscript(IntPtr ob, IntPtr idx, IntPtr v)
}


//====================================================================
// Implements __contains__ for array types.
//====================================================================

/// <summary>
/// Implements __contains__ for array types.
/// </summary>
public static int sq_contains(IntPtr ob, IntPtr v)
{
CLRObject obj = (CLRObject)ManagedType.GetManagedObject(ob);
Expand All @@ -251,10 +248,9 @@ public static int sq_contains(IntPtr ob, IntPtr v)
}


//====================================================================
// Implements __len__ for array types.
//====================================================================

/// <summary>
/// Implements __len__ for array types.
/// </summary>
public static int mp_length(IntPtr ob)
{
CLRObject self = (CLRObject)ManagedType.GetManagedObject(ob);
Expand Down
188 changes: 88 additions & 100 deletions src/runtime/assemblymanager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@ private AssemblyManager()
{
}

//===================================================================
// Initialization performed on startup of the Python runtime. Here we
// scan all of the currently loaded assemblies to determine exported
// names, and register to be notified of new assembly loads.
//===================================================================

/// <summary>
/// Initialization performed on startup of the Python runtime. Here we
/// scan all of the currently loaded assemblies to determine exported
/// names, and register to be notified of new assembly loads.
/// </summary>
internal static void Initialize()
{
namespaces = new ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>>();
Expand Down Expand Up @@ -69,10 +68,9 @@ internal static void Initialize()
}


//===================================================================
// Cleanup resources upon shutdown of the Python runtime.
//===================================================================

/// <summary>
/// Cleanup resources upon shutdown of the Python runtime.
/// </summary>
internal static void Shutdown()
{
AppDomain domain = AppDomain.CurrentDomain;
Expand All @@ -81,14 +79,13 @@ internal static void Shutdown()
}


//===================================================================
// Event handler for assembly load events. At the time the Python
// runtime loads, we scan the app domain to map the assemblies that
// are loaded at the time. We also have to register this event handler
// so that we can know about assemblies that get loaded after the
// Python runtime is initialized.
//===================================================================

/// <summary>
/// Event handler for assembly load events. At the time the Python
/// runtime loads, we scan the app domain to map the assemblies that
/// are loaded at the time. We also have to register this event handler
/// so that we can know about assemblies that get loaded after the
/// Python runtime is initialized.
/// </summary>
static void AssemblyLoadHandler(Object ob, AssemblyLoadEventArgs args)
{
Assembly assembly = args.LoadedAssembly;
Expand All @@ -97,14 +94,13 @@ static void AssemblyLoadHandler(Object ob, AssemblyLoadEventArgs args)
}


//===================================================================
// Event handler for assembly resolve events. This is needed because
// we augment the assembly search path with the PYTHONPATH when we
// load an assembly from Python. Because of that, we need to listen
// for failed loads, because they might be dependencies of something
// we loaded from Python which also needs to be found on PYTHONPATH.
//===================================================================

/// <summary>
/// Event handler for assembly resolve events. This is needed because
/// we augment the assembly search path with the PYTHONPATH when we
/// load an assembly from Python. Because of that, we need to listen
/// for failed loads, because they might be dependencies of something
/// we loaded from Python which also needs to be found on PYTHONPATH.
/// </summary>
static Assembly ResolveHandler(Object ob, ResolveEventArgs args)
{
string name = args.Name.ToLower();
Expand All @@ -120,19 +116,17 @@ static Assembly ResolveHandler(Object ob, ResolveEventArgs args)
}


//===================================================================
// We __really__ want to avoid using Python objects or APIs when
// probing for assemblies to load, since our ResolveHandler may be
// called in contexts where we don't have the Python GIL and can't
// even safely try to get it without risking a deadlock ;(
//
// To work around that, we update a managed copy of sys.path (which
// is the main thing we care about) when UpdatePath is called. The
// import hook calls this whenever it knows its about to use the
// assembly manager, which lets us keep up with changes to sys.path
// in a relatively lightweight and low-overhead way.
//===================================================================

/// <summary>
/// We __really__ want to avoid using Python objects or APIs when
/// probing for assemblies to load, since our ResolveHandler may be
/// called in contexts where we don't have the Python GIL and can't
/// even safely try to get it without risking a deadlock ;(
/// To work around that, we update a managed copy of sys.path (which
/// is the main thing we care about) when UpdatePath is called. The
/// import hook calls this whenever it knows its about to use the
/// assembly manager, which lets us keep up with changes to sys.path
/// in a relatively lightweight and low-overhead way.
/// </summary>
internal static void UpdatePath()
{
IntPtr list = Runtime.PySys_GetObject("path");
Expand All @@ -154,12 +148,11 @@ internal static void UpdatePath()
}


//===================================================================
// Given an assembly name, try to find this assembly file using the
// PYTHONPATH. If not found, return null to indicate implicit load
// using standard load semantics (app base directory then GAC, etc.)
//===================================================================

/// <summary>
/// Given an assembly name, try to find this assembly file using the
/// PYTHONPATH. If not found, return null to indicate implicit load
/// using standard load semantics (app base directory then GAC, etc.)
/// </summary>
public static string FindAssembly(string name)
{
char sep = Path.DirectorySeparatorChar;
Expand Down Expand Up @@ -193,11 +186,10 @@ public static string FindAssembly(string name)
}


//===================================================================
// Loads an assembly from the application directory or the GAC
// given a simple assembly name. Returns the assembly if loaded.
//===================================================================

/// <summary>
/// Loads an assembly from the application directory or the GAC
/// given a simple assembly name. Returns the assembly if loaded.
/// </summary>
public static Assembly LoadAssembly(string name)
{
Assembly assembly = null;
Expand All @@ -216,10 +208,9 @@ public static Assembly LoadAssembly(string name)
}


//===================================================================
// Loads an assembly using an augmented search path (the python path).
//===================================================================

/// <summary>
/// Loads an assembly using an augmented search path (the python path).
/// </summary>
public static Assembly LoadAssemblyPath(string name)
{
string path = FindAssembly(name);
Expand All @@ -240,8 +231,10 @@ public static Assembly LoadAssemblyPath(string name)
/// <summary>
/// Loads an assembly using full path.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
/// <param name="name">
/// </param>
/// <returns>
/// </returns>
public static Assembly LoadAssemblyFullPath(string name)
{
Assembly assembly = null;
Expand All @@ -263,10 +256,9 @@ public static Assembly LoadAssemblyFullPath(string name)
return assembly;
}

//===================================================================
// Returns an assembly that's already been loaded
//===================================================================

/// <summary>
/// Returns an assembly that's already been loaded
/// </summary>
public static Assembly FindLoadedAssembly(string name)
{
foreach (Assembly a in assemblies)
Expand All @@ -279,18 +271,19 @@ public static Assembly FindLoadedAssembly(string name)
return null;
}

//===================================================================
// Given a qualified name of the form A.B.C.D, attempt to load
// an assembly named after each of A.B.C.D, A.B.C, A.B, A. This
// will only actually probe for the assembly once for each unique
// namespace. Returns true if any assemblies were loaded.
// TODO item 3 "* Deprecate implicit loading of assemblies":
// Set the fromFile flag if the name of the loaded assembly matches
// the fully qualified name that was requested if the framework
// actually loads an assembly.
// Call ONLY for namespaces that HAVE NOT been cached yet.
//===================================================================

/// <summary>
/// Given a qualified name of the form A.B.C.D, attempt to load
/// an assembly named after each of A.B.C.D, A.B.C, A.B, A. This
/// will only actually probe for the assembly once for each unique
/// namespace. Returns true if any assemblies were loaded.
/// </summary>
/// <remarks>
/// TODO item 3 "* Deprecate implicit loading of assemblies":
/// Set the fromFile flag if the name of the loaded assembly matches
/// the fully qualified name that was requested if the framework
/// actually loads an assembly.
/// Call ONLY for namespaces that HAVE NOT been cached yet.
/// </remarks>
public static bool LoadImplicit(string name, bool warn = true)
{
string[] names = name.Split('.');
Expand Down Expand Up @@ -339,13 +332,12 @@ public static bool LoadImplicit(string name, bool warn = true)
}


//===================================================================
// Scans an assembly for exported namespaces, adding them to the
// mapping of valid namespaces. Note that for a given namespace
// a.b.c.d, each of a, a.b, a.b.c and a.b.c.d are considered to
// be valid namespaces (to better match Python import semantics).
//===================================================================

/// <summary>
/// Scans an assembly for exported namespaces, adding them to the
/// mapping of valid namespaces. Note that for a given namespace
/// a.b.c.d, each of a, a.b, a.b.c and a.b.c.d are considered to
/// be valid namespaces (to better match Python import semantics).
/// </summary>
internal static void ScanAssembly(Assembly assembly)
{
// A couple of things we want to do here: first, we want to
Expand Down Expand Up @@ -390,20 +382,18 @@ public static AssemblyName[] ListAssemblies()
return names.ToArray();
}

//===================================================================
// Returns true if the given qualified name matches a namespace
// exported by an assembly loaded in the current app domain.
//===================================================================

/// <summary>
/// Returns true if the given qualified name matches a namespace
/// exported by an assembly loaded in the current app domain.
/// </summary>
public static bool IsValidNamespace(string name)
{
return !String.IsNullOrEmpty(name) && namespaces.ContainsKey(name);
}

//===================================================================
// Returns list of assemblies that declare types in a given namespace
//===================================================================

/// <summary>
/// Returns list of assemblies that declare types in a given namespace
/// </summary>
public static IEnumerable<Assembly> GetAssemblies(string nsname)
{
if (!namespaces.ContainsKey(nsname))
Expand All @@ -412,10 +402,9 @@ public static IEnumerable<Assembly> GetAssemblies(string nsname)
return namespaces[nsname].Keys;
}

//===================================================================
// Returns the current list of valid names for the input namespace.
//===================================================================

/// <summary>
/// Returns the current list of valid names for the input namespace.
/// </summary>
public static List<string> GetNames(string nsname)
{
//Dictionary<string, int> seen = new Dictionary<string, int>();
Expand Down Expand Up @@ -460,12 +449,11 @@ public static List<string> GetNames(string nsname)
return names;
}

//===================================================================
// Returns the System.Type object for a given qualified name,
// looking in the currently loaded assemblies for the named
// type. Returns null if the named type cannot be found.
//===================================================================

/// <summary>
/// Returns the System.Type object for a given qualified name,
/// looking in the currently loaded assemblies for the named
/// type. Returns null if the named type cannot be found.
/// </summary>
public static Type LookupType(string qname)
{
foreach (Assembly assembly in assemblies)
Expand Down Expand Up @@ -528,8 +516,8 @@ public IEnumerator GetEnumerator()
}

/// <summary>
/// Enumerator wrapping around <see cref="AssemblyList._list"/>'s enumerator.
/// Acquires and releases a read lock on <see cref="AssemblyList._lock"/> during enumeration
/// Enumerator wrapping around <see cref="AssemblyList._list" />'s enumerator.
/// Acquires and releases a read lock on <see cref="AssemblyList._lock" /> during enumeration
/// </summary>
private class Enumerator : IEnumerator<Assembly>
{
Expand Down
Loading