[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