From 091ffa544484855af53939f298efb912267ac644 Mon Sep 17 00:00:00 2001 From: Wojtek Porczyk Date: Mon, 12 Jan 2015 16:56:14 +0100 Subject: [PATCH] qubes: Add parser for property docstring From now, docstrings in properties cannot contain sphinx-specific features, because there is no sphinx in dom0. --- qubes/__init__.py | 35 +++++++++++++++++++++++++++++------ qubes/vm/qubesvm.py | 31 +++++++++++++++++-------------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/qubes/__init__.py b/qubes/__init__.py index c9491388..4f148d44 100644 --- a/qubes/__init__.py +++ b/qubes/__init__.py @@ -26,6 +26,8 @@ import warnings import __builtin__ +import docutils.core +import docutils.io import lxml.etree 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 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 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: @@ -630,6 +632,26 @@ class property(object): 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 # @@ -1004,17 +1026,18 @@ class Qubes(PropertyHolder): ''' default_netvm = VMProperty('default_netvm', load_stage=3, default=None, - doc='''Default NetVM for AppVMs. Initial state is :py:obj:`None`, which - means that AppVMs are not connected to the Internet.''') + doc='''Default NetVM for AppVMs. Initial state is `None`, which means + that AppVMs are not connected to the Internet.''') default_fw_netvm = VMProperty('default_fw_netvm', load_stage=3, default=None, - doc='''Default NetVM for ProxyVMs. Initial state is :py:obj:`None`, which - means that ProxyVMs (including FirewallVM) are not connected to the + doc='''Default NetVM for ProxyVMs. Initial state is `None`, which means + that ProxyVMs (including FirewallVM) are not connected to the Internet.''') default_template = VMProperty('default_template', load_stage=3, vmclass=qubes.vm.templatevm.TemplateVM, doc='Default template for new AppVMs') 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, doc='Which VM to use as NTP proxy for updating AdminVM') default_kernel = property('default_kernel', load_stage=3, diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index e69b12d1..d9b46dad 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -114,17 +114,17 @@ class QubesVM(qubes.vm.BaseVM): netvm = qubes.VMProperty('netvm', load_stage=4, allow_none=True, default=(lambda self: self.app.default_fw_netvm if self.provides_network else self.app.default_netvm), - doc='VM that provides network connection to this domain. ' - 'When :py:obj:`None`, machine is disconnected. ' - 'When absent, domain uses default NetVM.') + doc='''VM that provides network connection to this domain. When + `None`, machine is disconnected. When absent, domain uses default + NetVM.''') 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, setter=_setter_qid, - doc='Internal, persistent identificator of particular domain. ' - 'Note this is different from Xen domid.') + doc='''Internal, persistent identificator of particular domain. Note + this is different from Xen domid.''') name = qubes.property('name', type=str, 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, setter=qubes.property.bool, - doc="If this domain's image was installed from package tracked by " - "package manager.") + doc='''If this domain's image was installed from package tracked by + package manager.''') memory = qubes.property('memory', type=int, default=qubes.config.defaults['memory'], doc='Memory currently available for this VM.') maxmem = qubes.property('maxmem', type=int, default=None, - doc='Maximum amount of memory available for this VM ' - '(for the purpose of memory balancer).') + doc='''Maximum amount of memory available for this VM (for the purpose + of the memory balancer).''') internal = qubes.property('internal', type=bool, default=False, 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 vcpus = qubes.property('vcpus', default=None, @@ -201,12 +202,14 @@ class QubesVM(qubes.vm.BaseVM): # return self._default_user qrexec_timeout = qubes.property('qrexec_timeout', type=int, default=60, - doc='Time in seconds after which qrexec connection attempt is deemed failed. ' - 'Operating system inside VM should be able to boot in this time.') + doc='''Time in seconds after which qrexec connection attempt is deemed + failed. Operating system inside VM should be able to boot in this + time.''') autostart = qubes.property('autostart', type=bool, default=False, 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 include_in_backups = qubes.property('include_in_backups', type=bool, default=True,