From 4e770270cff04125e4953c23c5ab6a1d513783e4 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Wed, 19 Aug 2015 20:33:41 +0200 Subject: [PATCH 1/5] Make grammar generation deterministic. --- sphinx/pycode/pgen2/pgen.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sphinx/pycode/pgen2/pgen.py b/sphinx/pycode/pgen2/pgen.py index e199ed8a3..7598e6abc 100644 --- a/sphinx/pycode/pgen2/pgen.py +++ b/sphinx/pycode/pgen2/pgen.py @@ -4,6 +4,7 @@ from __future__ import print_function from six import iteritems +from collections import OrderedDict # Pgen imports @@ -57,7 +58,7 @@ class ParserGenerator(object): def make_first(self, c, name): rawfirst = self.first[name] first = {} - for label in rawfirst: + for label in sorted(rawfirst): ilabel = self.make_label(c, label) ##assert ilabel not in first # X X X failed on <> ... != first[ilabel] = 1 @@ -138,8 +139,8 @@ class ParserGenerator(object): totalset[label] = 1 overlapcheck[label] = {label: 1} inverse = {} - for label, itsfirst in iteritems(overlapcheck): - for symbol in itsfirst: + for label, itsfirst in sorted(overlapcheck.items()): + for symbol in sorted(itsfirst): if symbol in inverse: raise ValueError("rule %s is ambiguous; %s is in the" " first sets of %s as well as %s" % @@ -349,6 +350,9 @@ class NFAState(object): assert isinstance(next, NFAState) self.arcs.append((label, next)) + def __hash__(self): + return hash(tuple(x[0] for x in self.arcs)) + class DFAState(object): def __init__(self, nfaset, final): @@ -357,7 +361,10 @@ class DFAState(object): assert isinstance(final, NFAState) self.nfaset = nfaset self.isfinal = final in nfaset - self.arcs = {} # map from label to DFAState + self.arcs = OrderedDict() # map from label to DFAState + + def __hash__(self): + return hash(tuple(self.arcs)) def addarc(self, next, label): assert isinstance(label, str) From aee7bd2952e33a0ef28799c80954a98ba7eb298e Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Wed, 19 Aug 2015 20:36:53 +0200 Subject: [PATCH 2/5] Make inventory generation deterministic. --- sphinx/builders/html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 0dc0c0a31..6c24f1189 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -837,7 +837,7 @@ class StandaloneHTMLBuilder(Builder): u'# The remainder of this file is compressed using zlib.\n' % (self.config.project, self.config.version)).encode('utf-8')) compressor = zlib.compressobj(9) - for domainname, domain in iteritems(self.env.domains): + for domainname, domain in sorted(self.env.domains.items()): for name, dispname, type, docname, anchor, prio in \ sorted(domain.get_objects()): if anchor.endswith(name): From a9323e6f59f4276b26488f372ecfff471a44714e Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Wed, 19 Aug 2015 20:38:23 +0200 Subject: [PATCH 3/5] Make Javascript locale deterministic. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 297891545..c38c1fc64 100644 --- a/setup.py +++ b/setup.py @@ -162,7 +162,7 @@ else: messages=jscatalog, plural_expr=catalog.plural_expr, locale=str(catalog.locale) - ), outfile) + ), outfile, sort_keys=True) outfile.write(');') finally: outfile.close() From f5ae89af15eaa41a02cee9e772d425fd441d930d Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Thu, 20 Aug 2015 12:33:21 +0200 Subject: [PATCH 4/5] Fix Python 2.6 incompatibility introduced in 4e77027. --- sphinx/pycode/pgen2/pgen.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sphinx/pycode/pgen2/pgen.py b/sphinx/pycode/pgen2/pgen.py index 7598e6abc..85a1bcc4d 100644 --- a/sphinx/pycode/pgen2/pgen.py +++ b/sphinx/pycode/pgen2/pgen.py @@ -4,7 +4,10 @@ from __future__ import print_function from six import iteritems -from collections import OrderedDict +try: + from collections import OrderedDict +except ImportError: # Fallback for Python 2.6 + OrderedDict = dict # Pgen imports From 9caa4b05f7038b76f69e665912ad60aee9b77f77 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Sun, 30 Aug 2015 21:23:28 +0200 Subject: [PATCH 5/5] Make searchindex generation deterministic. --- sphinx/search/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py index e248088ab..050ab2d7f 100644 --- a/sphinx/search/__init__.py +++ b/sphinx/search/__init__.py @@ -275,9 +275,9 @@ class IndexBuilder(object): rv = {} otypes = self._objtypes onames = self._objnames - for domainname, domain in iteritems(self.env.domains): + for domainname, domain in sorted(iteritems(self.env.domains)): for fullname, dispname, type, docname, anchor, prio in \ - domain.get_objects(): + sorted(domain.get_objects()): # XXX use dispname? if docname not in fn2index: continue