qubes: Add parser for property docstring

From now, docstrings in properties cannot contain sphinx-specific features,
because there is no sphinx in dom0.
This commit is contained in:
Wojtek Porczyk 2015-01-12 16:56:14 +01:00
parent 0a94762508
commit 091ffa5444
2 changed files with 46 additions and 20 deletions

View File

@ -26,6 +26,8 @@ import warnings
import __builtin__ import __builtin__
import docutils.core
import docutils.io
import lxml.etree import lxml.etree
import xml.parsers.expat import xml.parsers.expat
@ -501,7 +503,7 @@ class property(object):
:param object default: default value; if callable, will be called with holder as first argument :param object default: default value; if callable, will be called with holder as first argument
:param int load_stage: stage when property should be loaded (see :py:class:`Qubes` for description of stages) :param int load_stage: stage when property should be loaded (see :py:class:`Qubes` for description of stages)
:param int order: order of evaluation (bigger order values are later) :param int order: order of evaluation (bigger order values are later)
:param str doc: docstring; you may use RST markup :param str doc: docstring; this should be one paragraph of plain RST, no sphinx-specific features
Setters and savers have following signatures: Setters and savers have following signatures:
@ -630,6 +632,26 @@ class property(object):
return self.__name__ == other.__name__ return self.__name__ == other.__name__
def format_doc(self):
'''Return parsed documentation string, stripping RST markup.
'''
if not self.__doc__: return ''
output, pub = docutils.core.publish_programmatically(
source_class=docutils.io.StringInput,
source=' '.join(self.__doc__.strip().split()),
source_path=None,
destination_class=docutils.io.NullOutput, destination=None,
destination_path=None,
reader=None, reader_name='standalone',
parser=None, parser_name='restructuredtext',
writer=None, writer_name='null',
settings=None, settings_spec=None, settings_overrides=None,
config_section=None, enable_exit_status=None)
return pub.writer.document.astext()
# #
# exceptions # exceptions
# #
@ -1004,17 +1026,18 @@ class Qubes(PropertyHolder):
''' '''
default_netvm = VMProperty('default_netvm', load_stage=3, default=None, default_netvm = VMProperty('default_netvm', load_stage=3, default=None,
doc='''Default NetVM for AppVMs. Initial state is :py:obj:`None`, which doc='''Default NetVM for AppVMs. Initial state is `None`, which means
means that AppVMs are not connected to the Internet.''') that AppVMs are not connected to the Internet.''')
default_fw_netvm = VMProperty('default_fw_netvm', load_stage=3, default=None, default_fw_netvm = VMProperty('default_fw_netvm', load_stage=3, default=None,
doc='''Default NetVM for ProxyVMs. Initial state is :py:obj:`None`, which doc='''Default NetVM for ProxyVMs. Initial state is `None`, which means
means that ProxyVMs (including FirewallVM) are not connected to the that ProxyVMs (including FirewallVM) are not connected to the
Internet.''') Internet.''')
default_template = VMProperty('default_template', load_stage=3, default_template = VMProperty('default_template', load_stage=3,
vmclass=qubes.vm.templatevm.TemplateVM, vmclass=qubes.vm.templatevm.TemplateVM,
doc='Default template for new AppVMs') doc='Default template for new AppVMs')
updatevm = VMProperty('updatevm', load_stage=3, updatevm = VMProperty('updatevm', load_stage=3,
doc='Which VM to use as ``yum`` proxy for updating AdminVM and TemplateVMs') doc='''Which VM to use as `yum` proxy for updating AdminVM and
TemplateVMs''')
clockvm = VMProperty('clockvm', load_stage=3, clockvm = VMProperty('clockvm', load_stage=3,
doc='Which VM to use as NTP proxy for updating AdminVM') doc='Which VM to use as NTP proxy for updating AdminVM')
default_kernel = property('default_kernel', load_stage=3, default_kernel = property('default_kernel', load_stage=3,

View File

@ -114,17 +114,17 @@ class QubesVM(qubes.vm.BaseVM):
netvm = qubes.VMProperty('netvm', load_stage=4, allow_none=True, netvm = qubes.VMProperty('netvm', load_stage=4, allow_none=True,
default=(lambda self: self.app.default_fw_netvm if self.provides_network default=(lambda self: self.app.default_fw_netvm if self.provides_network
else self.app.default_netvm), else self.app.default_netvm),
doc='VM that provides network connection to this domain. ' doc='''VM that provides network connection to this domain. When
'When :py:obj:`None`, machine is disconnected. ' `None`, machine is disconnected. When absent, domain uses default
'When absent, domain uses default NetVM.') NetVM.''')
provides_network = qubes.property('provides_network', type=bool, provides_network = qubes.property('provides_network', type=bool,
doc=':py:obj:`True` if it is NetVM or ProxyVM, false otherwise') doc='`True` if it is NetVM or ProxyVM, false otherwise.')
qid = qubes.property('qid', type=int, qid = qubes.property('qid', type=int,
setter=_setter_qid, setter=_setter_qid,
doc='Internal, persistent identificator of particular domain. ' doc='''Internal, persistent identificator of particular domain. Note
'Note this is different from Xen domid.') this is different from Xen domid.''')
name = qubes.property('name', type=str, name = qubes.property('name', type=str,
doc='User-specified name of the domain.') doc='User-specified name of the domain.')
@ -146,19 +146,20 @@ class QubesVM(qubes.vm.BaseVM):
installed_by_rpm = qubes.property('installed_by_rpm', type=bool, default=False, installed_by_rpm = qubes.property('installed_by_rpm', type=bool, default=False,
setter=qubes.property.bool, setter=qubes.property.bool,
doc="If this domain's image was installed from package tracked by " doc='''If this domain's image was installed from package tracked by
"package manager.") package manager.''')
memory = qubes.property('memory', type=int, default=qubes.config.defaults['memory'], memory = qubes.property('memory', type=int, default=qubes.config.defaults['memory'],
doc='Memory currently available for this VM.') doc='Memory currently available for this VM.')
maxmem = qubes.property('maxmem', type=int, default=None, maxmem = qubes.property('maxmem', type=int, default=None,
doc='Maximum amount of memory available for this VM ' doc='''Maximum amount of memory available for this VM (for the purpose
'(for the purpose of memory balancer).') of the memory balancer).''')
internal = qubes.property('internal', type=bool, default=False, internal = qubes.property('internal', type=bool, default=False,
setter=qubes.property.bool, setter=qubes.property.bool,
doc="Internal VM (not shown in qubes-manager, doesn't create appmenus entries.") doc='''Internal VM (not shown in qubes-manager, don't create appmenus
entries.''')
# XXX what is that # XXX what is that
vcpus = qubes.property('vcpus', default=None, vcpus = qubes.property('vcpus', default=None,
@ -201,12 +202,14 @@ class QubesVM(qubes.vm.BaseVM):
# return self._default_user # return self._default_user
qrexec_timeout = qubes.property('qrexec_timeout', type=int, default=60, qrexec_timeout = qubes.property('qrexec_timeout', type=int, default=60,
doc='Time in seconds after which qrexec connection attempt is deemed failed. ' doc='''Time in seconds after which qrexec connection attempt is deemed
'Operating system inside VM should be able to boot in this time.') failed. Operating system inside VM should be able to boot in this
time.''')
autostart = qubes.property('autostart', type=bool, default=False, autostart = qubes.property('autostart', type=bool, default=False,
setter=qubes.property.bool, setter=qubes.property.bool,
doc='Setting this to :py:obj:`True` means that VM should be autostarted on dom0 boot.') doc='''Setting this to `True` means that VM should be autostarted on dom0
boot.''')
# XXX I don't understand backups # XXX I don't understand backups
include_in_backups = qubes.property('include_in_backups', type=bool, default=True, include_in_backups = qubes.property('include_in_backups', type=bool, default=True,