[pypy-commit] pypy stmgc-c7: Change the argument to threadlocalproperty() from a default value

arigo noreply at buildbot.pypy.org
Mon Mar 16 10:03:15 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r76394:87258f56326e
Date: 2015-03-16 10:02 +0100
http://bitbucket.org/pypy/pypy/changeset/87258f56326e/

Log:	Change the argument to threadlocalproperty() from a default value to
	a default value factory (like "defaultdict").

diff --git a/lib_pypy/pypy_test/test_transaction.py b/lib_pypy/pypy_test/test_transaction.py
--- a/lib_pypy/pypy_test/test_transaction.py
+++ b/lib_pypy/pypy_test/test_transaction.py
@@ -192,6 +192,39 @@
     assert d.setdefault(key2) is None
     assert d[key2] is None
 
+def test_stmdict():
+    d = transaction.stmdict()
+    d["abc"] = "def"
+    assert list(d.iterkeys()) == ["abc"]
+
+def test_stmset():
+    d = transaction.stmset()
+    d.add("abc")
+    assert list(d) == ["abc"]
+
+def test_time_clock():
+    assert isinstance(transaction.time(), float)
+    assert isinstance(transaction.clock(), float)
+
+def test_threadlocalproperty():
+    class Foo(object):
+        x = transaction.threadlocalproperty()
+        y = transaction.threadlocalproperty(dict)
+    foo = Foo()
+    py.test.raises(AttributeError, "foo.x")
+    d = foo.y
+    assert d == {}
+    assert d is foo.y
+    foo.y['bar'] = 'baz'
+    foo.x = 42
+    foo.y = 43
+    assert foo.x == 42
+    assert foo.y == 43
+    del foo.x
+    del foo.y
+    py.test.raises(AttributeError, "foo.x")
+    assert foo.y == {}
+
 
 def run_tests():
     for name in sorted(globals().keys()):
diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py
--- a/lib_pypy/transaction.py
+++ b/lib_pypy/transaction.py
@@ -294,9 +294,9 @@
 
 
 class threadlocalproperty(object):
-    def __init__(self, *default):
-        self.tl_default = default
-        self.tl_name = intern(str(id(self)))
+    def __init__(self, default_factory=None):
+        self.tl_default_factory = default_factory
+        self.tl_name = intern('tlprop.%d' % id(self))
 
     def tl_get(self, obj):
         try:
@@ -308,7 +308,14 @@
     def __get__(self, obj, cls=None):
         if obj is None:
             return self
-        return getattr(self.tl_get(obj), self.tl_name, *self.tl_default)
+        try:
+            return getattr(self.tl_get(obj), self.tl_name)
+        except AttributeError:
+            if self.tl_default_factory is None:
+                raise
+            result = self.tl_default_factory()
+            setattr(self.tl_get(obj), self.tl_name, result)
+            return result
 
     def __set__(self, obj, value):
         setattr(self.tl_get(obj), self.tl_name, value)


More information about the pypy-commit mailing list