3eb835087a38a98c48f3ea3ad676403315163e3d
[tiramisu.git] / doc / status.txt
1 .. default-role:: literal
2
3 Configuration status
4 ======================
5
6 :module: :api:`config.py`
7 :tests: - :api:`test_option_owner.py`
8         - :api:`test_option_type.py`
9         - :api:`test_option_default.py`
10
11 Available configuration statuses
12 ----------------------------------
13
14 These configuration statuses corresponds to specific global attributes :
15
16 **read write status**
17
18     The configuration can be accessed by `__get__` and `__set__`
19     properties, except for the `hidden` configuration options but, yes, it is
20     possible to modify a disabled option.
21
22     To enable read-write status, call
23     :api:`config.Config.cfgimpl_read_write()`
24
25 **read only status**
26
27     The whole configuration is `frozen`, that is modifiying a value is
28     forbidden. We can access to a configuration option only with the
29     `__getattr__` property.
30
31     The configuration has not an access to the hidden options
32     but can read the disabled options.
33
34     To enable read only status, call :api:`config.Config.cfgimpl_read_only()`
35
36 .. csv-table:: **Configuration's statuses summary**
37    :header: " ", "Hidden", "Disabled", "Mandatory"
38
39     "read only status", `False`, `True`, `True`
40     "read-write status", `True`, `False`, `False`
41
42 .. _`frozenconfig`:
43
44 Freezing a configuration
45 ---------------------------
46
47 At the configuration level, :api:`config.Config.cfgimpl_freeze()` freezes
48 the whole configuration options.
49
50 - :api:`test_option_type.test_frozen_value()`
51 - :api:`test_option_type.test_freeze()`
52
53 .. _`frozen`:
54
55 It is possible to *freeze* a single `Option` object with
56 :api:`option.Option.freeze()`. If you try to modify a frozen option, it
57 raises a `TypeError: trying to change a frozen option object`.
58
59 - :api:`test_option_type.test_freeze_one_option()`
60
61 Moreover, frozen option can return his default value if
62 :api:`option.Option.force_default()` has been called on this option,
63 see :api:`test_option_default.test_force_default_on_freeze()`
64
65
66 Restricted access to an `Option()`
67 -----------------------------------
68
69 Configuration options access statuses are defined at configuration level
70 that corresponds to the :api:`option.Option()`'s `properties` attribute,
71 for example
72
73 **hidden**
74
75     This means that an option raises an error if we try to access
76     the value of the option.
77
78     See `hide()` or `show()` in `Option()` that comes from
79     :api:`option.HiddenBaseType`
80
81 corresponding convenience API provided:
82
83     `hide()`:
84         set the `hidden` attribute to `True`
85
86     `show()`:
87         set the `hidden` attribute to `False`
88
89 **disabled**
90
91     This means that an option *doesn't exists* (doesn't say anything
92     much more thant an `AttibuteAccess` error)
93
94     See in :api:`option.DisabledBaseType` the origins of
95     `Option.enable()` or `Option.disable()`
96
97 corresponding convenience API provided:
98
99     `disable()`:
100         set the `disabled` attribute to `True`
101
102     `enable()`:
103         set the `disabled` attribute to `False`
104
105 Value owners
106 -------------
107
108 Every configuration option has a **owner**. When the option is
109 instanciated, the owner is `default` because a default value has been
110 set (including `None`, take a look at the tests).
111
112 The `value_owner` is the man who did it. Yes, the man who changed the value of the
113 configuration option.
114
115 - At the instance of the `Config` object, the value owner is `default` because
116   the default values are set at the instance of the configuration option object,
117
118 ::
119
120     # let's expect there is an option named 'name'
121     config = Config(descr, bool=False)
122     # the override method has been called
123     config._cfgimpl_value_owners['name'] == 'default'
124
125 - at the modification of an option, the owner is `default_owner`, (which is `user`)
126
127 ::
128
129     # modification of the value by attribute access
130     config.gc.dummy = True
131     assert config.gc._cfgimpl_value_owners['dummy'] == 'user'
132     assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'user'
133
134 - the default owner can be set with the `set_owner()` method
135
136 ::
137
138     config.set_owner('spam')
139     config.set(dummy=True)
140     assert config.gc._cfgimpl_value_owners['dummy'] == 'spam'
141     assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'spam'
142
143
144 Special behaviors for an option
145 ---------------------------------
146
147 **mandatory**
148
149     A mandatory option shall return a value. If a value, or a default value
150     has not been set, a error is raised.
151
152 **has a callback**
153
154     This means that it is a calculated value and therefore automatically
155     protected it cannot be modified by attribute access.
156
157     Its inner state is represented by :api:`option.Option.has_callback()`
158     and :api:`option.Option.hascallback_and_isfrozen()`
159
160 **force default**
161
162     if the configuration option has a default value, the default is
163     returned, otherwise the value is calculated.
164
165     Its inner state is represented by :api:`option.Option.force_default()`
166
167 Configuration options have default values that are stored in the
168 `Option()` object itself. Default values, the `default`, can be set in
169 various ways.
170
171 If a default value is modified by overriding it, not only the value of
172 the option resets to the default that is proposed, but the owner is
173 modified too, it is reseted to `default`.