[pypy-svn] r50821 - in pypy/dist/pypy/translator/cli: . src test

antocuni at codespeak.net antocuni at codespeak.net
Mon Jan 21 12:34:57 CET 2008


Author: antocuni
Date: Mon Jan 21 12:34:55 2008
New Revision: 50821

Modified:
   pypy/dist/pypy/translator/cli/dotnet.py
   pypy/dist/pypy/translator/cli/gencli.py
   pypy/dist/pypy/translator/cli/query.py
   pypy/dist/pypy/translator/cli/rte.py
   pypy/dist/pypy/translator/cli/src/query.cs
   pypy/dist/pypy/translator/cli/support.py
   pypy/dist/pypy/translator/cli/test/test_dotnet.py
   pypy/dist/pypy/translator/cli/test/test_query.py
Log:
a big refactoring of query.py.

Now info about types are loaded per-assembly instead of per-class, and
they are not cached in pypy/_cache; this is much faster, and removes
all that crappy [cli:query] logs.



Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/dotnet.py	Mon Jan 21 12:34:55 2008
@@ -259,6 +259,7 @@
     def compute_result_annotation(self):
         return SomeOOInstance(self.instance._INSTANCE)
 
+
 class CliNamespace(object):
     def __init__(self, name):
         self._name = name
@@ -270,23 +271,19 @@
             return '%s.%s' % (self._name, name)
 
     def __getattr__(self, attr):
-        from pypy.translator.cli.query import load_class_or_namespace
-        # .NET namespace are not self-entities but just parts of the
-        # FullName of a class. This imply that there is no way ask
-        # .NET if a particular name is a namespace; there are many
-        # names that are clearly not namespaces such as im_self and
-        # _freeze_, but there is no general rule and we have to guess.
-        # For now, the heuristic simply check is the first char of the
-        # name is a UPPERCASE letter.
+        from pypy.translator.cli.query import get_cli_class, Types, Namespaces
+        from pypy.translator.cli.query import load_assembly, mscorlib
+        load_assembly(mscorlib)
         
-        if attr[0].isalpha() and attr[0] == attr[0].upper():
-            # we assume it's a class or namespace
-            name = self.__fullname(attr)
-            load_class_or_namespace(name)
-            assert attr in self.__dict__
-            return getattr(self, attr)
+        fullname = self.__fullname(attr)
+        if fullname in Namespaces:
+            value = CliNamespace(fullname)
+        elif fullname in Types:
+            value = get_cli_class(fullname)
         else:
-            raise AttributeError
+            raise AttributeError, attr
+        setattr(self, attr, value)
+        return value
 
 CLR = CliNamespace(None)
 
@@ -421,7 +418,7 @@
         return res
 
 def _create_NativeException(cliClass):
-    from pypy.translator.cli.query import getattr_ex
+    from pypy.translator.cli.support import getattr_ex
     TYPE = cliClass._INSTANCE
     if PythonNet.__name__ in ('CLR', 'clr'):
         # we are using pythonnet -- use the .NET class
@@ -461,12 +458,12 @@
     _about_ = new_array
 
     def compute_result_annotation(self, type_s, length_s):
-        from pypy.translator.cli.query import load_class_maybe
+        from pypy.translator.cli.query import get_cli_class
         assert type_s.is_constant()
         assert isinstance(length_s, SomeInteger)
         TYPE = type_s.const._INSTANCE
         fullname = '%s.%s[]' % (TYPE._namespace, TYPE._classname)
-        cliArray = load_class_maybe(fullname)
+        cliArray = get_cli_class(fullname)
         return SomeOOInstance(cliArray._INSTANCE)
 
     def specialize_call(self, hop):
@@ -479,7 +476,7 @@
     _about_ = init_array
 
     def compute_result_annotation(self, type_s, *args_s):
-        from pypy.translator.cli.query import load_class_maybe
+        from pypy.translator.cli.query import get_cli_class
         assert type_s.is_constant()
         TYPE = type_s.const._INSTANCE
         for i, arg_s in enumerate(args_s):
@@ -487,7 +484,7 @@
                 raise TypeError, 'Wrong type of arg #%d: %s expected, %s found' % \
                       (i, TYPE, arg_s.ootype)
         fullname = '%s.%s[]' % (TYPE._namespace, TYPE._classname)
-        cliArray = load_class_maybe(fullname)
+        cliArray = get_cli_class(fullname)
         return SomeOOInstance(cliArray._INSTANCE)
 
     def specialize_call(self, hop):
