chiark / gitweb /
documentation/python: support enums.
authorVladimír Vondruš <mosra@centrum.cz>
Sat, 20 Apr 2019 14:10:19 +0000 (16:10 +0200)
committerVladimír Vondruš <mosra@centrum.cz>
Mon, 22 Apr 2019 15:53:36 +0000 (17:53 +0200)
doc/documentation/python.rst
documentation/python.py
documentation/templates/python/class.html
documentation/templates/python/details-enum.html [new file with mode: 0644]
documentation/templates/python/entry-enum.html [new file with mode: 0644]
documentation/templates/python/module.html
documentation/test_python/inspect_all_property/inspect_all_property.html
documentation/test_python/inspect_all_property/inspect_all_property/__init__.py
documentation/test_python/inspect_string/inspect_string.Foo.html
documentation/test_python/inspect_string/inspect_string.html
documentation/test_python/inspect_string/inspect_string/__init__.py

index d9b20475e69ce1afe1ca276fd12cf38d3cf3db94..9096379672f4d7bbe1a40aa3c1499ea85ed14f41 100644 (file)
@@ -481,6 +481,32 @@ extracted from the property getter.
     would require parsing Python code directly (which is what Sphinx has to do
     to support these).
 
+`Documenting enum values`_
+--------------------------
+
+Python supplies an implicit docstrings for enums derived from :py:`enum.Enum`
+and enum values implicitly inherit the docstring of the enum class. If either
+is detected to be the case, docstring of the enum or the value is ignored.
+While it's possible to document enum classes the usual way, there's a
+non-obvious way to document enum values as well.
+
+.. code:: py
+
+    import enum
+
+    class MyEnum(enum.Enum):
+        """My enum"""
+
+        ZERO = 0
+        TWO = 3
+        CONSISTENCY = -73
+
+    MyEnum.ZERO.__doc__ = "Zero value"
+    MyEnum.TWO.__doc__ = "Three, but named TWO for compatibility"
+
+The documentation output for enums includes enum value values and the class it
+was derived from, so it's possible to know whether it's an enum or a flag.
+
 `Command-line options`_
 =======================
 
@@ -595,14 +621,21 @@ Each module page has the following additional properties:
 ======================================= =======================================
 Property                                Description
 ======================================= =======================================
+:py:`page.prefix_wbr`                   Fully-qualified symbol prefix for given
+                                        compound with trailing ``.`` with
+                                        :html:`<wbr/>` tag after every ``.``.
 :py:`page.modules`                      List of inner modules. See
                                         `Module properties`_ for details.
 :py:`page.classes`                      List of classes. See
                                         `Class properties`_ for details.
+:py:`page.enums`                        List of enums. See
+                                        `Enum properties`_ for details.
 :py:`page.functions`                    List of module-level functions. See
                                         `Function properties`_ for details.
 :py:`page.data`                         List of module-level data. See
                                         `Data properties`_ for details.
+:py:`page.has_enum_details`             If there is at least one enum with full
+                                        description block [2]_
 ======================================= =======================================
 
 Each class page has the following additional properties:
@@ -612,8 +645,13 @@ Each class page has the following additional properties:
 ======================================= =======================================
 Property                                Description
 ======================================= =======================================
+:py:`page.prefix_wbr`                   Fully-qualified symbol prefix for given
+                                        compound with trailing ``.`` with
+                                        :html:`<wbr/>` tag after every ``.``.
 :py:`page.classes`                      List of classes. See
                                         `Class properties`_ for details.
+:py:`page.enums`                        List of enums. See
+                                        `Enum properties`_ for details.
 :py:`page.classmethods`                 List of class methods (annotated with
                                         :py:`@classmethod`). See
                                         `Function properties`_ for details.
@@ -629,6 +667,8 @@ Property                                Description
                                         `Property properties`_ for details.
 :py:`page.data`                         List of data. See `Data properties`_
                                         for details.
+:py:`page.has_enum_details`             If there is at least one enum with full
+                                        description block [2]_
 ======================================= =======================================
 
 `Module properties`_
