[rb-general] Sphinx output always reproducible?

Chris Lamb lamby at debian.org
Tue Apr 10 23:15:10 CEST 2018


Hi Martin,

>     class A_Class(object):
>         #: A set
>         a_set = {'a', 'b', 'c'}
 
Indeed, the order of the set is arbitrary which ends up in the
documentation as you are seeing.

There are a number of approaches depending on the code, in particular
how much of an "interface" or exposed it is. For example, you could
potentially do:

   - a_set = {'a', 'b', 'c'}
   + _a_set = {'a', 'b', 'c'}

… as the leading "_" means that sphinx ignores it. However, it looks
like this is part of the interface for this XMPP class, so probably not
the best idea.

Another approach might be to:

   - a_set = {'a', 'b', 'c'}
   + a_set = ['a', 'b', 'c']

… as most things will just Magically Work as they are both iterables.
For example, code such as:

 613             elif interface in self.interfaces:
 614                 self[full_interface] = value

… will still work. However, in this particular instance that's still
a bit ugly in context due to this being part of a really kinda clean
interface:
  
  --- slixmpp-1.2.2.orig/slixmpp/xmlstream/stanzabase.py
  +++ slixmpp-1.2.2/slixmpp/xmlstream/stanzabase.py
  @@ -311,7 +311,7 @@ class ElementBase(object):
       #: manipulating the underlying XML object. This set may be augmented
       #: with the :attr:`plugin_attrib` value of any registered
       #: stanza plugins.
  -    interfaces = {'type', 'to', 'from', 'id', 'payload'}
  +    interfaces = ['type', 'to', 'from', 'id', 'payload']
   
       #: A subset of :attr:`interfaces` which maps interfaces to direct
       #: subelements of the underlying XML object. Using this set, the text
  @@ -1385,10 +1385,10 @@ class StanzaBase(ElementBase):
       #: There is a small set of attributes which apply to all XMPP stanzas:
       #: the stanza type, the to and from JIDs, the stanza ID, and, especially
       #: in the case of an Iq stanza, a payload.
  -    interfaces = {'type', 'to', 'from', 'id', 'payload'}
  +    interfaces = ['type', 'to', 'from', 'id', 'payload']
   
       #: A basic set of allowed values for the ``'type'`` interface.
  -    types = {'get', 'set', 'error', None, 'unavailable', 'normal', 'chat'}
  +    types = ['get', 'set', 'error', None, 'unavailable', 'normal', 'chat']
   
       def __init__(self, stream=None, xml=None, stype=None,
                    sto=None, sfrom=None, sid=None, parent=None):

(However, the tests do pass with this applied)

Another (obviously suboptimal!) approach would be to set Sphinx's
":skip-member:" (or something like that), to avoid it appearing in the docs
in the first place.

Finally, we could patch Sphinx to force the ordering. I'm not sure how
difficult this would be, but it might be difficult to get to the Abstract
Syntax Tree to get the "original" ordering (preferable) and I would prefer
not to sort the contents for some undefined æsthetic reason.

Anyway, just my brain-dump at this point, I'm sure other things will come
to mind as soon as I've sent this. :)


Best wishes,

-- 
      ,''`.
     : :'  :     Chris Lamb
     `. `'`      lamby at debian.org / chris-lamb.co.uk
       `-


More information about the rb-general mailing list