[pypy-svn] r50737 - in pypy/branch/clr-module-improvements/pypy/module/clr: . test

antocuni at codespeak.net antocuni at codespeak.net
Thu Jan 17 23:07:48 CET 2008


Author: antocuni
Date: Thu Jan 17 23:07:47 2008
New Revision: 50737

Modified:
   pypy/branch/clr-module-improvements/pypy/module/clr/__init__.py
   pypy/branch/clr-module-improvements/pypy/module/clr/app_importer.py
   pypy/branch/clr-module-improvements/pypy/module/clr/interp_clr.py
   pypy/branch/clr-module-improvements/pypy/module/clr/test/test_importer.py
Log:
store the info about namespaces and generics in a global object inside
interp_clr.py, which app_importer queries when needed.



Modified: pypy/branch/clr-module-improvements/pypy/module/clr/__init__.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/__init__.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/__init__.py	Thu Jan 17 23:07:47 2008
@@ -14,10 +14,8 @@
         '_CliObject_internal': 'interp_clr.W_CliObject',
         'call_staticmethod': 'interp_clr.call_staticmethod',
         'load_cli_class': 'interp_clr.load_cli_class',
-        'get_extra_type_info': 'interp_clr.get_extra_type_info',
+        'get_assemblies_info': 'interp_clr.get_assemblies_info',
         'isDotNetType': 'interp_clr.isDotNetType',
-        #'load_assembly': 'interp_clr.load_assembly',
-        #'list_of_loadedAssemblies': 'interp_clr.list_of_loadedAssemblies',
     }
 
     def startup(self, space):

Modified: pypy/branch/clr-module-improvements/pypy/module/clr/app_importer.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/app_importer.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/app_importer.py	Thu Jan 17 23:07:47 2008
@@ -19,25 +19,16 @@
          When importer.find_module("spam.eggs.ham") is called, "spam.eggs" has already 
          been imported and added to sys.modules.
     '''
-    def __init__(self):
-        self.valid_namespaces = None
-        self.generic_mappings = None
 
     def find_module(self, fullname, path=None):
         import clr
-        if self.valid_namespaces is None:
-            # this might not be the correct place to load the valid NameSpaces
-            valid_namespaces, generic_mappings = clr.get_extra_type_info()
-            self.valid_namespaces = set(valid_namespaces)
-            self.generic_mappings = dict(generic_mappings)
-
-        if fullname in self.valid_namespaces or fullname in self.generic_mappings or clr.isDotNetType(fullname): 
-            # fullname is a  .Net Module
-            return self
+        namespaces, generic_map = clr.get_assemblies_info()
+
+        if fullname in namespaces or fullname in generic_map or clr.isDotNetType(fullname): 
+            return self # fullname is a  .NET Module
         else:
-            # fullname is not a .Net Module
-            return None
-            
+            return None # fullname is not a .NET Module
+
     def load_module(self, fullname):
         '''
             The load_module() must fulfill the following *before* it runs any code:
