On Sun, 2008-09-28 at 00:51 +0400, Oleg Broytmann wrote:
> On Sat, Sep 27, 2008 at 01:51:45PM -0400, David Turner wrote:
> > Depending on how attributes are set on child classes, rowupdatesignal
> > fires either just on the base class, or on both the base and the child.
> > This is inconsistent.
> 
>    I suspect a subtle bug in SLObject._SO_setValue().

I have written a patch for this.  Since I noticed the change in the
inheritance system, that's where the test for it ended up going.  If
this is OK with you, I'll commit it.
Index: inheritance/__init__.py
===================================================================
--- inheritance/__init__.py	(revision 3601)
+++ inheritance/__init__.py	(working copy)
@@ -3,6 +3,7 @@
 from sqlobject.col import StringCol, ForeignKey
 from sqlobject.main import sqlmeta, SQLObject, SelectResults, \
    makeProperties, unmakeProperties, getterName, setterName
+from sqlobject import events
 import iteration
 
 try:
@@ -110,9 +111,16 @@
                 setattr(soClass, getterName(cname), eval(
                     'lambda self: self._parent.%s' % cname))
                 if not col.immutable:
-                    setattr(soClass, setterName(cname), eval(
-                        'lambda self, val: setattr(self._parent, %s, val)'
-                        % repr(cname)))
+                    def make_setfunc(cname):
+                        def setfunc(self, val):
+                            if not self.sqlmeta._creating and not getattr(self.sqlmeta, "row_update_sig_suppress", False):
+                                self.sqlmeta.send(events.RowUpdateSignal, self, {cname : val})
+                                
+                            result = setattr(self._parent, cname, val)
+                        return setfunc
+
+                    setfunc = make_setfunc(cname)
+                    setattr(soClass, setterName(cname), setfunc)
             if childUpdate:
                 makeProperties(soClass)
                 return
@@ -224,6 +232,12 @@
     _inheritable = True
     SelectResultsClass = InheritableSelectResults
 
+    def set(self, **kw):
+        if self._parent:
+            SQLObject.set(self, _suppress_set_sig=True, **kw)
+        else:
+            SQLObject.set(self, **kw)
+
     def __classinit__(cls, new_attrs):
         SQLObject.__classinit__(cls, new_attrs)
         # if we are a child class, add sqlbuilder fields from parents
Index: main.py
===================================================================
--- main.py	(revision 3601)
+++ main.py	(working copy)
@@ -1042,8 +1042,8 @@
         if self.sqlmeta.cacheValues:
             setattr(self, instanceName(name), value)
 
-    def set(self, **kw):
-        if not self.sqlmeta._creating and not getattr(self.sqlmeta, "row_update_sig_suppress", False):
+    def set(self, _suppress_set_sig=False, **kw):
+        if not self.sqlmeta._creating and not getattr(self.sqlmeta, "row_update_sig_suppress", False) and not _suppress_set_sig:
             self.sqlmeta.send(events.RowUpdateSignal, self, kw)
         # set() is used to update multiple values at once,
         # potentially with one SQL statement if possible.
Index: versioning/test/test_version.py
===================================================================
--- versioning/test/test_version.py	(revision 3601)
+++ versioning/test/test_version.py	(working copy)
@@ -4,7 +4,6 @@
     # For Python 2.3:
     from sqlobject.events import sorted
 
-from py.test import raises
 from sqlobject import *
 from sqlobject.inheritance import InheritableSQLObject
 from sqlobject.versioning import Versioning
@@ -96,6 +95,7 @@
     assert not hasattr(government, 'versions')
 
     monarchy = Monarchy(name='UK', monarch='king george iv')
+    assert len(list(monarchy.versions)) == 0
     monarchy.set(name='queen elisabeth ii')
     assert len(list(monarchy.versions)) == 1
     assert monarchy.versions[0].name == "UK"
@@ -107,6 +107,8 @@
     vchild.set(name='toon', weapon='dynamite')
     assert len(list(base.versions)) == num_base_versions
     assert len(list(vchild.versions)) == 1
+    vchild.name = "newname" #test setting using setattr directly rather than .set
+    assert len(list(vchild.versions)) == 2
 
 def test_restore():
     setup()
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss

Reply via email to