@@ -511,9 +508,9 @@
     _about_ = typeof
 
     def compute_result_annotation(self, cliClass_s):
-        from query import load_class_maybe
+        from pypy.translator.cli.query import get_cli_class
         assert cliClass_s.is_constant()
-        cliType = load_class_maybe('System.Type')
+        cliType = get_cli_class('System.Type')
         return SomeOOInstance(cliType._INSTANCE)
 
     def specialize_call(self, hop):

Modified: pypy/dist/pypy/translator/cli/gencli.py
==============================================================================
--- pypy/dist/pypy/translator/cli/gencli.py	(original)
+++ pypy/dist/pypy/translator/cli/gencli.py	Mon Jan 21 12:34:55 2008
@@ -17,7 +17,6 @@
 from pypy.translator.cli.rte import get_pypy_dll
 from pypy.translator.cli.support import Tee
 from pypy.translator.cli.prebuiltnodes import get_prebuilt_nodes
-from pypy.translator.cli import query
 from pypy.translator.cli import constant
 
 class GenCli(GenOO):
@@ -50,7 +49,6 @@
     def generate_source(self):
         GenOO.generate_source(self)
         self.db.const_count.dump(self.const_stat)
-        query.savedesc()
         return self.tmpfile.strpath
 
     def create_assembler(self):

Modified: pypy/dist/pypy/translator/cli/query.py
==============================================================================
--- pypy/dist/pypy/translator/cli/query.py	(original)
+++ pypy/dist/pypy/translator/cli/query.py	Mon Jan 21 12:34:55 2008
@@ -1,149 +1,147 @@
+import sys
 import cPickle as pickle
 import os.path
+import py
 from py.compat import subprocess
+from pypy.tool.udir import udir
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.cli.rte import Query
 from pypy.translator.cli.sdk import SDK
 from pypy.translator.cli.support import log
 from pypy.translator.cli.dotnet import CLR, CliNamespace, CliClass,\
      NativeInstance, _overloaded_static_meth, _static_meth, OverloadingResolver
-    
-ClassCache = {}
-OOTypeCache = {}
-Descriptions = {}
-
-class Dummy: pass
-fake_root = Dummy()
-fake_root._INSTANCE = ootype.ROOT
-ClassCache['ROOT'] = fake_root
-ClassCache['System.Array'] = fake_root
-del fake_root
-del Dummy
-
-def _descfilename(filename):
-    if filename is None:
-        curdir = os.path.dirname(__file__)
-        return os.path.join(curdir, 'query-descriptions')
+
+Assemblies = set()
+Types = {} # TypeName -> ClassDesc
+Namespaces = set()
+mscorlib = 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
+
+#_______________________________________________________________________________
+# This is the public interface of query.py
+
+def load_assembly(name):
+    if name in Assemblies:
+        return
+    Query.get() # clear the cache if we need to recompile
+    _cache = get_cachedir()
+    outfile = _cache.join(name + '.pickle')
+    if outfile.check():
+        f = outfile.open('rb')
+        types = pickle.load(f)
+        f.close()
     else:
-        return filename
+        types = load_and_cache_assembly(name, outfile)
 
-def savedesc(filename=None):
-    f = open(_descfilename(filename), 'wb')
-    pickle.dump(Descriptions, f, protocol=-1)
+    for ttype in types:
+        parts = ttype.split('.')
+        ns = parts[0]
+        Namespaces.add(ns)
+        for part in parts[1:-1]:
+            ns = '%s.%s' % (ns, part)
+            Namespaces.add(ns)
+    Assemblies.add(name)
+    Types.update(types)
+
+
+def get_cli_class(name):
+    desc = get_class_desc(name)
+    return desc.get_cliclass()
+
+#_______________________________________________________________________________
+
+
+def get_cachedir():
+    import pypy
+    _cache = py.path.local(pypy.__file__).new(basename='_cache').ensure(dir=1)
+    return _cache
+
+def load_and_cache_assembly(name, outfile):
+    tmpfile = udir.join(name)
+    arglist = SDK.runtime() + [Query.get(), name, str(tmpfile)]
+    retcode = subprocess.call(arglist)
+    assert retcode == 0
+    mydict = {}
+    execfile(str(tmpfile), mydict)
+    types = mydict['types']
+    f = outfile.open('wb')
+    pickle.dump(types, f, pickle.HIGHEST_PROTOCOL)
     f.close()
