6 Sep 11:38
[Traits] feature request
Hi Dave Morrill,
I see from the implementation (from trunk) that the CHasTraits class
defines a _trait_change_notify method that is used in the trait_set
method to disable/enable notifications. Unfortunately, there is no way
to determine from Python if this flag has been set or not. This is
needed if you want to create a Property trait that does the right thing
in its set method. For example:
class Test(HasTraits):
x = Property(Float)
_x = Float
def _get_x(self):
return self._x
def _set_x(self, value):
old = self._x
self._x = value
if old != new:
self.trait_property_changed('x', old, new)
Clearly, this will break the trait_set method when
trait_change_notify=False. I propose to add a
_get_trait_change_notify() to the ctraits.c to be able to get this so
users can write:
if self._get_trait_change_notify():
...
etc. to work around this.
Attached is a working patch with a test case. This change doesn't break
any existing code.
Could you please check this in? Thanks!
Thanks.
prabhu
Index: enthought/traits/ctraits.c
===================================================================
--- enthought/traits/ctraits.c (revision 21706)
+++ enthought/traits/ctraits.c (working copy)
@@ -1474,6 +1474,24 @@
}
/*-----------------------------------------------------------------------------
+| Returns whether or not trait change notification is enabled for the object:
++----------------------------------------------------------------------------*/
+
+static PyObject *
+_has_get_traits_change_notify ( has_traits_object * obj, PyObject * args ) {
+
+ if ( !PyArg_ParseTuple( args, "" ) )
+ return NULL;
+
+ if ( ( obj->flags & HASTRAITS_NO_NOTIFY ) == 0 ) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
+}
+
+/*-----------------------------------------------------------------------------
| Enables/Disables trait change notifications when this object is assigned to
| a trait:
+----------------------------------------------------------------------------*/
@@ -1623,6 +1641,9 @@
{ "_trait_change_notify", (PyCFunction) _has_traits_change_notify,
METH_VARARGS,
PyDoc_STR( "_trait_change_notify(boolean)" ) },
+ { "_get_trait_change_notify", (PyCFunction) _has_get_traits_change_notify,
+ METH_VARARGS,
+ PyDoc_STR( "_get_trait_change_notify() -> bool" ) },
{ "_trait_veto_notify", (PyCFunction) _has_traits_veto_notify,
METH_VARARGS,
PyDoc_STR( "_trait_veto_notify(boolean)" ) },
from enthought.traits.api import HasTraits, Float, Property, Int
import unittest
class Test(HasTraits):
x = Float
_test = Int(0)
def _x_changed(self, value):
self._test += 1
class TestTraitChangeNotify(unittest.TestCase):
def test_trait_change_notify(self):
"Test if _get/_trait_change_notify work."
t = Test()
t.x = 10.0
self.assertEqual(t._test, 1)
self.assertEqual(t._get_trait_change_notify(), True)
# Turn off notification.
t._trait_change_notify(False)
self.assertEqual(t._get_trait_change_notify(), False)
t.x = 20.0
self.assertEqual(t._test, 1)
# Turn it back on.
t._trait_change_notify(True)
self.assertEqual(t._get_trait_change_notify(), True)
t.x = 30.0
self.assertEqual(t._test, 2)
if __name__ == '__main__':
unittest.main()
_______________________________________________ Enthought-dev mailing list Enthought-dev@... https://mail.enthought.com/mailman/listinfo/enthought-dev
RSS Feed