qubes: property may be unset by assinging DEFAULT
Introducing qubes.property.DEFAULT special value, which may be assigned to any property. Result is the same as del'ing a property.
This commit is contained in:
		
							parent
							
								
									713ced8cd2
								
							
						
					
					
						commit
						6ec86ec9f7
					
				@ -430,6 +430,11 @@ class property(object):
 | 
				
			|||||||
    This class holds one property that can be saved to and loaded from
 | 
					    This class holds one property that can be saved to and loaded from
 | 
				
			||||||
    :file:`qubes.xml`. It is used for both global and per-VM properties.
 | 
					    :file:`qubes.xml`. It is used for both global and per-VM properties.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Property can be unset by ordinary ``del`` statement or assigning
 | 
				
			||||||
 | 
					    :py:attr:`DEFAULT` special value to it. After deletion (or before first
 | 
				
			||||||
 | 
					    assignment/load) attempting to read a property will get its default value
 | 
				
			||||||
 | 
					    or, when no default, py:class:`exceptions.AttributeError`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :param str name: name of the property
 | 
					    :param str name: name of the property
 | 
				
			||||||
    :param collections.Callable setter: if not :py:obj:`None`, this is used to initialise value; first parameter to the function is holder instance and the second is value; this is called before ``type``
 | 
					    :param collections.Callable setter: if not :py:obj:`None`, this is used to initialise value; first parameter to the function is holder instance and the second is value; this is called before ``type``
 | 
				
			||||||
    :param collections.Callable saver: function to coerce value to something readable by setter
 | 
					    :param collections.Callable saver: function to coerce value to something readable by setter
 | 
				
			||||||
@ -459,6 +464,10 @@ class property(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #: Assigning this value to property means setting it to its default value.
 | 
				
			||||||
 | 
					    #: If property has no default value, this will unset it.
 | 
				
			||||||
 | 
					    DEFAULT = object()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, name, setter=None, saver=None, type=None, default=None,
 | 
					    def __init__(self, name, setter=None, saver=None, type=None, default=None,
 | 
				
			||||||
            load_stage=2, order=0, save_via_ref=False, doc=None):
 | 
					            load_stage=2, order=0, save_via_ref=False, doc=None):
 | 
				
			||||||
        self.__name__ = name
 | 
					        self.__name__ = name
 | 
				
			||||||
@ -498,6 +507,10 @@ class property(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __set__(self, instance, value):
 | 
					    def __set__(self, instance, value):
 | 
				
			||||||
 | 
					        if value is self.__class__.DEFAULT:
 | 
				
			||||||
 | 
					            self.__delete__(instance)
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            oldvalue = getattr(instance, self.__name__)
 | 
					            oldvalue = getattr(instance, self.__name__)
 | 
				
			||||||
            has_oldvalue = True
 | 
					            has_oldvalue = True
 | 
				
			||||||
 | 
				
			|||||||
@ -123,7 +123,20 @@ class TC_10_property(qubes.tests.QubesTestCase):
 | 
				
			|||||||
        with self.assertRaises(AttributeError):
 | 
					        with self.assertRaises(AttributeError):
 | 
				
			||||||
            self.holder.testprop
 | 
					            self.holder.testprop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_091_delete_default(self):
 | 
					    def test_090_delete_by_assign(self):
 | 
				
			||||||
 | 
					        self.holder.testprop1 = 'testvalue'
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if self.holder.testprop1 != 'testvalue':
 | 
				
			||||||
 | 
					                self.skipTest('testprop1 value is wrong')
 | 
				
			||||||
 | 
					        except AttributeError:
 | 
				
			||||||
 | 
					            self.skipTest('testprop1 value is wrong')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.holder.testprop1 = qubes.property.DEFAULT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with self.assertRaises(AttributeError):
 | 
				
			||||||
 | 
					            self.holder.testprop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_092_delete_default(self):
 | 
				
			||||||
        class TestHolder(qubes.tests.TestEmitter, qubes.PropertyHolder):
 | 
					        class TestHolder(qubes.tests.TestEmitter, qubes.PropertyHolder):
 | 
				
			||||||
            testprop1 = qubes.property('testprop1', default='defaultvalue')
 | 
					            testprop1 = qubes.property('testprop1', default='defaultvalue')
 | 
				
			||||||
        holder = TestHolder(None)
 | 
					        holder = TestHolder(None)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user