]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
removed circular loop in creating new list elements, fixes a common refresh() condition
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 25 Mar 2006 21:44:42 +0000 (21:44 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 25 Mar 2006 21:44:42 +0000 (21:44 +0000)
added None check in PropertyLoader many-to-one private deletion traversal, fixes byroot_tree (add a unit test for that)

lib/sqlalchemy/attributes.py
lib/sqlalchemy/mapping/properties.py
test/mapper.py

index bd5868baf4870547d691586286e70dfd81ea04f7..997b2c8f82ad95ae1abd7869542f7a03c311e303 100644 (file)
@@ -144,6 +144,8 @@ class ListElement(util.HistoryArraySet):
         # list that might be set on the object already
         try:
             list_ = obj.__dict__[key]
+            if list_ is data:
+                raise InvalidArgumentError("Creating a list element passing the object's list as an argument")
             if data is not None:
                 for d in data:
                     list_.append(d)
@@ -435,8 +437,7 @@ class AttributeManager(object):
         elif not uselist:
             return PropHistory(obj, key, **kwargs)
         else:
-            list_ = obj.__dict__.get(key, None)
-            return self.create_list(obj, key, list_, **kwargs)
+            return self.create_list(obj, key, None, **kwargs)
         
     def register_attribute(self, class_, key, uselist, callable_=None, **kwargs):
         """registers an attribute's behavior at the class level.  This attribute
index 7f5489de6091b5ffce043537aee3fdf0f1d316f1..10d6472f4c88cc30be36d64bab445d4367becf9e 100644 (file)
@@ -449,6 +449,8 @@ class PropertyLoader(MapperProperty):
                 for obj in deplist:
                     childlist = getlist(obj, False)
                     for child in childlist.deleted_items() + childlist.unchanged_items():
+                        if child is None:
+                            continue
                         uowcommit.register_object(child, isdelete=True)
             elif self.post_update:
                 # post_update means we have to update our row to not reference the child object
@@ -467,6 +469,8 @@ class PropertyLoader(MapperProperty):
                 for obj in deplist:
                     childlist = getlist(obj, False)
                     for child in childlist.deleted_items() + childlist.unchanged_items():
+                        if child is None:
+                            continue
                         uowcommit.register_object(child, isdelete=True)
             else:
                 for obj in deplist:
index 26668df1af39dbf36c0cbe99f55f0e4e0e9ee7b5..4ce698852d2ae4f5c4a644d3fbe37b486a45b2d5 100644 (file)
@@ -118,6 +118,27 @@ class MapperTest(MapperSuperTest):
         self.assert_(a not in u.addresses)
         # not dirty anymore
         self.assert_(u not in objectstore.get_session().uow.dirty)
+    
+    def testrefresh2(self):
+        assign_mapper(Address, addresses)
+
+        assign_mapper(User, users, properties = dict(addresses=relation(Address.mapper,private=True,lazy=False)) )
+
+        u=User()
+        u.user_name='Justin'
+        a = Address()
+        a.address_id=17  # to work around the hardcoded IDs in this test suite....
+        u.addresses.append(a)
+        objectstore.commit()
+        objectstore.clear()
+        u = User.mapper.selectfirst()
+        print u.user_name
+
+        #ok so far
+        u.expire()        #hangs when
+        print u.user_name #this line runs
+
+        u.refresh() #hangs
         
     def testmagic(self):
         m = mapper(User, users, properties = {