@@ -657,6 +697,38 @@ Property                                Description
 :py:`class_.brief`                      Brief docs
 ======================================= =======================================
 
+`Enum properties`_
+```````````````````
+
+.. class:: m-table m-fullwidth
+
+======================================= =======================================
+Property                                Description
+======================================= =======================================
+:py:`enum.name`                         Enum name
+:py:`enum.brief`                        Brief docs
+:py:`enum.base`                         Base class from which the enum is
+                                        derived
+:py:`enum.values`                       List of enum values
+:py:`enum.has_details`                  If there is enough content for the full
+                                        description block. [2]_
+:py:`enum.has_value_details`            If the enum values have description.
+                                        Impies :py:`enum.has_details`.
+======================================= =======================================
+
+Every item of :py:`enum.values` has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`value.name`            Value name
+:py:`value.value`           Value value. Set to :py:`None` if no value is
+                            available.
+:py:`value.brief`           Value brief docs
+=========================== ===================================================
+
 `Function properties`_
 ``````````````````````
 
index 4d81ae1b01d3fde94673b511d39d8506b7a87fa3..cd38f8ab4e1ec068f4cdfb71e7e44dfdeaba2cb3 100755 (executable)
@@ -26,6 +26,7 @@
 
 import argparse
 import copy
+import enum
 import urllib.parse
 import html
 import importlib
@@ -181,6 +182,41 @@ def extract_class_doc(path: List[str], class_):
     out.brief = extract_brief(class_.__doc__)
     return out
 
+def extract_enum_doc(path: List[str], enum_):
+    assert issubclass(enum_, enum.Enum)
+
+    out = Empty()
+    out.name = path[-1]
+
+    # Enum doc is by default set to a generic value. That's useless as well.
+    if enum_.__doc__ == 'An enumeration.':
+        out.brief = ''
+    else:
+        out.brief = extract_brief(enum_.__doc__)
+
+    out.base = extract_type(enum_.__base__)
+    out.values = []
+    out.has_details = False
+    out.has_value_details = False
+
+    for i in enum_:
+        value = Empty()
+        value.name = i.name
+        value.value = html.escape(repr(i.value))
+
+        # Value doc gets by default inherited from the enum, that's useless
+        if i.__doc__ == enum_.__doc__:
+            value.brief = ''
+        else:
+            value.brief = extract_brief(i.__doc__)
+
+        if value.brief:
+            out.has_details = True
+            out.has_value_details = True
+        out.values += [value]
+
+    return out
+
 def extract_function_doc(path: List[str], function):
     assert inspect.isfunction(function) or inspect.ismethod(function) or inspect.isroutine(function)
 
@@ -271,10 +307,13 @@ def render_module(config, path, module, env):
     page.brief = extract_brief(module.__doc__)
     page.url = breadcrumb[-1][1]
     page.breadcrumb = breadcrumb
+    page.prefix_wbr = '.<wbr />'.join(path + [''])
     page.modules = []
     page.classes = []
+    page.enums = []
     page.functions = []
     page.data = []
+    page.has_enum_details = False
 
     # This is actually complicated -- if the module defines __all__, use that.
     # The __all__ is meant to expose the public API, so we don't filter out
@@ -292,9 +331,13 @@ def render_module(config, path, module, env):
             if inspect.ismodule(object):
                 page.modules += [extract_module_doc(subpath, object)]
                 render_module(config, subpath, object, env)
-            elif inspect.isclass(object):
+            elif inspect.isclass(object) and not issubclass(object, enum.Enum):
                 page.classes += [extract_class_doc(subpath, object)]
                 render_class(config, subpath, object, env)
+            elif inspect.isclass(object) and issubclass(object, enum.Enum):
+                enum_ = extract_enum_doc(subpath, object)
+                page.enums += [enum_]
+                if enum_.has_details: page.has_enum_details = True
             elif inspect.isfunction(object) or inspect.isbuiltin(object):
                 page.functions += [extract_function_doc(subpath, object)]
             # Assume everything else is data. The builtin help help() (from
@@ -319,7 +362,7 @@ def render_module(config, path, module, env):
             render_module(config, subpath, object, env)
 
         # Get (and render) inner classes
-        for name, object in inspect.getmembers(module, inspect.isclass):
+        for name, object in inspect.getmembers(module, lambda o: inspect.isclass(o) and not issubclass(o, enum.Enum)):
             if is_internal_or_imported_module_member(module, path, name, object): continue
 
             subpath = path + [name]
@@ -328,6 +371,17 @@ def render_module(config, path, module, env):
             page.classes += [extract_class_doc(subpath, object)]
             render_class(config, subpath, object, env)
 
+        # Get enums
+        for name, object in inspect.getmembers(module, lambda o: inspect.isclass(o) and issubclass(o, enum.Enum)):
+            if is_internal_or_imported_module_member(module, path, name, object): continue
+
+            subpath = path + [name]
+            if not object.__doc__: logging.warning("%s is undocumented", '.'.join(subpath))
+
+            enum_ = extract_enum_doc(subpath, object)
+            page.enums += [enum_]
+            if enum_.has_details: page.has_enum_details = True
+
         # Get inner functions
         for name, object in inspect.getmembers(module, lambda o: inspect.isfunction(o) or inspect.isbuiltin(o)):
             if is_internal_or_imported_module_member(module, path, name, object): continue
@@ -398,16 +452,19 @@ def render_class(config, path, class_, env):
     page.brief = extract_brief(class_.__doc__)
     page.url = breadcrumb[-1][1]
     page.breadcrumb = breadcrumb
+    page.prefix_wbr = '.<wbr />'.join(path + [''])
     page.classes = []
+    page.enums = []
     page.classmethods = []
     page.staticmethods = []
     page.dunder_methods = []
     page.methods = []
     page.properties = []
     page.data = []
+    page.has_enum_details = False
 
     # Get inner classes
-    for name, object in inspect.getmembers(class_, inspect.isclass):
+    for name, object in inspect.getmembers(class_, lambda o: inspect.isclass(o) and not issubclass(o, enum.Enum)):
         if name in ['__base__', '__class__']: continue # TODO
         if name.startswith('_'): continue
 
@@ -417,6 +474,17 @@ def render_class(config, path, class_, env):
         page.classes += [extract_class_doc(subpath, object)]
         render_class(config, subpath, object, env)
 
+    # Get enums
+    for name, object in inspect.getmembers(class_, lambda o: inspect.isclass(o) and issubclass(o, enum.Enum)):
+        if name.startswith('_'): continue
+
+        subpath = path + [name]
+        if not object.__doc__: logging.warning("%s is undocumented", '.'.join(subpath))
+
+        enum_ = extract_enum_doc(subpath, object)
+        page.enums += [enum_]
+        if enum_.has_details: page.has_enum_details = True
+
     # Get methods
     for name, object in inspect.getmembers(class_, inspect.isroutine):
         # Filter out underscored methods (but not dunder methods)
index 27d15f6b65228d5a756ae385855dc68d567b09f4..7bbcf1a72242b42ca0aff0ab8d7158b12cf71e7e 100644 (file)
@@ -1,10 +1,13 @@
 {% extends 'base.html' %}
 
 {% macro entry_class(class) %}{% include 'entry-class.html' %}{% endmacro %}
+{% macro entry_enum(enum) %}{% include 'entry-enum.html' %}{% endmacro %}
 {% macro entry_function(function) %}{% include 'entry-function.html' %}{% endmacro %}
 {% macro entry_property(property) %}{% include 'entry-property.html' %}{% endmacro %}
 {% macro entry_data(data) %}{% include 'entry-data.html' %}{% endmacro %}
 
+{% macro details_enum(enum, prefix) %}{% include 'details-enum.html' %}{% endmacro %}
+
 {% block title %}{% set j = joiner('.') %}{% for name, _ in page.breadcrumb %}{{ j() }}{{ name }}{% endfor %} | {{ super() }}{% endblock %}
 
 {% block main %}
@@ -24,6 +27,9 @@
                 {% if page.classes %}
                 <li><a href="#classes">Classes</a></li>
                 {% endif %}
+                {% if page.enums %}
+                <li><a href="#enums">Enums</a></li>
+                {% endif %}
                 {% if page.classmethods %}
                 <li><a href="#classmethods">Class methods</a></li>
                 {% endif %}
           </dl>
         </section>
         {% endif %}
+        {% if page.enums %}
+        <section id="enums">
+          <h2><a href="#enums">Enums</a></h2>
+          <dl class="m-doc">
+            {% for enum in page.enums %}
+{{ entry_enum(enum) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
         {% if page.classmethods %}
         <section id="classmethods">
           <h2><a href="#classmethods">Class methods</a></h2>
           </dl>
         </section>
         {% endif %}
+        {% if page.has_enum_details %}
+        <section>
+          <h2>Enum documentation</h2>
+          {% for enum in page.enums %}
+          {% if enum.has_details %}
+{{ details_enum(enum, page.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+        </section>
+        {% endif %}
 {% endblock %}
diff --git a/documentation/templates/python/details-enum.html b/documentation/templates/python/details-enum.html
new file mode 100644 (file)
index 0000000..50fb94d
--- /dev/null
@@ -0,0 +1,25 @@
+          <section class="m-doc-details"><div>
+            <h3>
+              class {{ prefix }}<a href="" class="m-doc-self">{{ enum.name }}</a>({{ enum.base }})
+            </h3>
+            {% if enum.brief %}
+            <p>{{ enum.brief }}</p>
+            {% endif %}
+            {% if enum.has_value_details %}
+            <table class="m-table m-fullwidth m-flat m-doc">
+              <thead><tr><th style="width: 1%">Enumerators</th><th></th></tr></thead>
+              <tbody>
+                {% for value in enum.values %}
+                <tr>
+                  <td><a href="" class="m-doc-self">{{ value.name }}</a></td>
+                  <td>
+                  {% if value.brief %}
+                  <p>{{ value.brief }}</p>
+                  {% endif %}
+                  </td>
+                </tr>
+                {% endfor %}
+              </tbody>
+            </table>
+            {% endif %}
+          </div></section>
diff --git a/documentation/templates/python/entry-enum.html b/documentation/templates/python/entry-enum.html
new file mode 100644 (file)
index 0000000..6b83083
--- /dev/null
@@ -0,0 +1,5 @@
+            <dt>
+              {% set j = joiner('\n              ') %}
+              <span class="m-doc-wrap-bumper">class <a href="" class="m-doc{% if not enum.has_details %}-self{% endif %}">{{ enum.name }}</a>({{ enum.base }}): </span><span class="m-doc-wrap">{% for value in enum.values %}{{ j() }}<a href="" class="m-doc{% if not enum.has_details %}-self{% endif %}">{{ value.name }}</a>{% if value.value is not none %} = {{ value.value }}{% endif %}{% endfor %}</span>
+            </dt>
+            <dd>{{ enum.brief }}</dd>
index 09eada78e26ae79fd1566d60ad78fb722c1aff43..0721ba7a59332f3353fb6042757012c559ca2039 100644 (file)
@@ -2,9 +2,12 @@
 
 {% macro entry_module(module) %}{% include 'entry-module.html' %}{% endmacro %}
 {% macro entry_class(class) %}{% include 'entry-class.html' %}{% endmacro %}
+{% macro entry_enum(enum) %}{% include 'entry-enum.html' %}{% endmacro %}
 {% macro entry_function(function) %}{% include 'entry-function.html' %}{% endmacro %}
 {% macro entry_data(data) %}{% include 'entry-data.html' %}{% endmacro %}
 
+{% macro details_enum(enum, prefix) %}{% include 'details-enum.html' %}{% endmacro %}
+
 {% block title %}{% set j = joiner('.') %}{% for name, _ in page.breadcrumb %}{{ j() }}{{ name }}{% endfor %} | {{ super() }}{% endblock %}
 
 {% block main %}
@@ -27,6 +30,9 @@
                 {% if page.classes %}
                 <li><a href="#classes">Classes</a></li>
                 {% endif %}
+                {% if page.enums %}
+                <li><a href="#enums">Enums</a></li>
+                {% endif %}
                 {% if page.functions %}
                 <li><a href="#functions">Functions</a></li>
                 {% endif %}
           </dl>
         </section>
         {% endif %}
+        {% if page.enums %}
+        <section id="enums">
+          <h2><a href="#enums">Enums</a></h2>
+          <dl class="m-doc">
+            {% for enum in page.enums %}
+{{ entry_enum(enum) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
         {% if page.functions %}
         <section id="functions">
           <h2><a href="#functions">Functions</a></h2>
           </dl>
         </section>
         {% endif %}
+        {% if page.has_enum_details %}
+        <section>
+          <h2>Enum documentation</h2>
+          {% for enum in page.enums %}
+          {% if enum.has_details %}
+{{ details_enum(enum, page.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+        </section>
+        {% endif %}
 {% endblock %}
index 771b037cc8e79597fb0cb70b82cea9897357299d..8150aadd60bb0a2e3b29c8b58a172e5398e3d204 100644 (file)
@@ -30,6 +30,7 @@
               <ul>
                 <li><a href="#packages">Modules</a></li>
                 <li><a href="#classes">Classes</a></li>
+                <li><a href="#enums">Enums</a></li>
                 <li><a href="#functions">Functions</a></li>
                 <li><a href="#data">Data</a></li>
               </ul>
             <dd></dd>
           </dl>
         </section>
+        <section id="enums">
+          <h2><a href="#enums">Enums</a></h2>
+          <dl class="m-doc">
+            <dt>
+              <span class="m-doc-wrap-bumper">class <a href="" class="m-doc">_MyPrivateEnum</a>(enum.Enum): </span><span class="m-doc-wrap"><a href="" class="m-doc">VALUE</a> = 1
+              <a href="" class="m-doc">ANOTHER</a> = 2
+              <a href="" class="m-doc">YAY</a> = 3</span>
+            </dt>
+            <dd></dd>
+            <dt>
+              <span class="m-doc-wrap-bumper">class <a href="" class="m-doc-self">UndocumentedEnum</a>(enum.IntFlag): </span><span class="m-doc-wrap"><a href="" class="m-doc-self">FLAG_ONE</a> = 1
+              <a href="" class="m-doc-self">FLAG_SEVENTEEN</a> = 17</span>
+            </dt>
+            <dd></dd>
+          </dl>
+        </section>
         <section id="functions">
           <h2><a href="#functions">Functions</a></h2>
           <dl class="m-doc">
             <dd></dd>
           </dl>
         </section>
+        <section>
+          <h2>Enum documentation</h2>
+          <section class="m-doc-details"><div>
+            <h3>
+              class inspect_all_property.<wbr /><a href="" class="m-doc-self">_MyPrivateEnum</a>(enum.Enum)
+            </h3>
+            <table class="m-table m-fullwidth m-flat m-doc">
+              <thead><tr><th style="width: 1%">Enumerators</th><th></th></tr></thead>
+              <tbody>
+                <tr>
+                  <td><a href="" class="m-doc-self">VALUE</a></td>
+                  <td>
+                  <p>A value</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td><a href="" class="m-doc-self">ANOTHER</a></td>
+                  <td>
+                  <p>Another value</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td><a href="" class="m-doc-self">YAY</a></td>
+                  <td>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </div></section>
+        </section>
       </div>
     </div>
   </div>
index cd670b6440f0b1e1b7a2691deb25e42b70d03b46..b6a737daf91444d665398946632dfdee11b74044 100644 (file)
@@ -1,3 +1,5 @@
+import enum
+
 from . import hidden
 from . import _private_but_exposed
 
@@ -21,4 +23,19 @@ hidden_data = 34
 
 _private_data = 'Hey!'
 
-__all__ = ['_private_but_exposed', '_PrivateButExposedClass', '_private_but_exposed_func', '_private_data']
+class _MyPrivateEnum(enum.Enum):
+    VALUE = 1
+    ANOTHER = 2
+    YAY = 3
+
+_MyPrivateEnum.VALUE.__doc__ = "A value"
+_MyPrivateEnum.ANOTHER.__doc__ = "Another value"
+
+class UndocumentedEnum(enum.IntFlag):
+    FLAG_ONE = 1
+    FLAG_SEVENTEEN = 17
+
+class HiddenEnum(enum.Flag):
+    pass
+
+__all__ = ['_private_but_exposed', '_PrivateButExposedClass', '_private_but_exposed_func', '_private_data', '_MyPrivateEnum', 'UndocumentedEnum']
index b7cdce3e60978d70c2c9d841b949733ceff295ac..234cc9a4cc4db8af05d1fa52222e7af5891590f5 100644 (file)
@@ -30,6 +30,7 @@
               Reference
               <ul>
                 <li><a href="#classes">Classes</a></li>
+                <li><a href="#enums">Enums</a></li>
                 <li><a href="#classmethods">Class methods</a></li>
                 <li><a href="#staticmethods">Static methods</a></li>
                 <li><a href="#methods">Methods</a></li>
             <dd>A subclass of Foo</dd>
           </dl>
         </section>
+        <section id="enums">
+          <h2><a href="#enums">Enums</a></h2>
+          <dl class="m-doc">
+            <dt>
+              <span class="m-doc-wrap-bumper">class <a href="" class="m-doc">InnerEnum</a>(enum.Enum): </span><span class="m-doc-wrap"><a href="" class="m-doc">VALUE</a> = 0
+              <a href="" class="m-doc">ANOTHER</a> = 1
+              <a href="" class="m-doc">YAY</a> = 2</span>
+            </dt>
+            <dd>Inner enum</dd>
+            <dt>
+              <span class="m-doc-wrap-bumper">class <a href="" class="m-doc-self">UndocumentedInnerEnum</a>(enum.IntFlag): </span><span class="m-doc-wrap"><a href="" class="m-doc-self">FLAG_ONE</a> = 1
+              <a href="" class="m-doc-self">FLAG_SEVENTEEN</a> = 17</span>
+            </dt>
+            <dd></dd>
+          </dl>
+        </section>
         <section id="classmethods">
           <h2><a href="#classmethods">Class methods</a></h2>
           <dl class="m-doc">
             <dd></dd>
           </dl>
         </section>
+        <section>
+          <h2>Enum documentation</h2>
+          <section class="m-doc-details"><div>
+            <h3>
+              class inspect_string.<wbr />Foo.<wbr /><a href="" class="m-doc-self">InnerEnum</a>(enum.Enum)
+            </h3>
+            <p>Inner enum</p>
+            <table class="m-table m-fullwidth m-flat m-doc">
+              <thead><tr><th style="width: 1%">Enumerators</th><th></th></tr></thead>
+              <tbody>
+                <tr>
+                  <td><a href="" class="m-doc-self">VALUE</a></td>
+                  <td>
+                  <p>A value</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td><a href="" class="m-doc-self">ANOTHER</a></td>
+                  <td>
+                  <p>Another value</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td><a href="" class="m-doc-self">YAY</a></td>
+                  <td>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </div></section>
+        </section>
       </div>
     </div>
   </div>
index eb283b03fd20430e2f82913750e89f0151743412..1687bf519e2f8f68b4b17ca5c93ce85ea1362465 100644 (file)
@@ -31,6 +31,7 @@
               <ul>
                 <li><a href="#packages">Modules</a></li>
                 <li><a href="#classes">Classes</a></li>
+                <li><a href="#enums">Enums</a></li>
                 <li><a href="#functions">Functions</a></li>
                 <li><a href="#data">Data</a></li>
               </ul>
             <dd>Special class members</dd>
           </dl>
         </section>
+        <section id="enums">
+          <h2><a href="#enums">Enums</a></h2>
+          <dl class="m-doc">
+            <dt>
+              <span class="m-doc-wrap-bumper">class <a href="" class="m-doc">MyEnum</a>(enum.Enum): </span><span class="m-doc-wrap"><a href="" class="m-doc">VALUE</a> = 0
+              <a href="" class="m-doc">ANOTHER</a> = 1
+              <a href="" class="m-doc">YAY</a> = 2</span>
+            </dt>
+            <dd>An enum</dd>
+            <dt>
+              <span class="m-doc-wrap-bumper">class <a href="" class="m-doc-self">UndocumentedEnum</a>(enum.IntFlag): </span><span class="m-doc-wrap"><a href="" class="m-doc-self">FLAG_ONE</a> = 1
+              <a href="" class="m-doc-self">FLAG_SEVENTEEN</a> = 17</span>
+            </dt>
+            <dd></dd>
+          </dl>
+        </section>
         <section id="functions">
           <h2><a href="#functions">Functions</a></h2>
           <dl class="m-doc">
               <a href="" class="m-doc-self">A_CONSTANT</a> = 3.24
             </dt>
             <dd></dd>
+            <dt>
+              <a href="" class="m-doc-self">ENUM_THING</a>
+            </dt>
+            <dd></dd>
             <dt>
               <a href="" class="m-doc-self">foo</a>
             </dt>
             <dd></dd>
           </dl>
         </section>
+        <section>
+          <h2>Enum documentation</h2>
+          <section class="m-doc-details"><div>
+            <h3>
+              class inspect_string.<wbr /><a href="" class="m-doc-self">MyEnum</a>(enum.Enum)
+            </h3>
+            <p>An enum</p>
+            <table class="m-table m-fullwidth m-flat m-doc">
+              <thead><tr><th style="width: 1%">Enumerators</th><th></th></tr></thead>
+              <tbody>
+                <tr>
+                  <td><a href="" class="m-doc-self">VALUE</a></td>
+                  <td>
+                  <p>A value</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td><a href="" class="m-doc-self">ANOTHER</a></td>
+                  <td>
+                  <p>Another value</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td><a href="" class="m-doc-self">YAY</a></td>
+                  <td>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </div></section>
+        </section>
       </div>
     </div>
   </div>
index 987df07a633f44582eda6d163b7100466407c24d..c98973d913ee6de87fbd4cd37f156353206c7000 100644 (file)
@@ -23,6 +23,20 @@ class Foo:
 
     A_DATA = 'BOO'
 
+    class InnerEnum(enum.Enum):
+        """Inner enum"""
+
+        VALUE = 0
+        ANOTHER = 1
+        YAY = 2
+
+    InnerEnum.VALUE.__doc__ = "A value"
+    InnerEnum.ANOTHER.__doc__ = "Another value"
+
+    class UndocumentedInnerEnum(enum.IntFlag):
+        FLAG_ONE = 1
+        FLAG_SEVENTEEN = 17
+
     class Subclass:
         """A subclass of Foo"""
         pass
@@ -102,6 +116,20 @@ class Specials:
         # Undocumented, but should be present
         pass
 
+class MyEnum(enum.Enum):
+    """An enum"""
+
+    VALUE = 0
+    ANOTHER = 1
+    YAY = 2
+
+MyEnum.VALUE.__doc__ = "A value"
+MyEnum.ANOTHER.__doc__ = "Another value"
+
+class UndocumentedEnum(enum.IntFlag):
+    FLAG_ONE = 1
+    FLAG_SEVENTEEN = 17
+
 class _PrivateClass:
     """Private class"""
     pass
@@ -116,6 +144,8 @@ def _private_function():
 
 A_CONSTANT = 3.24
 
+ENUM_THING = MyEnum.YAY
+
 _PRIVATE_CONSTANT = -3
 
 foo = Foo()