diff --git a/qubes/__init__.py b/qubes/__init__.py index a404f9a4..9d077c88 100644 --- a/qubes/__init__.py +++ b/qubes/__init__.py @@ -221,14 +221,16 @@ class property(object): # pylint: disable=redefined-builtin,invalid-name return getattr(instance, self._attr_name) except AttributeError: - if self._default is self._NO_DEFAULT: - raise AttributeError( - 'property {!r} not set'.format(self.__name__)) - elif isinstance(self._default, collections.Callable): - return self._default(instance) - else: - return self._default + return self.get_default(instance) + def get_default(self, instance): + if self._default is self._NO_DEFAULT: + raise AttributeError( + 'property {!r} have no default'.format(self.__name__)) + elif isinstance(self._default, collections.Callable): + return self._default(instance) + else: + return self._default def __set__(self, instance, value): self._enforce_write_once(instance) @@ -554,6 +556,15 @@ class PropertyHolder(qubes.events.Emitter): attrname = self.property_get_def(prop)._attr_name return not hasattr(self, attrname) + def property_get_default(self, prop): + '''Get property default value. + + :param qubes.property or str prop: property object of particular + interest + ''' + + return self.property_get_def(prop).get_default(self) + @classmethod def property_get_def(cls, prop): diff --git a/qubes/tests/init.py b/qubes/tests/init.py index 25490c69..a2b9da3e 100644 --- a/qubes/tests/init.py +++ b/qubes/tests/init.py @@ -100,6 +100,9 @@ class TC_10_property(qubes.tests.QubesTestCase): holder = MyTestHolder(None) self.assertEqual(holder.testprop1, 'defaultvalue') + self.assertEqual( + type(holder).testprop1.get_default(holder), + 'defaultvalue') def test_023_get_default_func(self): class MyTestHolder(qubes.tests.TestEmitter, qubes.PropertyHolder): @@ -278,6 +281,13 @@ class TC_20_PropertyHolder(qubes.tests.QubesTestCase): expected_prop3.text = 'testdefault' self.assertXMLEqual(elements_with_defaults[2], expected_prop3) + def test_007_property_get_default(self): + self.assertEqual( + self.holder.property_get_default('testprop3'), + 'testdefault') + with self.assertRaises(AttributeError): + self.holder.property_get_default('testprop1'), + @unittest.skip('test not implemented') def test_010_property_require(self): pass