@@ -63,11 +54,13 @@
         '''
         # If it is a call for a Class then return with the Class reference
         import clr
-        if clr.isDotNetType(fullname) or fullname in self.generic_mappings:
+        namespaces, generic_map = clr.get_assemblies_info()
+
+        if clr.isDotNetType(fullname) or fullname in generic_map:
             ''' Task is to breakup System.Collections.ArrayList and call 
                 clr.load_cli_class('System.Collections','ArrayList')
             '''
-            fullname = self.generic_mappings.get(fullname, fullname)
+            fullname = generic_map.get(fullname, fullname)
             rindex = fullname.rfind('.')
             if rindex != -1:
                 leftStr = fullname[:rindex]
@@ -86,15 +79,6 @@
 
             # if it is a PACKAGE then we are to initialize the __path__ for the module
             # we won't deal with Packages here
-
-
-            # treating System.Collections.Generic specially here.
-            # this treatment is done after the empty module insertion
-            #if fullname == "System.Collections.Generic":
-            #    genericClassList = clr.list_of_generic_classes()
-            #    for genericClass in genericClassList:
-            #        sys.modules[genericClass[: genericClass.find('`')]] = clr.load_cli_class("System.Collections.Generic", genericClass)
-
         return sys.modules[fullname]
 
 class CLRModule(types.ModuleType):

Modified: pypy/branch/clr-module-improvements/pypy/module/clr/interp_clr.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/interp_clr.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/interp_clr.py	Thu Jan 17 23:07:47 2008
@@ -193,43 +193,50 @@
         return self.cache.get(fullname, None)
 CliClassCache = _CliClassCache()
 
-def get_extra_type_info(space):
-    """
-    We use this function to play with reflection
-    and then return useful data to the app_importer module
-
-    Parameters:
-
-    Return: List of Valid .NET namespaces
-    """
-    namespaces = {}
-    generics = []
-    currentDomain = System.AppDomain.get_CurrentDomain()
-    assems = currentDomain.GetAssemblies()
-    for i in range(len(assems)):
-        loadedAssembly = assems[i]
-        typesInAssembly = loadedAssembly.GetTypes()
-        for i in range(len(typesInAssembly)):
-            ttype = typesInAssembly[i]
-            namespace = ttype.get_Namespace()
-            if namespace is not None:
-                chunks = namespace.split(".")
-                temp_name = chunks[0]
-                namespaces[temp_name] = None
-                for chunk in chunks[1:]:
-                    temp_name += "."+chunk
-                    namespaces[temp_name] = None
-            if ttype.get_IsGenericType():
-                fullname = ttype.get_FullName()
-                if '+' not in fullname:
-                    # else it's a nested type, ignore it
-                    index = fullname.rfind("`")
-                    assert index >= 0
-                    generics.append((fullname[0:index], fullname))
-    w_listOfNamespaces = wrap_list_of_strings(space, namespaces.keys())
-    w_generic_mappings = wrap_list_of_pairs(space, generics)
-    return space.newtuple([w_listOfNamespaces, w_generic_mappings])
-get_extra_type_info.unwrap_spec = [ObjSpace]
+class _AssembliesInfo:
+    w_namespaces = None
+    w_generic_map = None
+    w_info = None # a tuple containing (w_namespaces, w_generic_map)
+AssembliesInfo = _AssembliesInfo()
+
+def save_info_for_assembly(space, b_assembly):
+    info = AssembliesInfo
+    b_types = b_assembly.GetTypes()
+    for i in range(len(b_types)):
+        b_type = b_types[i]
+        namespace = b_type.get_Namespace()
+        if namespace is not None:
+            # builds all possible sub-namespaces
+            # (e.g. 'System', 'System.Windows', 'System.Windows.Forms')
+            chunks = namespace.split(".")
+            temp_name = chunks[0]
+            space.setitem(info.w_namespaces, space.wrap(temp_name), space.w_None)
+            for chunk in chunks[1:]:
+                temp_name += "."+chunk
+                space.setitem(info.w_namespaces, space.wrap(temp_name), space.w_None)
+        if b_type.get_IsGenericType():
+            fullname = b_type.get_FullName()
+            if '+' not in fullname:
+                index = fullname.rfind("`")
+                assert index >= 0
+                pyName = fullname[0:index]
+                space.setitem(info.w_generic_map, space.wrap(pyName), space.wrap(fullname))
+    
+def save_info_for_all_assemblies(space):
+    b_currentDomain = System.AppDomain.get_CurrentDomain()
+    b_assems = b_currentDomain.GetAssemblies()
+    for i in range(len(b_assems)):
+        save_info_for_assembly(space, b_assems[i])
+
+def get_assemblies_info(space):
+    info = AssembliesInfo
+    if info.w_info is None:
+        info.w_namespaces = space.newdict()
+        info.w_generic_map = space.newdict()
+        info.w_info = space.newtuple([info.w_namespaces, info.w_generic_map])
+        save_info_for_all_assemblies(space) # cache info for all standard assemblies
+    return info.w_info
+get_assemblies_info.unwrap_spec = [ObjSpace]
 
 def isDotNetType(space, nameFromImporter):
     """
@@ -241,57 +248,6 @@
     return space.wrap(System.Type.GetType(nameFromImporter) is not None)
 isDotNetType.unwrap_spec = [ObjSpace, str]
 
-##def list_of_loadedAssemblies(space):
-##    """
-##    return a List of currently loaded .NET assembliesy
-
-##    return:
-##        list eg:  ['System.Xml','System.Data','mscorlib']
-##    """
-##    loadedAssemblies = []
-##    currentDomain = System.AppDomain.get_CurrentDomain()
-##    currentLoadedAssemblies = currentDomain.GetAssemblies()
-
-##    for i in range(len(currentLoadedAssemblies)):
-##        lAssembly = currentLoadedAssemblies[i]
-##        strName = lAssembly.get_FullName()
-##        rindexComma = strName.find(',')
-##        if rindexComma != -1:
-##            loadedAssemblies.append(strName[:rindexComma])
-##    return space.wrap(loadedAssemblies)
-##list_of_loadedAssemblies.unwrap_spec = [ObjSpace]
-
-##def load_assembly(space, assemblyPath):
-##    """
-##    Load the given .NET assembly into the PyPy interpreter 
-
-##    Parameters:
-
-##       - assemblyPath: the full path of the assembly 
-##          (e.g., /usr/lib/mono/2.0/System.Data.dll).
-##    """
-##    assemblyToLoad = ""
-##    loadedAssemblies = space.unwrap(list_of_loadedAssemblies(space))
-
-##    # split the name to pull out "System.Data.dll"
-##    # then check if it has already been loaded.
-##    rindexSlash = assemblyPath.rfind('/')
-##    if rindexSlash != -1:
-##        strAfterSlash = assemblyPath[rindexSlash +1 : ]
-##        rindexDot = strAfterSlash.rfind('.')
-##        if rindexDot != -1:
-##            assemblyToLoad = strAfterSlash[: rindexDot]
-
-##    if assemblyToLoad in loadedAssemblies:
-##        print " won't reload loaded assembly " 
-##        pass
-##    else:
-##        try:
-##            System.Reflection.Assembly.LoadFile(assemblyPath)
-##            print "Loaded %s"%assemblyPath
-##        except:
-##            print " can not load the assembly " 
-##load_assembly.unwrap_spec = [ObjSpace, str]
 
 def load_cli_class(space, namespace, classname):
     """

Modified: pypy/branch/clr-module-improvements/pypy/module/clr/test/test_importer.py
==============================================================================
--- pypy/branch/clr-module-improvements/pypy/module/clr/test/test_importer.py	(original)
+++ pypy/branch/clr-module-improvements/pypy/module/clr/test/test_importer.py	Thu Jan 17 23:07:47 2008
@@ -7,7 +7,7 @@
 
     def test_list_of_valid_namespaces(self):
         import clr
-        ns, gen = clr.get_extra_type_info()
+        ns, gen = clr.get_assemblies_info()
         
         assert 'System' in ns
         assert 'System.Collections' in ns



More information about the Pypy-commit mailing list