[pypy-commit] pypy cffi-1.0: new feature in TypeDefs: you can use ClassAttr(f) to make a class

arigo noreply at buildbot.pypy.org
Fri May 8 11:09:05 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r77200:8d4b19bf8439
Date: 2015-05-08 11:07 +0200
http://bitbucket.org/pypy/pypy/changeset/8d4b19bf8439/

Log:	new feature in TypeDefs: you can use ClassAttr(f) to make a class
	attribute whose value is lazily initialized by calling 'f(space)'.

diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py
--- a/pypy/interpreter/test/test_typedef.py
+++ b/pypy/interpreter/test/test_typedef.py
@@ -341,6 +341,28 @@
         assert space.is_true(space.ne(w_a, w_b))
         assert not space.is_true(space.ne(w_b, w_c))
 
+    def test_class_attr(self):
+        class W_SomeType(W_Root):
+            pass
+
+        seen = []
+        def make_me(space):
+            seen.append(1)
+            return space.wrap("foobar")
+
+        W_SomeType.typedef = typedef.TypeDef(
+            'some_type',
+            abc = typedef.ClassAttr(make_me)
+            )
+        assert seen == []
+        self.space.appexec([W_SomeType()], """(x):
+            assert type(x).abc == "foobar"
+            assert x.abc == "foobar"
+            assert type(x).abc == "foobar"
+        """)
+        assert seen == [1]
+
+
 class AppTestTypeDef:
 
     def setup_class(cls):
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -594,6 +594,19 @@
 
 # ____________________________________________________________
 
+class ClassAttr(W_Root):
+    """For class-level attributes that need to be initialized
+    with some code.  This code is provided as a callback function
+    invoked with the space.
+    """
+    def __init__(self, function):
+        self.function = function
+
+    def __spacebind__(self, space):
+        return self.function(space)
+
+# ____________________________________________________________
+
 def generic_new_descr(W_Type):
     def descr_new(space, w_subtype, __args__):
         self = space.allocate_instance(W_Type, w_subtype)


More information about the pypy-commit mailing list