From 4b1ca23027493d8d1b7ea48d4585699b0d126d16 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 18 Aug 2013 15:34:23 -0400 Subject: [PATCH] Fixed a potential issue in an ordered sequence implementation used by the ORM to iterate mapper hierarchies; under the Jython interpreter this implementation wasn't ordered, even though cPython and Pypy maintained ordering. Also in 0.8.3. [ticket:2794] Conflicts: doc/build/changelog/changelog_09.rst lib/sqlalchemy/util/_collections.py --- doc/build/changelog/changelog_08.rst | 9 +++++++++ lib/sqlalchemy/orm/util.py | 1 + lib/sqlalchemy/util/_collections.py | 17 +++++++++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index bbd2741c80..d67c088eb1 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -6,6 +6,15 @@ .. changelog:: :version: 0.8.3 + .. change:: + :tags: bug, orm + :tickets: 2794 + + Fixed a potential issue in an ordered sequence implementation used + by the ORM to iterate mapper hierarchies; under the Jython interpreter + this implementation wasn't ordered, even though cPython and Pypy + maintained ordering. + .. change:: :tags: bug, sql :tickets: 2801 diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index e2b3ddd01c..99349c0197 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -1292,3 +1292,4 @@ def randomize_unitofwork(): from sqlalchemy.testing.util import RandomSet topological.set = unitofwork.set = session.set = mapper.set = \ dependency.set = RandomSet + diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index 8e61275e75..4da13b3fe0 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -618,18 +618,27 @@ class IdentitySet(object): class WeakSequence(object): def __init__(self, elements): - self._storage = weakref.WeakValueDictionary( - (idx, element) for idx, element in enumerate(elements) - ) + self._storage = [ + weakref.ref(element) for element in elements + ] + + def _remove(self, ref): + self._storage.remove(ref) def __iter__(self): +<<<<<<< HEAD return self._storage.itervalues() +======= + return (obj for obj in (ref() for ref in self._storage) if obj is not None) +>>>>>>> 676876f... Fixed a potential issue in an ordered sequence implementation used def __getitem__(self, index): try: - return self._storage[index] + obj = self._storage[index] except KeyError: raise IndexError("Index %s out of range" % index) + else: + return obj() class OrderedIdentitySet(IdentitySet): -- 2.47.3