[py-svn] r33506 - in py/dist/py/apigen: rest tracer tracer/testing

fijal at codespeak.net fijal at codespeak.net
Fri Oct 20 18:43:01 CEST 2006


Author: fijal
Date: Fri Oct 20 18:41:30 2006
New Revision: 33506

Added:
   py/dist/py/apigen/tracer/model.py   (contents, props changed)
   py/dist/py/apigen/tracer/testing/test_model.py   (contents, props changed)
Modified:
   py/dist/py/apigen/rest/genrest.py
   py/dist/py/apigen/tracer/description.py
   py/dist/py/apigen/tracer/docstorage.py
   py/dist/py/apigen/tracer/testing/test_docgen.py
   py/dist/py/apigen/tracer/testing/test_magic.py
   py/dist/py/apigen/tracer/tracer.py
Log:
Remove pypy dependency, added some stuff. Right now I would go for more objects to support.


Modified: py/dist/py/apigen/rest/genrest.py
==============================================================================
--- py/dist/py/apigen/rest/genrest.py	(original)
+++ py/dist/py/apigen/rest/genrest.py	Fri Oct 20 18:41:30 2006
@@ -197,8 +197,8 @@
         # XXX: we just do "knowntype" here, but we should
         # present some more informative way, maybe even provide a link
         # for the type declaration (if this is known)
-        arg_str = "(%s)" % (",".join([str(i.knowntype) for i in args]))
-        ret_str = str(retval.knowntype)
+        arg_str = "(%s)" % (",".join([str(i) for i in args]))
+        ret_str = str(retval)
         arg_quote = Paragraph("Function type:", Quote(arg_str), '->',
                               Quote(ret_str))
         lst.append(arg_quote)

Modified: py/dist/py/apigen/tracer/description.py
==============================================================================
--- py/dist/py/apigen/tracer/description.py	(original)
+++ py/dist/py/apigen/tracer/description.py	Fri Oct 20 18:41:30 2006
@@ -1,8 +1,10 @@
 
-try:
-    from pypy.annotation import model
-except ImportError:
-    pass
+#try:
+#    from pypy.annotation import model
+#except ImportError:
+#    pass
+
+from py.__.apigen.tracer import model
 
 import types
 
@@ -117,7 +119,10 @@
         # other variables encountered here
     
     def getcode(self):
-        return self.pyobj.__init__.im_func.func_code
+        try:
+            return self.pyobj.__init__.im_func.func_code
+        except AttributeError:
+            return self.pyobj.__name__
     code = property(getcode)
     
     def consider_call(self, inputcells):

Modified: py/dist/py/apigen/tracer/docstorage.py
==============================================================================
--- py/dist/py/apigen/tracer/docstorage.py	(original)
+++ py/dist/py/apigen/tracer/docstorage.py	Fri Oct 20 18:41:30 2006
@@ -7,23 +7,16 @@
 import sys
 import types
 
-from py.__.apigen.tracer.description import FunctionDesc, ClassDesc, \
-                                            MethodDesc, Desc
+from py.__.apigen.tracer.description import FunctionDesc, ClassDesc, MethodDesc, \
+    Desc
 
-try:
-    from pypy.annotation.policy import AnnotatorPolicy
-    from pypy.annotation.bookkeeper import Bookkeeper
-except ImportError, i:
-    py.test.skip("No PyPy %s" % i)
-
-class DummyAnnotator(object):
-    policy = AnnotatorPolicy()
+from py.__.apigen.tracer.model import guess_type
 
 class DocStorage(object):
     """ Class storing info about API
     """
-    def __init__(self):
-        self.bookkeeper = Bookkeeper(DummyAnnotator())
+    #def __init__(self):
+        #self.bookkeeper = Bookkeeper(DummyAnnotator())
         #self.call_stack = []
         #self.frames = []
     
@@ -37,10 +30,10 @@
     def generalize_args(self, desc, frame):
         args = [arg for key, arg in frame.getargs()]
         #self.call_stack.append((desc, args))
