[pygobject] Don't let Property.setter() method names define property names
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Don't let Property.setter() method names define property names
- Date: Thu, 10 Jan 2013 11:28:47 +0000 (UTC)
commit 8117e6bce73581e89211371708ff7d5de7d870d4
Author: Martin Pitt <martinpitt gnome org>
Date: Thu Jan 10 12:13:16 2013 +0100
Don't let Property.setter() method names define property names
Defining property names in install_properties() is too late when using
@propname.setter decorators; their method names don't define a property name,
nor are they even required to be a valid property identifier.
So change the logic to already fix the property name when using a setter
decorator and use that instead of the member name in install_properties().
https://bugzilla.gnome.org/show_bug.cgi?id=688971
gi/_gobject/propertyhelper.py | 29 ++++++++++++++++++++++-------
tests/test_properties.py | 18 ++++++++++++++++++
2 files changed, 40 insertions(+), 7 deletions(-)
---
diff --git a/gi/_gobject/propertyhelper.py b/gi/_gobject/propertyhelper.py
index a038f1b..d5a1852 100644
--- a/gi/_gobject/propertyhelper.py
+++ b/gi/_gobject/propertyhelper.py
@@ -149,6 +149,8 @@ class Property(object):
@keyword maximum: maximum allowed value (int, float, long only)
"""
+ self.name = None
+
if type is None:
type = object
self.type = self._type_from_python(type)
@@ -180,7 +182,9 @@ class Property(object):
getter = self._default_getter
setter = self._default_setter
self.getter(getter)
- self.setter(setter)
+ # do not call self.setter() here, as this defines the property name
+ # already
+ self.fset = setter
if minimum is not None:
if minimum < self._get_minimum():
@@ -199,8 +203,6 @@ class Property(object):
maximum = self._get_maximum()
self.maximum = maximum
- self.name = None
-
self._exc = None
def __repr__(self):
@@ -248,6 +250,11 @@ class Property(object):
def setter(self, fset):
"""Set the setter function to fset. For use as a decorator."""
self.fset = fset
+ # with a setter decorator, we must ignore the name of the method in
+ # install_properties, as this does not need to be a valid property name
+ # and does not define the property name. So set the name here.
+ if not self.name:
+ self.name = self.fget.__name__
return self
def _type_from_python(self, type_):
@@ -364,10 +371,18 @@ def install_properties(cls):
props = []
for name, prop in cls.__dict__.items():
if isinstance(prop, Property): # not same as the built-in
- if name in gproperties:
- raise ValueError('Property %s was already found in __gproperties__' % name)
- prop.name = name
- gproperties[name] = prop.get_pspec_args()
+ # if a property was defined with a decorator, it may already have
+ # a name; if it was defined with an assignment (prop = Property(...))
+ # we set the property's name to the member name
+ if not prop.name:
+ prop.name = name
+ # we will encounter the same property multiple times in case of
+ # custom setter methods
+ if prop.name in gproperties:
+ if gproperties[prop.name] == prop.get_pspec_args():
+ continue
+ raise ValueError('Property %s was already found in __gproperties__' % prop.name)
+ gproperties[prop.name] = prop.get_pspec_args()
props.append(prop)
if not props:
diff --git a/tests/test_properties.py b/tests/test_properties.py
index fe286e2..d19970f 100644
--- a/tests/test_properties.py
+++ b/tests/test_properties.py
@@ -541,6 +541,24 @@ class TestProperty(unittest.TestCase):
self.assertEqual(o.value, 'blah')
self.assertEqual(o.props.value, 'blah')
+ def test_decorator_private_setter(self):
+ class C(GObject.GObject):
+ _value = 'value'
+
+ @GObject.Property
+ def value(self):
+ return self._value
+
+ @value.setter
+ def _set_value(self, value):
+ self._value = value
+
+ o = C()
+ self.assertEqual(o.value, 'value')
+ o.value = 'blah'
+ self.assertEqual(o.value, 'blah')
+ self.assertEqual(o.props.value, 'blah')
+
def test_decorator_with_call(self):
class C(GObject.GObject):
_value = 1
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]