Commit 106a8dca authored by Tres Seaver's avatar Tres Seaver

Merge pull request #8 from NextThought/jython

In WeakSet, use the `valuerefs` method from Python 2.5 instead of accessing the internal `data` implementation detail.
parents bf6e186c b42a65c5
......@@ -4,6 +4,9 @@ Changes
1.4.4 (unreleased)
------------------
- Use the standard ``valuerefs()`` method rather than relying on
implementation details of ``WeakValueDictionary`` in ``WeakSet``.
- Add support for PyPy3.
- Require 100% branch coverage (in addition to 100% statement coverage).
......
[tox]
envlist =
# Jython support pending 2.7 support, due 2012-07-15 or so. See:
# http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html
# py26,py27,py32,pypy,jython,coverage
# Jython 2.7rc2+ does work, but unfortunately has an issue running
# with Tox 1.9.2 (see https://github.com/pypa/virtualenv/pull/746)
envlist =
py26,py27,pypy,py32,py33,py34,pypy3,coverage,docs
[testenv]
commands =
commands =
python setup.py test -q
deps = transaction
[testenv:jython]
commands =
jython setup.py test -q
[testenv:coverage]
basepython =
python2.6
commands =
commands =
nosetests --with-xunit --with-xcoverage
deps =
nose
......@@ -27,7 +22,7 @@ deps =
[testenv:docs]
basepython =
python2.6
commands =
commands =
sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest
deps =
......
......@@ -2,6 +2,7 @@ import sys
import types
PY3 = sys.version_info[0] == 3
JYTHON = sys.platform.startswith('java')
if PY3: # pragma: no cover
string_types = str,
......@@ -79,12 +80,11 @@ if PY3: #pragma NO COVER
from threading import _get_ident as get_thread_ident
else:
from thread import get_ident as get_thread_ident
if PY3:
def func_name(func): #pragma NO COVER
return func.__name__
else:
def func_name(func): #pragma NO COVER
return func.func_name
......@@ -12,7 +12,7 @@
#
##############################################################################
import unittest
from transaction._compat import JYTHON
class WeakSetTests(unittest.TestCase):
def test_contains(self):
......@@ -35,7 +35,9 @@ class WeakSetTests(unittest.TestCase):
self.assertEqual(len(w), 2)
del d1
gc.collect()
self.assertEqual(len(w), 1)
if not JYTHON:
# The Jython GC is non deterministic
self.assertEqual(len(w), 1)
def test_remove(self):
from transaction.weakset import WeakSet
......@@ -100,17 +102,17 @@ class WeakSetTests(unittest.TestCase):
gc.collect()
return result
w.as_weakref_list = _as_weakref_list
def poker(x):
x.poked = 1
w.map(poker)
for thing in dummy, dummy2:
self.assertEqual(thing.poked, 1)
class Dummy:
pass
def test_suite():
return unittest.makeSuite(WeakSetTests)
......@@ -13,6 +13,7 @@
############################################################################
import weakref
from ._compat import PY3
# A simple implementation of weak sets, supplying just enough of Python's
# sets.Set interface for our needs.
......@@ -62,7 +63,6 @@ class WeakSet(object):
# underlying dict may change size during iteration, due to gc or
# activity from other threads). as_weakef_list() is safe.
#
# Something like this should really be a method of Python's weak dicts.
# If we invoke self.data.values() instead, we get back a list of live
# objects instead of weakrefs. If gc occurs while this list is alive,
# all the objects move to an older generation (because they're strongly
......@@ -75,9 +75,12 @@ class WeakSet(object):
# elements are actually trash. By returning a list of weakrefs instead,
# we avoid that, although the decision to use weakrefs is now very
# visible to our clients.
def as_weakref_list(self):
# We're cheating by breaking into the internals of Python's
# WeakValueDictionary here (accessing its .data attribute).
# Python 3: be sure to freeze the list, to avoid RuntimeError:
if PY3: #pragma: no cover (coverage tests run under 2.7)
# Python 3: be sure to freeze the iterator, to avoid RuntimeError:
# dictionary changed size during iteration.
return list(self.data.data.values())
def as_weakref_list(self):
return list(self.data.valuerefs())
else:
# On Python2 we already get a list, no need to copy
def as_weakref_list(self):
return self.data.valuerefs()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment