2
# This file is part of Checkbox.
4
# Copyright 2008 Canonical Ltd.
6
# Checkbox is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
11
# Checkbox is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
19
from checkbox.attribute import Attribute
20
from checkbox.variables import (BoolVariable, StringVariable,
21
IntVariable, FloatVariable, ListVariable, VariableFactory, Variable,
25
class Property(object):
27
def __init__(self, variable_class=Variable, variable_kwargs={}):
28
self._variable_class = variable_class
29
self._variable_kwargs = variable_kwargs
31
def __get__(self, obj, cls=None):
33
return self._get_attribute(cls)
36
attribute = self._get_attribute(cls)
37
variable = get_variable(obj, attribute)
40
def __set__(self, obj, value):
42
attribute = self._get_attribute(cls)
43
variable = get_variable(obj, attribute)
46
def _detect_name(self, used_cls):
48
for cls in used_cls.__mro__:
49
for attr, prop in cls.__dict__.items():
50
if id(prop) == self_id:
52
raise RuntimeError("Property used in an unknown class")
54
def _get_attribute(self, cls):
56
attribute = cls.__dict__["_checkbox_attributes"].get(self)
58
cls._checkbox_attributes = {}
62
name = self._detect_name(cls)
63
attribute = PropertyAttribute(self, cls, name,
64
self._variable_class, self._variable_kwargs)
65
cls._checkbox_attributes[self] = attribute
70
class PropertyAttribute(Attribute):
72
def __init__(self, prop, cls, name, variable_class, variable_kwargs):
73
super(PropertyAttribute, self).__init__(name, cls,
74
VariableFactory(variable_class, attribute=self, **variable_kwargs))
76
self.cls = cls # Used by references
78
# Copy attributes from the property to avoid one additional
79
# function call on each access.
80
for attr in ["__get__", "__set__"]:
81
setattr(self, attr, getattr(prop, attr))
84
class PropertyType(Property):
86
def __init__(self, **kwargs):
87
kwargs["value"] = kwargs.pop("default", None)
88
kwargs["value_factory"] = kwargs.pop("default_factory", None)
89
super(PropertyType, self).__init__(self.variable_class, kwargs)
92
class Bool(PropertyType):
94
variable_class = BoolVariable
97
class String(PropertyType):
99
variable_class = StringVariable
102
class Int(PropertyType):
104
variable_class = IntVariable
107
class Float(PropertyType):
109
variable_class = FloatVariable
112
class List(PropertyType):
114
variable_class = ListVariable
116
def __init__(self, **kwargs):
117
if "default" in kwargs:
118
raise ValueError("'default' not allowed for List. "
119
"Use 'default_factory' instead.")
120
type = kwargs.pop("type", None)
123
kwargs["item_factory"] = VariableFactory(type._variable_class,
124
**type._variable_kwargs)
125
super(List, self).__init__(**kwargs)