-        desc.consider_call([self.bookkeeper.immutablevalue(arg) for arg in args])
+        desc.consider_call([guess_type(arg) for arg in args])
     
     def generalize_retval(self, desc, arg):
-        desc.consider_return(self.bookkeeper.immutablevalue(arg))
+        desc.consider_return(guess_type(arg))
 
     def consider_return(self, frame, arg):
         assert isinstance(frame, py.code.Frame)
@@ -64,7 +57,8 @@
         self.descs = {}
         for key, val in _dict.iteritems():
             to_key, to_val = self.make_desc(key, val)
-            self.descs[to_key] = to_val
+            if to_key:
+                self.descs[to_key] = to_val
         self.make_cache()
         return self
     
@@ -86,7 +80,8 @@
             desc = ClassDesc(key, value, **kwargs)
             for name in dir(value):
                 field = getattr(value, name)
-                if isinstance(field, types.MethodType):
+                if isinstance(field, types.MethodType) and \
+                    isinstance(field.im_func, types.FunctionType):
                     real_name = key + '.' + name
                     md = MethodDesc(real_name, field)
                     self.descs[real_name] = md
@@ -101,7 +96,15 @@
 
     def from_pkg(self, module):
         self.module = module
-        self.from_dict(module.__package__.__dict__)
+        keys = module.__package__.exportdefs.keys()
+        d = {}
+        for key in keys:
+            chain = key.split('.')
+            base = module
+            for elem in chain:
+                base = getattr(base, elem)
+            d[key] = base
+        self.from_dict(d)
         return self
     
     def from_module(self, func):

