Author: Armin Rigo <ar...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit