Coverage for control/typ/base.py : 70%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Base class for data types."""
3from config import Config as C, Names as N
4from control.html import HtmlElements as H
6from control.utils import pick as G, E
9CW = C.web
11QQ = H.icon(CW.unknown[N.generic])
12Qq = H.icon(CW.unknown[N.generic], asChar=True)
14WRONG_TYPE = CW.messages
17class TypeBase:
18 """The base class for functions on typed values.
20 This class is meant to be extended by classes dealing with specific types.
21 It will be extended by Text and Numeric type classes, who in turn will be extended
22 by concrete type classes. And there are the classes Value and Master which
23 will be exteded by type classes for each value table and type classes for
24 each master table respectively.
26 See the config file tables.yaml, under keys `scalarTypes` and `boolTypes`.
28 Attributes
29 ----------
30 widgetType: string
31 The type of widget that this type needs to edit its value. E.g. `text`.
32 rawType: type
33 The Python type that is used to represent values of this type.
34 If it is None, the rawType is not relevant.
35 pattern: string(re)
36 For text widgets, this is a regular expression that constrains what is legal
37 input in the text input field.
38 needsContext: boolean
39 Whether methods of this type need to be supplied with the Context singleton.
41 !!! note
42 In order to compute the representation of a user, the Auth singleton inside the
43 Context singleton is needed to detemine what parts of the user identifiaction
44 the current user is allowed to see.
45 """
47 widgetType = None
48 pattern = None
49 rawType = None
50 needsContext = False
52 @staticmethod
53 def validationMsg(tp):
54 """A validation error message for a specific type.
56 Parameters
57 ----------
58 tp: string
59 The name under which a type is registered.
61 Returns
62 -------
63 string
64 An error message. See web.yaml under key `wrongType`.
65 """
67 return G(WRONG_TYPE, tp)
69 def normalize(self, strVal):
70 """Normalizes a string representation of a value.
72 Parameters
73 ----------
74 strVal: string
75 The string rep that must be normalized.
77 Returns
78 -------
79 string
80 A normalized equivalent representation of the same value.
81 """
83 return str(strVal).strip()
85 def fromStr(self, editVal):
86 """Turns the output from an edit widget into a real value that can be saved.
88 Parameters
89 ----------
90 editVal: string
91 The output of an edit widget.
93 Returns
94 -------
95 mixed
96 A value of the type in question, corresponding to `editVal`.
97 """
99 if not editVal: 99 ↛ 100line 99 didn't jump to line 100, because the condition on line 99 was never true
100 return None
101 val = self.normalize(editVal)
102 cast = self.rawType
103 return val if cast is None else cast(val)
105 def toDisplay(self, val, markup=True):
106 """Turns a real value into a HTML code for readonly display.
108 Parameters
109 ----------
110 val: mixed
111 A value of this type.
113 Returns
114 -------
115 string(html)
116 Possibly with nice formatting depending on the nature of the value.
117 """
119 if val is None:
120 return None if markup is None else QQ if markup else Qq
121 valBare = val if markup is None else H.he(self.normalize(str(val)))
122 return H.span(valBare) if markup else valBare
124 def toEdit(self, val):
125 """Turns a real value into a string for editable display.
127 Parameters
128 ----------
129 val: mixed
130 A value of this type.
132 Returns
133 -------
134 string
135 """
137 return E if val is None else self.normalize(str(val))
139 def toOrig(self, val):
140 """Turns a real value into an (original) value.
142 The resulting value can be used for comparison with newly entered values
143 in an edit widget at the client side.
145 Parameters
146 ----------
147 val: mixed
148 A value of this type.
150 Returns
151 -------
152 boolean | string | None
153 """
155 if val is None: 155 ↛ 156line 155 didn't jump to line 156, because the condition on line 155 was never true
156 return None
157 return str(val)
159 def widget(self, val):
160 """Constructs and edit widget around for this type.
162 Parameters
163 ----------
164 val: string
165 The initial value for the widget.
167 Returns
168 -------
169 string(html)
170 Dependent on a batch of Javascript in `index.js`, look for `const widgets`.
171 """
173 atts = {}
174 if self.pattern:
175 atts[N.pattern] = self.pattern
176 validationMsg = TypeBase.validationMsg(self.name)
178 widgetElem = H.input(self.toEdit(val), type=N.text, cls="wvalue", **atts)
179 validationElem = H.span(E, valmsg=validationMsg) if validationMsg else E
180 return H.join([widgetElem, validationElem])