Source: epydoc
Version: 3.0.1+dfsg-12
Severity: wishlist
Tags: patch
Usertags: randomness fileordering

Dear Maintainer,

while working on the “reproducible builds” effort [1], we have noticed
that documentation written by epydoc list several items in an order that varies
across builds.

Tha attached patch makes sure that subclass lists are traversed in a sorted
fashion, as well as that input files are processed in a deterministic way.

Once applied, more packages using epydoc, e.g. python-csb [2], can be built
reproducibly in our current experimental framework.

Please note that there are also a few more packages [3] that may be affected by 
more specific issues. It is likely that additional patches will follow.

Many thanks,
Sascha Steinbiss

Description: make subclass traversal and input file handling deterministic
Author: Sascha Steinbiss <>
--- a/epydoc/
+++ b/epydoc/
@@ -574,7 +574,7 @@
     subpackage_dirs = set()
     for subdir in pkg_path:
         if os.path.isdir(subdir):
-            for name in os.listdir(subdir):
+            for name in sorted(os.listdir(subdir)):
                 filename = os.path.join(subdir, name)
                 # Is it a valid module filename?
                 if is_module_file(filename):
@@ -660,7 +660,7 @@
         num_items = 0
         if is_package_dir(package_dir):
-            for name in os.listdir(package_dir):
+            for name in sorted(os.listdir(package_dir)):
                 filename = os.path.join(package_dir, name)
                 if is_module_file(filename):
                     num_items += 1
--- a/epydoc/docwriter/
+++ b/epydoc/docwriter/
@@ -879,7 +879,8 @@
                     len(doc.subclasses) > 0):
                     out('<dl><dt>Known Subclasses:</dt>\n<dd>\n    ')
                     out('  <ul class="subclass-list">\n')
-                    for i, subclass in enumerate(doc.subclasses):
+                    sort_key = lambda c:tuple(reversed(c.canonical_name))
+                    for i, subclass in enumerate(sorted(set(doc.subclasses), key=sort_key)):
                         href = self.href(subclass, context=doc)
                         if self._val_is_public(subclass): css = ''
                         else: css = ' class="private"'
Reproducible-builds mailing list

Reply via email to