+    return types
 
-def loaddesc(filename=None):
-    filename = _descfilename(filename)
-    if not os.path.exists(filename):
-        return
-    f = open(filename, 'rb')
-    try:
-        newdesc = pickle.load(f)        
-    except pickle.UnpicklingError:
-        log.WARNING('query-descriptions file exits, but failed to unpickle')
+def get_ootype(name):
+    # a bit messy, but works
+    if name.startswith('ootype.'):
+        _, name = name.split('.')
+        return getattr(ootype, name)
     else:
-        Descriptions.clear()
-        Descriptions.update(newdesc)
+        cliclass = get_cli_class(name)
+        return cliclass._INSTANCE
 
-def getattr_ex(target, attr):
-    parts = attr.split('.')
-    for part in parts:
-        target = getattr(target, part)
-    return target
-
-def setattr_ex(target, attr, value):
-    if '.' in attr:
-        namespace, attr = attr.rsplit('.', 1)
-        target = getattr_ex(target, namespace)
-    setattr(target, attr, value)
-
-def load_class_or_namespace(name):
-    try:
-        desc = Descriptions[name]
-    except KeyError:
-        desc = query_description(name)
-        Descriptions[name] = desc
-    res = desc.build()
-    setattr_ex(CLR, name, res)
-    return res
-
-def query_description(name):
-    log.query('Loading description for %s' % name)
-    arglist = SDK.runtime() + [Query.get(), name]
-    query = subprocess.Popen(arglist, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                             universal_newlines=True)
-    stdout, stderr = query.communicate()
-    retval = query.wait()
-    if retval == 0:
-        cls = ClassDesc()
-        exec stdout in cls.__dict__
-        del cls.__dict__['__builtins__']
-        return cls
-    elif retval == 1:
-        raise RuntimeError, 'query.exe failed with this message:\n%s' % stderr
-    elif retval == 2:
-        # can't load type, assume it's a namespace
-        return NamespaceDesc(name)
-
-def load_class_maybe(name):
-    if name.startswith('System.Array+InternalArray'):
-        res = ClassCache['System.Array']
-        ClassCache[name] = res
-        return res
-    elif name not in ClassCache:
-        return load_class_or_namespace(name)
+def get_class_desc(name):
+    if name in Types:
+        return Types[name]
+
+    if name == 'System.Array':
+        desc = ClassDesc()
+        desc.Assembly = mscorlib
+        desc.FullName = name
+        desc.BaseType = 'System.Object'
+        desc.IsArray = True
+        desc.ElementType = 'System.Object' # not really true, but we need something
+        desc.StaticMethods = []
+        desc.Methods = []
+    elif name.endswith('[]'): # it's an array
+        itemname = name[:-2]
+        itemdesc = get_class_desc(itemname)
+        desc = ClassDesc()
+        desc.Assembly = mscorlib
+        desc.FullName = name
+        desc.BaseType = 'System.Array'
+        desc.ElementType = itemdesc.FullName
+        desc.IsArray = True
+        desc.StaticMethods = []
+        desc.Methods = [
+            ('Get', ['ootype.Signed', ], itemdesc.FullName),
+            ('Set', ['ootype.Signed', itemdesc.FullName], 'ootype.Void')
+            ]
     else:
-        return ClassCache[name]
+        assert False, 'Unknown desc'
+
+    Types[name] = desc
+    return desc
+
 
+class ClassDesc(object):
+    _cliclass = None
 
-class Desc:
-    def build(self):
-        raise NotImplementedError
-    
     def __eq__(self, other):
         return self.__dict__ == other.__dict__
 
     def __hash__(self):
         raise TypeError
-    
-class NamespaceDesc(Desc):
-    def __init__(self, name):
-        self.name = name
 
-    def build(self):
-        return CliNamespace(self.name)
-
-class ClassDesc(Desc):
-    def build(self):
+    def get_cliclass(self):
+        if self._cliclass is not None:
+            return self._cliclass
+        
         assert self.Assembly.startswith('mscorlib') # TODO: support external assemblies
         namespace, name = self.FullName.rsplit('.', 1)
 
         # construct OOTYPE and CliClass
