[Reproducible-commits] [sphinx] 03/03: Add remove_non_determinism.diff to make Sphinx output reproducible from one build to the other (closes: #776443).
Holger Levsen
holger at moszumanska.debian.org
Mon Mar 23 12:53:44 UTC 2015
This is an automated email from the git hooks/post-receive script.
holger pushed a commit to branch pu/reproducible_builds
in repository sphinx.
commit 4196f75a007546b720e9905ddb2ccd8cef76a7dd
Author: Chris Lamb <lamby at debian.org>
Date: Mon Mar 23 13:52:10 2015 +0100
Add remove_non_determinism.diff to make Sphinx output reproducible from one build to the other (closes: #776443).
---
debian/changelog | 8 ++
debian/patches/remove_non_determinism.diff | 133 +++++++++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 142 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 4067e21..17c35e5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+sphinx (1.2.3+dfsg-1.0~reproducible1) UNRELEASED; urgency=low
+
+ [ Chris Lamb ]
+ * Add remove_non_determinism.diff to make Sphinx output reproducible
+ from one build to the other (closes: #776443).
+
+ -- Jérémy Bobbio <lunar at debian.org> Wed, 28 Jan 2015 14:38:24 +0000
+
sphinx (1.2.3+dfsg-1) unstable; urgency=medium
* New upstream bugfix release.
diff --git a/debian/patches/remove_non_determinism.diff b/debian/patches/remove_non_determinism.diff
new file mode 100644
index 0000000..2db6336
--- /dev/null
+++ b/debian/patches/remove_non_determinism.diff
@@ -0,0 +1,133 @@
+Description: remove non-determinism
+ To enable packages using Sphinx to build reproducibly, its output
+ needs to be the same from one build to another.
+ .
+ Its output now strips memory references such as:
+ .
+ <__main__.A at 0x7f68cb685710>
+ .
+ In addition, various generated files (objects.inv, searchindex.js,
+ translations) are now written with their keys in a determinstic order.
+Author: Chris Lamb <lamby at debian.org>
+
+--- sphinx-1.2.3+dfsg.orig/sphinx/builders/html.py
++++ sphinx-1.2.3+dfsg/sphinx/builders/html.py
+@@ -269,7 +269,8 @@ class StandaloneHTMLBuilder(Builder):
+ # html_domain_indices can be False/True or a list of index names
+ indices_config = self.config.html_domain_indices
+ if indices_config:
+- for domain in self.env.domains.itervalues():
++ for domain_name in sorted(self.env.domains.keys()):
++ domain = self.env.domains[domain_name]
+ for indexcls in domain.indices:
+ indexname = '%s-%s' % (domain.name, indexcls.name)
+ if isinstance(indices_config, list):
+@@ -808,7 +809,7 @@ class StandaloneHTMLBuilder(Builder):
+ compressor = zlib.compressobj(9)
+ for domainname, domain in self.env.domains.iteritems():
+ for name, dispname, type, docname, anchor, prio in \
+- domain.get_objects():
++ sorted(domain.get_objects()):
+ if anchor.endswith(name):
+ # this can shorten the inventory by as much as 25%
+ anchor = anchor[:-len(name)] + '$'
+--- sphinx-1.2.3+dfsg.orig/sphinx/ext/autodoc.py
++++ sphinx-1.2.3+dfsg/sphinx/ext/autodoc.py
+@@ -60,7 +60,6 @@ class DefDict(dict):
+
+ identity = lambda x: x
+
+-
+ class Options(dict):
+ """A dict/attribute hybrid that returns None on nonexisting keys."""
+ def __getattr__(self, name):
+@@ -975,7 +974,8 @@ class FunctionDocumenter(DocstringSignat
+ argspec = getargspec(self.object.__init__)
+ if argspec[0]:
+ del argspec[0][0]
+- args = inspect.formatargspec(*argspec)
++ args = inspect.formatargspec(*argspec,
++ formatvalue=lambda x: '=' + safe_repr(x))
+ # escape backslashes for reST
+ args = args.replace('\\', '\\\\')
+ return args
+@@ -1030,7 +1030,8 @@ class ClassDocumenter(ModuleLevelDocumen
+ return None
+ if argspec[0] and argspec[0][0] in ('cls', 'self'):
+ del argspec[0][0]
+- return inspect.formatargspec(*argspec)
++ return inspect.formatargspec(*argspec,
++ formatvalue=lambda x: '=' + safe_repr(x))
+
+ def format_signature(self):
+ if self.doc_as_attr:
+@@ -1229,7 +1230,8 @@ class MethodDocumenter(DocstringSignatur
+ argspec = getargspec(self.object)
+ if argspec[0] and argspec[0][0] in ('cls', 'self'):
+ del argspec[0][0]
+- args = inspect.formatargspec(*argspec)
++ args = inspect.formatargspec(*argspec,
++ formatvalue=lambda x: '=' + safe_repr(x))
+ # escape backslashes for reST
+ args = args.replace('\\', '\\\\')
+ return args
+--- sphinx-1.2.3+dfsg.orig/sphinx/search/__init__.py
++++ sphinx-1.2.3+dfsg/sphinx/search/__init__.py
+@@ -268,13 +268,13 @@ class IndexBuilder(object):
+ if fn in fn2index:
+ rv[k] = fn2index[fn]
+ else:
+- rv[k] = [fn2index[fn] for fn in v if fn in fn2index]
++ rv[k] = sorted([fn2index[fn] for fn in v if fn in fn2index])
+ return rvs
+
+ def freeze(self):
+ """Create a usable data structure for serializing."""
+- filenames = self._titles.keys()
+- titles = self._titles.values()
++ filenames = sorted(self._titles.keys())
++ titles = sorted(self._titles.values())
+ fn2index = dict((f, i) for (i, f) in enumerate(filenames))
+ terms, title_terms = self.get_terms(fn2index)
+
+--- sphinx-1.2.3+dfsg.orig/sphinx/util/inspect.py
++++ sphinx-1.2.3+dfsg/sphinx/util/inspect.py
+@@ -9,6 +9,7 @@
+ :license: BSD, see LICENSE for details.
+ """
+
++import re
+ import sys
+
+ # this imports the standard library inspect module without resorting to
+@@ -135,7 +136,10 @@ def safe_repr(object):
+ except Exception:
+ raise ValueError
+ if isinstance(s, bytes):
+- return force_decode(s, None).replace('\n', ' ')
++ s = force_decode(s, None)
++ # Strip non-deterministic memory addresses such as
++ # ``<__main__.A at 0x7f68cb685710>``
++ s = re.sub(r' at 0x[0-9a-f]{8,12}(?=>$)', '', s)
+ return s.replace('\n', ' ')
+
+
+--- sphinx-1.2.3+dfsg.orig/sphinx/util/jsdump.py
++++ sphinx-1.2.3+dfsg/sphinx/util/jsdump.py
+@@ -87,11 +87,13 @@ def dumps(obj, key=False):
+ elif isinstance(obj, (int, long, float)):
+ return str(obj)
+ elif isinstance(obj, dict):
+- return '{%s}' % ','.join('%s:%s' % (
++ return '{%s}' % ','.join(sorted('%s:%s' % (
+ dumps(key, True),
+ dumps(value)
+- ) for key, value in obj.iteritems())
+- elif isinstance(obj, (tuple, list, set)):
++ ) for key, value in obj.iteritems()))
++ elif isinstance(obj, set):
++ return '[%s]' % ','.join(sorted(dumps(x) for x in obj))
++ elif isinstance(obj, (tuple, list)):
+ return '[%s]' % ','.join(dumps(x) for x in obj)
+ elif isinstance(obj, basestring):
+ return encode_string(obj)
diff --git a/debian/patches/series b/debian/patches/series
index 5d9378c..02afab5 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,4 @@ python3_test_build_dir.diff
parallel_2to3.diff
no_external_css.diff
fix_latex_hlines.diff
+remove_non_determinism.diff
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/sphinx.git
More information about the Reproducible-commits
mailing list