Added: py/dist/py/apigen/tracer/model.py
==============================================================================
--- (empty file)
+++ py/dist/py/apigen/tracer/model.py	Fri Oct 20 18:41:30 2006
@@ -0,0 +1,239 @@
+
+""" model - type system model for apigen
+"""
+
+# we implement all the types which are in the types.*, naming
+# scheme after pypy's
+
+import types
+
+# __extend__ and pairtype?
+class SomeObject(object):
+    typedef = types.ObjectType
+    
+    def __repr__(self):
+        return str(self.typedef)[7:-2]
+    
+    def unionof(self, other):
+        if isinstance(other, SomeImpossibleValue):
+            return self
+        if self.gettypedef() is other.gettypedef():
+            return self
+        return SomeUnion([self, other])
+    
+    def gettypedef(self):
+        return self.typedef
+
+class SomeUnion(object):
+    # empty typedef
+    def __init__(self, possibilities):
+        self.possibilities = possibilities
+    
+    def unionof(self, other):
+        return SomeUnion(self.possibilities + [other])
+    
+    def __repr__(self):
+        return "AnyOf(%s)" % ",".join([str(i) for i in self.possibilities])
+    
+    def gettypedef(self):
+        return (None, None)
+
+class SomeBoolean(SomeObject):
+    typedef = types.BooleanType
+
+class SomeBuffer(SomeObject):
+    typedef = types.BufferType
+
+class SomeBuiltinFunction(SomeObject):
+    typedef = types.BuiltinFunctionType
+
+class SomeBuiltinMethod(SomeObject):
+    typedef = types.BuiltinMethodType
+
+class SomeClass(SomeObject):
+    typedef = types.ClassType
+
+class SomeCode(SomeObject):
+    typedef = types.CodeType
+
+class SomeComplex(SomeObject):
+    typedef = types.ComplexType
+
+class SomeDictProxy(SomeObject):
+    typedef = types.DictProxyType
+
+class SomeDict(SomeObject):
+    typedef = types.DictType
+
+class SomeBoolean(SomeObject):
+    typedef = types.BooleanType
+
+class SomeDictionary(SomeObject):
+    typedef = types.DictionaryType
+
+class SomeEllipsis(SomeObject):
+    typedef = types.EllipsisType
+
+class SomeFile(SomeObject):
+    typedef = types.FileType
+
+class SomeFloat(SomeObject):
+    typedef = types.FloatType
+
+class SomeFrame(SomeObject):
+    typedef = types.FrameType
+
+class SomeFunction(SomeObject):
+    typedef = types.FunctionType
+
+class SomeGenerator(SomeObject):
+    typedef = types.GeneratorType
+
+class SomeInstance(SomeObject):
+    typedef = types.InstanceType
+
+class SomeInt(SomeObject):
+    typedef = types.IntType
+
+class SomeLambda(SomeObject):
+    typedef = types.LambdaType
+
+class SomeList(SomeObject):
+    typedef = types.ListType
+
+class SomeLong(SomeObject):
+    typedef = types.LongType
+
+class SomeMethod(SomeObject):
+    typedef = types.MethodType
+
+class SomeModule(SomeObject):
+    typedef = types.ModuleType
+
+class SomeNone(SomeObject):
+    typedef = types.NoneType
+
+class SomeNotImplemented(SomeObject):
+    typedef = types.NotImplementedType
+
+class SomeObject(SomeObject):
+    typedef = types.ObjectType
+
+class SomeSlice(SomeObject):
+    typedef = types.SliceType
+
+class SomeString(SomeObject):
+    typedef = types.StringType
+
+class SomeTraceback(SomeObject):
+    typedef = types.TracebackType
+
+class SomeTuple(SomeObject):
+    typedef = types.TupleType
+
+class SomeType(SomeObject):
+    typedef = types.TypeType
+
+class SomeUnboundMethod(SomeObject):
+    typedef = types.UnboundMethodType
+
+class SomeUnicode(SomeObject):
+    typedef = types.UnicodeType
+
+class SomeXRange(SomeObject):
+    typedef = types.XRangeType
+
+class SomeImpossibleValue(SomeObject):
+    def unionof(self, other):
+        return other
+    
+    def __repr__(self):
+        return "<UNKNOWN>"
+
+s_ImpossibleValue = SomeImpossibleValue()
+s_None = SomeNone()
+s_Ellipsis = SomeEllipsis()
+
+def guess_type(x):
+    # this is mostly copy of immutablevalue
+    if hasattr(x, 'im_self') and x.im_self is None:
+        x = x.im_func
+        assert not hasattr(x, 'im_self')
+    tp = type(x)
+    if tp is bool:
+        result = SomeBool()
+    elif tp is int:
+        result = SomeInt()
+    elif issubclass(tp, str):
+        result = SomeString()
+    elif tp is unicode:
+        result = SomeUnicode()
+    elif tp is tuple:
+        result = SomeTuple()
+        #result = SomeTuple(items = [self.immutablevalue(e, need_const) for e in x])
+    elif tp is float:
+        result = SomeFloat()
+    elif tp is list:
+        #else:
+        #    listdef = ListDef(self, s_ImpossibleValue)
+        #    for e in x:
+        #        listdef.generalize(self.annotation_from_example(e))
+        result = SomeList()
+    elif tp is dict:
+##        dictdef = DictDef(self, 
+##        s_ImpossibleValue,
+##        s_ImpossibleValue,
+##        is_r_dict = tp is r_dict)
+##        if tp is r_dict:
+##            s_eqfn = self.immutablevalue(x.key_eq)
+##            s_hashfn = self.immutablevalue(x.key_hash)
+##            dictdef.dictkey.update_rdict_annotations(s_eqfn,
+##                s_hashfn)
+##        for ek, ev in x.iteritems():
+##            dictdef.generalize_key(self.annotation_from_example(ek))
+##            dictdef.generalize_value(self.annotation_from_example(ev))
+        result = SomeDict()
+    elif callable(x):
+        #if hasattr(x, '__self__') and x.__self__ is not None:
+        #    # for cases like 'l.append' where 'l' is a global constant list
+        #    s_self = self.immutablevalue(x.__self__, need_const)
+        #    result = s_self.find_method(x.__name__)
+        #    if result is None:
+        #        result = SomeObject()
+        #elif hasattr(x, 'im_self') and hasattr(x, 'im_func'):
+        #    # on top of PyPy, for cases like 'l.append' where 'l' is a
+        #    # global constant list, the find_method() returns non-None
+        #    s_self = self.immutablevalue(x.im_self, need_const)
+        #    result = s_self.find_method(x.im_func.__name__)
+        #else:
+        #    result = None
+        #if result is None:
+        #    if (self.annotator.policy.allow_someobjects
+        #        and getattr(x, '__module__', None) == '__builtin__'
+        #        # XXX note that the print support functions are __builtin__
+        #        and tp not in (types.FunctionType, types.MethodType)):
+        ##        result = SomeObject()
+        #        result.knowntype = tp # at least for types this needs to be correct
+        #    else:
+        #        result = SomePBC([self.getdesc(x)])
+        if hasattr(x, 'im_func'):
+            result = SomeMethod()
+        else:
+            result = SomeFunction()
+    elif hasattr(x, '__class__'):
+        if x.__class__ is type:
+            result = SomeClass()
+        else:
+            result = SomeInstance()
+    elif tp is types.ClassType:
+        result = SomeClass()
+    elif x is None:
+        return s_None
+    else:
+        result = SomeObject()
+    # XXX here we might want to consider stuff like
+    # buffer, slice, etc. etc. Let's leave it for now
+    return result
+
+def unionof(first, other):
+    return first.unionof(other)