-        if self.FullName == 'System.Type':
-            # we need to special case System.Type because it contains
-            # circular dependencies, since its superclasses have got
-            # methods which take System.Type as parameters
-            BASETYPE = None
-        else:
-            load_class_maybe(self.BaseType)
-            BASETYPE = ClassCache[self.BaseType]._INSTANCE
-        TYPE = NativeInstance('[mscorlib]', namespace, name, BASETYPE, {}, {})
-        TYPE._isArray = self.IsArray
-        if self.IsArray:
-            load_class_maybe(self.ElementType)
-            TYPE._ELEMENT = ClassCache[self.ElementType]._INSTANCE
+        # no superclass for now, will add it later
+        TYPE = NativeInstance('[mscorlib]', namespace, name, None, {}, {})
         Class = CliClass(TYPE, {})
-        OOTypeCache[self.OOType] = TYPE
-        ClassCache[self.FullName] = Class
-
-        if BASETYPE is None:
-            load_class_maybe(self.BaseType)
-            BASETYPE = ClassCache[self.BaseType]._INSTANCE
+        self._cliclass = Class
+        # we need to check also for System.Array to prevent a circular recursion
+        if self.FullName in ('System.Object', 'System.Array'):
+            TYPE._set_superclass(ootype.ROOT)
+        else:
+            BASETYPE = get_ootype(self.BaseType)
             TYPE._set_superclass(BASETYPE)
 
