Revision 685d3b42 lib/build/sphinx_ext.py
b/lib/build/sphinx_ext.py | ||
---|---|---|
27 | 27 |
from cStringIO import StringIO |
28 | 28 |
|
29 | 29 |
import docutils.statemachine |
30 |
import docutils.nodes |
|
31 |
import docutils.utils |
|
30 | 32 |
|
31 | 33 |
import sphinx.errors |
32 | 34 |
import sphinx.util.compat |
33 | 35 |
|
36 |
from ganeti import constants |
|
37 |
from ganeti import compat |
|
38 |
from ganeti import errors |
|
34 | 39 |
from ganeti import utils |
35 | 40 |
from ganeti import opcodes |
36 | 41 |
from ganeti import ht |
... | ... | |
38 | 43 |
|
39 | 44 |
COMMON_PARAM_NAMES = map(operator.itemgetter(0), opcodes.OpCode.OP_PARAMS) |
40 | 45 |
|
46 |
#: Namespace for evaluating expressions |
|
47 |
EVAL_NS = dict(compat=compat, constants=constants, utils=utils, errors=errors) |
|
48 |
|
|
41 | 49 |
|
42 | 50 |
class OpcodeError(sphinx.errors.SphinxError): |
43 | 51 |
category = "Opcode error" |
... | ... | |
150 | 158 |
return [] |
151 | 159 |
|
152 | 160 |
|
161 |
def PythonEvalRole(role, rawtext, text, lineno, inliner, |
|
162 |
options={}, content=[]): |
|
163 |
"""Custom role to evaluate Python expressions. |
|
164 |
|
|
165 |
The expression's result is included as a literal. |
|
166 |
|
|
167 |
""" |
|
168 |
code = docutils.utils.unescape(text, restore_backslashes=True) |
|
169 |
|
|
170 |
try: |
|
171 |
result = eval(code, EVAL_NS) |
|
172 |
except Exception, err: |
|
173 |
msg = inliner.reporter.error("Failed to evaluate %r: %s" % (code, err), |
|
174 |
line=lineno) |
|
175 |
return ([inliner.problematic(rawtext, rawtext, msg)], [msg]) |
|
176 |
|
|
177 |
node = docutils.nodes.literal("", unicode(result), **options) |
|
178 |
|
|
179 |
return ([node], []) |
|
180 |
|
|
181 |
|
|
182 |
class PythonAssert(sphinx.util.compat.Directive): |
|
183 |
"""Custom directive for writing assertions. |
|
184 |
|
|
185 |
The content must be a valid Python expression. If its result does not |
|
186 |
evaluate to C{True}, the assertion fails. |
|
187 |
|
|
188 |
""" |
|
189 |
has_content = True |
|
190 |
required_arguments = 0 |
|
191 |
optional_arguments = 0 |
|
192 |
final_argument_whitespace = False |
|
193 |
|
|
194 |
def run(self): |
|
195 |
self.assert_has_content() |
|
196 |
|
|
197 |
code = "\n".join(self.content) |
|
198 |
|
|
199 |
try: |
|
200 |
result = eval(code, EVAL_NS) |
|
201 |
except Exception, err: |
|
202 |
raise self.error("Failed to evaluate %r: %s" % (code, err)) |
|
203 |
|
|
204 |
if not result: |
|
205 |
raise self.error("Assertion failed: %s" % (code, )) |
|
206 |
|
|
207 |
return [] |
|
208 |
|
|
209 |
|
|
153 | 210 |
def setup(app): |
154 | 211 |
"""Sphinx extension callback. |
155 | 212 |
|
156 | 213 |
""" |
157 | 214 |
app.add_directive("opcode_params", OpcodeParams) |
215 |
app.add_directive("pyassert", PythonAssert) |
|
216 |
app.add_role("pyeval", PythonEvalRole) |
Also available in: Unified diff