Modified: py/dist/py/apigen/tracer/testing/test_docgen.py
==============================================================================
--- py/dist/py/apigen/tracer/testing/test_docgen.py	(original)
+++ py/dist/py/apigen/tracer/testing/test_docgen.py	Fri Oct 20 18:41:30 2006
@@ -5,14 +5,14 @@
 import py
 import sys
 
-try:
-    from py.__.apigen.tracer.docstorage import DocStorage
-    from py.__.apigen.tracer.tracer import Tracer
-    from py.__.apigen.tracer.testing.runtest import cut_pyc
-    from py.__.apigen.tracer.description import FunctionDesc
-    from pypy.annotation import model
-except ImportError, s:
-    py.test.skip("Cannot import: %s" % str(s))
+#try:
+from py.__.apigen.tracer.tracer import DocStorage, Tracer
+from py.__.apigen.tracer.testing.runtest import cut_pyc
+from py.__.apigen.tracer.description import FunctionDesc
+from py.__.apigen.tracer import model
+#    from pypy.annotation import model
+#except ImportError, s:
+#    py.test.skip("Cannot import: %s" % str(s))
 
 #def setup_module(mod):
 #    data_path = py.path.local(mod.__file__).dirpath().join("data")
@@ -34,10 +34,10 @@
     desc = ds.descs['fun']
     inputcells = desc.inputcells
     assert len(inputcells) == 3
-    assert isinstance(inputcells[0], model.SomeFloat)
+    assert isinstance(inputcells[0], model.SomeUnion)
     assert isinstance(inputcells[1], model.SomeTuple)
-    assert isinstance(inputcells[2], model.SomeObject)
-    assert isinstance(desc.retval, model.SomeChar)
+    assert isinstance(inputcells[2], model.SomeUnion)
+    assert isinstance(desc.retval, model.SomeString)
     cs = sorted(desc.call_sites.keys())
     assert len(cs) == 2
     f_name = cut_pyc(__file__)
@@ -74,7 +74,8 @@
     inputcells = desc.fields['__init__'].inputcells
     assert len(inputcells) == 2
     assert isinstance(inputcells[0], model.SomeInstance)
-    assert inputcells[0].classdef.classdesc.pyobj is SomeClass
+    #assert inputcells[0].classdef.classdesc.pyobj is SomeClass
+    # XXX: should work
     assert isinstance(inputcells[1], model.SomeString)
     f_name = __file__
     if f_name.endswith('.pyc'):