-        # render dependencies
-        for name in self.Depend:
-            load_class_maybe(name)
+        TYPE._isArray = self.IsArray
+        if self.IsArray:
+            TYPE._ELEMENT = get_ootype(self.ElementType)
 
         # add both static and instance methods
         static_meths = self.group_methods(self.StaticMethods, _overloaded_static_meth,
@@ -167,17 +165,6 @@
         return res
 
     def get_method_type(self, Meth, args, result):
-        ARGS = [self.get_ootype(arg) for arg in args]
-        RESULT = self.get_ootype(result)
+        ARGS = [get_ootype(arg) for arg in args]
+        RESULT = get_ootype(result)
         return Meth(ARGS, RESULT)
-
-    def get_ootype(self, t):
-        # a bit messy, but works
-        if t.startswith('ootype.'):
-            _, name = t.split('.')
-            return getattr(ootype, name)
-        else:
-            return OOTypeCache[t]
-
-
-loaddesc() ## automatically loads the cached Dependencies

Modified: pypy/dist/pypy/translator/cli/rte.py
==============================================================================
--- pypy/dist/pypy/translator/cli/rte.py	(original)
+++ pypy/dist/pypy/translator/cli/rte.py	Mon Jan 21 12:34:55 2008
@@ -95,10 +95,10 @@
 
     def compile(cls, sources, out):
         # assume that if query.exe need to be recompiled the descriptions cache is invalid        
-        from pypy.translator.cli.query import _descfilename
-        filename = _descfilename(None)
-        if os.path.exists(filename):
-            os.remove(filename)
+        from pypy.translator.cli.query import get_cachedir, mscorlib
+        mscorlib_cache = get_cachedir().join(mscorlib + '.pickle') 
+        if mscorlib_cache.check():
+            mscorlib_cache.remove()
         Target.compile.im_func(cls, sources, out)
     compile = classmethod(compile)
 

Modified: pypy/dist/pypy/translator/cli/src/query.cs
==============================================================================
--- pypy/dist/pypy/translator/cli/src/query.cs	(original)
+++ pypy/dist/pypy/translator/cli/src/query.cs	Mon Jan 21 12:34:55 2008
@@ -1,53 +1,73 @@
 using System;
+using System.IO;
 using System.Reflection;
 using System.Collections.Generic;
 
 public class Query
 {
-    public static Dictionary<Type, bool> PendingTypes = new Dictionary<Type, bool>();
+    private static StreamWriter outfile = null;
 
     public static int Main(string[] argv)
     { 
-        if (argv.Length != 1) {
-            Console.Error.WriteLine("Usage: query full-qualified-name");
+        if (argv.Length != 2) {
+            Console.Error.WriteLine("Usage: query assembly-name output-file");
             return 1;
         }
         
         string name = argv[0];
-        Type t = Type.GetType(name);
-        if (t == null) {
-            Console.Error.WriteLine("Cannot load type {0}", name);
+        string outname = argv[1];
+        Assembly ass;
+        try {
+            ass = Assembly.Load(name);
+        } 
+        catch(System.IO.IOException e) {
+            Console.Error.WriteLine("Cannot load assembly {0}: {1}", name, e.Message);
             return 2;
         }
 
-        if (!t.IsPublic) {
-            Console.Error.WriteLine("Cannot load a non-public type");
-            return 2;
+        try {
+            outfile = new StreamWriter(outname);
         }
-
-        PrintType(t);
+        catch(System.IO.IOException e) {
+            Console.Error.WriteLine("Cannot open file {0}: {1}", outname, e.Message);
+            return 3;
+        }
+        
+        PrintAssembly(ass);
+        outfile.Close();
         return 0;
     }
 
+    private static void PrintAssembly(Assembly ass)
+    {
+        Type[] types = ass.GetTypes();
+        outfile.WriteLine("# This file has been autogenerated by query.exe -- DO NOT EDIT");
+        outfile.WriteLine("from pypy.translator.cli.query import ClassDesc");
+        outfile.WriteLine("types = {}");
+        foreach(Type t in types) {
+            if (IgnoreType(t))
+                continue;
+            PrintType(t);
+            outfile.WriteLine("types['{0}'] = desc", t.FullName);
+            outfile.WriteLine("del desc");
+        }
+    }
+
     private static void PrintType(Type t)
     {
-        Console.WriteLine("Assembly = '{0}'", t.Assembly.FullName);
-        Console.WriteLine("FullName = '{0}'", t.FullName);
-        Console.WriteLine("BaseType = '{0}'", GetBaseType(t));
-        Console.WriteLine("OOType = '{0}'", GetOOType(t));
-        Console.WriteLine("IsArray = {0}", t.IsArray);
-        if (t.IsArray)
-            Console.WriteLine("ElementType = '{0}'", t.GetElementType().FullName);
-        PrintMethods("StaticMethods", t.GetMethods(BindingFlags.Static|BindingFlags.Public|BindingFlags.DeclaredOnly));
-        PrintMethods("Methods", t.GetMethods(BindingFlags.Instance|BindingFlags.Public|BindingFlags.DeclaredOnly));
-        PendingTypes.Remove(t);
-        PrintDepend();
+        outfile.WriteLine("desc = ClassDesc()");
+        outfile.WriteLine("desc.Assembly = '{0}'", t.Assembly.FullName);
+        outfile.WriteLine("desc.FullName = '{0}'", t.FullName);
+        outfile.WriteLine("desc.BaseType = '{0}'", GetBaseType(t));
+        outfile.WriteLine("desc.IsArray = {0}", t.IsArray);
+        PrintMethods("desc.StaticMethods", t.GetMethods(BindingFlags.Static|BindingFlags.Public|BindingFlags.DeclaredOnly));
+        PrintMethods("desc.Methods", t.GetMethods(BindingFlags.Instance|BindingFlags.Public|BindingFlags.DeclaredOnly));
     }
 
     private static string GetBaseType(Type t)
     {
         if (t == typeof(object))
-            return "ROOT"; // special case for System.Object to avoid circular dependencies
+            return "System.Object"; // special case for System.Object to avoid circular dependencies
         else if (t.BaseType == null)
              return "System.Object"; // the only known case is the BaseType of an interface
         else
@@ -77,29 +97,25 @@
         else if (t == typeof(string))
             return "ootype.String";
         else {
-            PendingTypes[t] = true;
-            string name = t.FullName.Replace(".", "_"); // TODO: ensure unicity
-            if (t.IsArray)
-                name = name.Replace("[]", "___array___");
-            return name;
+            return t.FullName;
         }
     }
 
     private static void PrintMethods(string varname, MethodInfo[] methods)
     {
-        Console.WriteLine("{0} = [", varname);
+        outfile.WriteLine("{0} = [", varname);
         // MethodName, [ARGS], RESULT
         foreach(MethodInfo meth in methods) {
             if (IgnoreMethod(meth))
                 continue;
-            Console.Write("    ('{0}', [", meth.Name);
+            outfile.Write("    ('{0}', [", meth.Name);
             foreach(ParameterInfo par in meth.GetParameters()) {
-                Console.Write("'{0}'", GetOOType(par.ParameterType));
-                Console.Write(", ");
+                outfile.Write("'{0}'", GetOOType(par.ParameterType));
+                outfile.Write(", ");
             }
-            Console.WriteLine("], '{0}'),", GetOOType(meth.ReturnType));
+            outfile.WriteLine("], '{0}'),", GetOOType(meth.ReturnType));
         }
-        Console.WriteLine("  ]");
+        outfile.WriteLine("  ]");
     }
 
     private static bool IgnoreMethod(MethodInfo meth)
@@ -124,21 +140,13 @@
     {
         return !t.IsPrimitive 
             && t != typeof(void)
-            &&(t == typeof(System.ValueType) ||
-               t == typeof(System.Array) ||
+            &&(t == typeof(System.Array) ||
+               t.FullName == null ||
                t.FullName.StartsWith("System.Array+InternalArray") ||
-               t.IsValueType ||
+               t.IsNotPublic ||
                t.IsByRef ||
                t.IsPointer ||
                t.IsGenericType ||
                t.IsGenericTypeDefinition);
     }
-
-    private static void PrintDepend()
-    {
-        Console.Write("Depend = [");
-        foreach(Type t in PendingTypes.Keys)
-            Console.Write("'{0}', ", t.FullName);
-        Console.WriteLine("]");
-    }
 }

Modified: pypy/dist/pypy/translator/cli/support.py
==============================================================================
--- pypy/dist/pypy/translator/cli/support.py	(original)
+++ pypy/dist/pypy/translator/cli/support.py	Mon Jan 21 12:34:55 2008
@@ -66,3 +66,14 @@
             f.write('%s: %d\n' % (label, self.counters[key]))
         f.close()
 
+def getattr_ex(target, attr):
+    parts = attr.split('.')
+    for part in parts:
+        target = getattr(target, part)
+    return target
+
+def setattr_ex(target, attr, value):
+    if '.' in attr:
+        namespace, attr = attr.rsplit('.', 1)
+        target = getattr_ex(target, namespace)
+    setattr(target, attr, value)

Modified: pypy/dist/pypy/translator/cli/test/test_dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_dotnet.py	(original)
+++ pypy/dist/pypy/translator/cli/test/test_dotnet.py	Mon Jan 21 12:34:55 2008
@@ -349,6 +349,7 @@
         assert res.startswith("Index is less than 0")
 
     def test_typeof(self):
+        System.Int32 # force Int32 to be loaded
         def fn():
             x = box(42)
             return x.GetType() == typeof(System.Int32)

Modified: pypy/dist/pypy/translator/cli/test/test_query.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_query.py	(original)
+++ pypy/dist/pypy/translator/cli/test/test_query.py	Mon Jan 21 12:34:55 2008
@@ -1,16 +1,21 @@
+import py
 from pypy.translator.cli import query
 from pypy.translator.cli.dotnet import CLR, CliNamespace
 
-def test_load_namespace_simple():
-    query.load_class_or_namespace('System')
-    assert isinstance(CLR.System, CliNamespace)
-    assert CLR.System._name == 'System'
+def setup_module(module):
+    from pypy.translator.cli.query import load_assembly, mscorlib
+    load_assembly(mscorlib)
+
+def test_load_assembly():
+    query.load_assembly(query.mscorlib)
+    assert 'System.Math' in query.Types
+    assert 'System.Collections.ArrayList' in query.Types
 
-def test_load_namespace_complex():
-    query.load_class_or_namespace('System.Collections')
-    assert isinstance(CLR.System, CliNamespace)
-    assert isinstance(CLR.System.Collections, CliNamespace)
+def test_namespaces():
+    assert CLR.System._name == 'System'
     assert CLR.System.Collections._name == 'System.Collections'
+    py.test.raises(AttributeError, getattr, CLR, 'Foo')
+    py.test.raises(AttributeError, getattr, CLR.System, 'Foo')
 
 def test_CLR_getattr():
     System = CLR.System
@@ -25,17 +30,6 @@
     assert 'ToString' in Object._INSTANCE._methods
 
 def test_array():
-    query.load_class_or_namespace('System.Object[]')
-    cls = query.ClassCache['System.Object[]']
+    cls = query.get_cli_class('System.Object[]')
     assert cls._INSTANCE._isArray
     assert cls._INSTANCE._ELEMENT is CLR.System.Object._INSTANCE
-
-def test_savedesc():
-    from pypy.tool.udir import udir
-    CLR.System.Object # force System.Object to be loaded
-    olddesc = query.Descriptions.copy()
-    tmpfile = str(udir.join('descriptions'))
-    query.savedesc(tmpfile)
-    query.Descriptions.clear()
-    query.loaddesc(tmpfile)
-    assert query.Descriptions == olddesc


More information about the pypy-svn mailing list