[pypy-svn] r70007 - in pypy/branch/sepcomp/pypy/annotation: . test

xoraxax at codespeak.net xoraxax at codespeak.net
Wed Dec 9 12:40:34 CET 2009


Author: xoraxax
Date: Wed Dec  9 12:40:33 2009
New Revision: 70007

Modified:
   pypy/branch/sepcomp/pypy/annotation/description.py
   pypy/branch/sepcomp/pypy/annotation/test/test_annrpython.py
Log:
Add _attrs_this_ logic and other descriptor hacks.


Modified: pypy/branch/sepcomp/pypy/annotation/description.py
==============================================================================
--- pypy/branch/sepcomp/pypy/annotation/description.py	(original)
+++ pypy/branch/sepcomp/pypy/annotation/description.py	Wed Dec  9 12:40:33 2009
@@ -114,6 +114,7 @@
 
 class Desc(object):
     __metaclass__ = extendabletype
+    avoid_constantness = False
 
     def __init__(self, bookkeeper, pyobj=None):
         self.bookkeeper = bookkeeper
@@ -360,10 +361,15 @@
                  name=None, basedesc=None, classdict=None,
                  specialize=None):
         super(ClassDesc, self).__init__(bookkeeper, pyobj)
+        self.enable_virtual_access = (getattr(pyobj, '_exported_', False) or getattr(pyobj, '_force_virtual_', False)
+                ) # XXX should only look in dict
 
         if name is None:
             name = pyobj.__module__ + '.' + pyobj.__name__
+        if hasattr(pyobj, '_force_name_'):
+            name = pyobj._force_name_
         self.name = name
+        self.abstract = False
         self.basedesc = basedesc
         if classdict is None:
             classdict = {}    # populated below
@@ -400,6 +406,9 @@
                                             "with _mixin_: %r" % (cls,))
                     base = b1
 
+            if '_abstract_' in cls.__dict__:
+                self.abstract = bool(cls.__dict__['_abstract_'])
+                assert '_exported_' in cls.__dict__
             self.add_sources_for_class(cls)
             if base is not object:
                 self.basedesc = bookkeeper.getdesc(base)
@@ -407,21 +416,27 @@
             if '_settled_' in cls.__dict__:
                 self.settled = bool(cls.__dict__['_settled_'])
 
-            if '__slots__' in cls.__dict__ or '_attrs_' in cls.__dict__:
+            if '__slots__' in cls.__dict__ or '_attrs_' in cls.__dict__ or '_attrs_this_' in cls.__dict__:
                 attrs = {}
-                for decl in ('__slots__', '_attrs_'):
+                def fish_attrs(decl):
                     decl = cls.__dict__.get(decl, [])
                     if isinstance(decl, str):
                         decl = (decl,)
                     decl = dict.fromkeys(decl)
-                    attrs.update(decl)
+                    return decl
+                for decl in ('__slots__', '_attrs_'):
+                    attrs.update(fish_attrs(decl))
+                self.inheriting_enforced_attrs = attrs
                 if self.basedesc is not None:
                     if self.basedesc.all_enforced_attrs is None:
                         raise Exception("%r has slots or _attrs_, "
                                         "but not its base class"
                                         % (pyobj,))
-                    attrs.update(self.basedesc.all_enforced_attrs)
-                self.all_enforced_attrs = attrs
+                    attrs.update(self.basedesc.inheriting_enforced_attrs)
+                self.all_enforced_attrs = fish_attrs("_attrs_this_")
+                self.all_enforced_attrs.update(self.inheriting_enforced_attrs)
+            if self.abstract and not getattr(self, 'all_enforced_attrs', None):
+                self.all_enforced_attrs = ()
 
     def add_source_attribute(self, name, value, mixin=False):
         if isinstance(value, types.FunctionType):
@@ -464,6 +479,8 @@
 
     def add_sources_for_class(self, cls, mixin=False):
         for name, value in cls.__dict__.items():
+            if self.abstract:
+                assert name.startswith("_") or hasattr(value, '_inputtypes_')
             self.add_source_attribute(name, value, mixin)
 
     def getclassdef(self, key):
@@ -682,6 +699,7 @@
     def __init__(self, bookkeeper, funcdesc, originclassdef, 
                  selfclassdef, name, flags={}):
         super(MethodDesc, self).__init__(bookkeeper)
+        self.force_virtual_access = getattr(funcdesc.pyobj, '_force_virtual_', False) and originclassdef.classdesc.enable_virtual_access
         self.funcdesc = funcdesc
         self.originclassdef = originclassdef
         self.selfclassdef = selfclassdef

Modified: pypy/branch/sepcomp/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/branch/sepcomp/pypy/annotation/test/test_annrpython.py	(original)
+++ pypy/branch/sepcomp/pypy/annotation/test/test_annrpython.py	Wed Dec  9 12:40:33 2009
@@ -2482,7 +2482,7 @@
         def fun(x, y):
             return y
         s_nonneg = annmodel.SomeInteger(nonneg=True)
-        fun._annenforceargs_ = policy.Sig(lambda s1,s2: s1, lambda s1,s2: s1)
+        fun._annenforceargs_ = policy.Sig(lambda s1, s2: s1, lambda s1, s2: s1)
         # means: the 2nd argument's annotation becomes the 1st argument's
         #        input annotation
 
@@ -2592,6 +2592,31 @@
                 from pypy.annotation.classdef import NoSuchAttrError
                 py.test.raises(NoSuchAttrError, a.build_types, fun, [int])
 
+    def test_enforced_attrs_this(self):
+        class Base(object):
+            _attrs_this_ = 'x'
+            def m(self):
+                return 65
+        class A(Base): pass
+        for attrname, works1, works2 in [('x', True, True),
+                                         ('y', False, True)]:
+            def fun1(n):
+                o = Base()
+                setattr(o, attrname, 12)
+                return o.m()
+            def fun2(n):
+                o = A()
+                setattr(o, attrname, 12)
+                return o.m()
+            for works, fun in ((works1, fun1), (works2, fun2)):
+                a = self.RPythonAnnotator()
+                if works:
+                    a.build_types(fun, [int])
+                else:
+                    from pypy.annotation.classdef import NoSuchAttrError
+                    py.test.raises(NoSuchAttrError, a.build_types, fun, [int])
+
+
     def test_attrs_enforce_attrs(self):
         class Superbase(object):
             _attrs_ = 'x'



More information about the Pypy-commit mailing list