@@ -88,11 +89,12 @@
     inputcells = desc.fields['exposed_method'].inputcells
     assert len(inputcells) == 4
     assert isinstance(inputcells[0], model.SomeInstance)
-    assert inputcells[0].classdef.classdesc.pyobj is SomeClass
-    assert isinstance(inputcells[1], model.SomeInteger)
+    #assert inputcells[0].classdef.classdesc.pyobj is SomeClass
+    # XXX should work
+    assert isinstance(inputcells[1], model.SomeInt)
     assert isinstance(inputcells[2], model.SomeFloat)
     assert isinstance(inputcells[3], model.SomeList)
-    assert isinstance(desc.fields['exposed_method'].retval, model.SomeChar)
+    assert isinstance(desc.fields['exposed_method'].retval, model.SomeString)
 
 def other_fun():
     pass

Modified: py/dist/py/apigen/tracer/testing/test_magic.py
==============================================================================
--- py/dist/py/apigen/tracer/testing/test_magic.py	(original)
+++ py/dist/py/apigen/tracer/testing/test_magic.py	Fri Oct 20 18:41:30 2006
@@ -5,7 +5,7 @@
 from py.__.apigen.tracer.magic import trace, get_storage, stack_copier, \
     DocStorageKeeper
 from py.__.apigen.tracer.docstorage import DocStorage
-from pypy.annotation import model
+from py.__.apigen.tracer import model
 
 #def setup_function(f):
 #    DocStorageKeeper.set_storage(DocStorage().from_dict({}))
@@ -22,10 +22,10 @@
     assert len(ds.descs.keys()) == 2
     desc = ds.descs['fun']
     inputcells = desc.inputcells
-    assert isinstance(inputcells[0], model.SomeInteger)
-    assert isinstance(inputcells[1], model.SomeInteger)
-    assert isinstance(inputcells[2], model.SomeInteger)
-    assert isinstance(desc.retval, model.SomeChar)
+    assert isinstance(inputcells[0], model.SomeInt)
+    assert isinstance(inputcells[1], model.SomeInt)
+    assert isinstance(inputcells[2], model.SomeInt)
+    assert isinstance(desc.retval, model.SomeString)
 
 def g(x):
     return f(x)

Added: py/dist/py/apigen/tracer/testing/test_model.py
==============================================================================
--- (empty file)
+++ py/dist/py/apigen/tracer/testing/test_model.py	Fri Oct 20 18:41:30 2006
@@ -0,0 +1,16 @@
+
+""" test_model - our (very simple) type system
+model tests
+"""
+
+from py.__.test.tracer import model
+
+import types
+import py
+
+def test_basic():
+    py.test.skip("Checks nothing")
+    for i in dir(types):
+        if i.endswith('Type'):
+            attr = getattr(types, i)
+            assert model.typedefs[attr].typedef is attr

Modified: py/dist/py/apigen/tracer/tracer.py
==============================================================================
--- py/dist/py/apigen/tracer/tracer.py	(original)
+++ py/dist/py/apigen/tracer/tracer.py	Fri Oct 20 18:41:30 2006
@@ -6,9 +6,8 @@
 import sys
 import types
 
-# We have to steal as much as possible from union of types
-# from pypy's code.
-# BLAH BLAH BLAH
+from py.__.apigen.tracer.description import FunctionDesc
+from py.__.apigen.tracer.docstorage import DocStorage
 
 class UnionError(Exception):
     pass
@@ -23,15 +22,14 @@
     
     def _tracer(self, frame, event, arg):
         
-        # perform actual tracing
+        # perform actuall tracing
         frame = py.code.Frame(frame)
         if event == 'call':
             assert arg is None
-            self.docstorage.consider_call(frame,
-                                          py.code.Frame(sys._getframe(2)))
+            self.docstorage.consider_call(frame, py.code.Frame(sys._getframe(2)))
         elif event == 'return':
             self.docstorage.consider_return(frame, arg)
-        
+            
         return self._tracer
     
     def start_tracing(self):



More information about the pytest-commit mailing list