From e76e6071c99b0c8e2697a6f69b9d08014041222c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= Date: Sun, 15 May 2016 15:53:34 +0300 Subject: [PATCH 1/2] Output pdf dictionaries in deterministic order for #6317 --- lib/matplotlib/backends/backend_pdf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 8bbe991bd1a1..01145b785df5 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -182,8 +182,8 @@ def pdfRepr(obj): # represented as Name objects. elif isinstance(obj, dict): r = [b"<<"] - r.extend([Name(key).pdfRepr() + b" " + pdfRepr(val) - for key, val in six.iteritems(obj)]) + r.extend([Name(key).pdfRepr() + b" " + pdfRepr(obj[key]) + for key in sorted(six.iterkeys(obj))]) r.append(b">>") return fill(r) From 9dfb35d00776a90b72d2fc08c371b125ba5777c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20K=2E=20Sepp=C3=A4nen?= Date: Sun, 15 May 2016 16:37:25 +0300 Subject: [PATCH 2/2] Make backend_pdf.Name comparable and hashable --- lib/matplotlib/backends/backend_pdf.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 01145b785df5..c73f0e867101 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -18,6 +18,7 @@ import warnings import zlib from io import BytesIO +from functools import total_ordering import numpy as np from matplotlib.externals.six import unichr @@ -183,7 +184,7 @@ def pdfRepr(obj): elif isinstance(obj, dict): r = [b"<<"] r.extend([Name(key).pdfRepr() + b" " + pdfRepr(obj[key]) - for key in sorted(six.iterkeys(obj))]) + for key in sorted(obj)]) r.append(b">>") return fill(r) @@ -243,6 +244,7 @@ def write(self, contents, file): write(b"\nendobj\n") +@total_ordering class Name(object): """PDF name object.""" __slots__ = ('name',) @@ -262,6 +264,15 @@ def __repr__(self): def __str__(self): return '/' + six.text_type(self.name) + def __eq__(self, other): + return isinstance(other, Name) and self.name == other.name + + def __lt__(self, other): + return isinstance(other, Name) and self.name < other.name + + def __hash__(self): + return hash(self.name) + @staticmethod def hexify(match): return '#%02x' % ord(match.group())