Package: matplotlib
Version: 1.5.2~rc2-1
Severity: wishlist
Tags: patch upstream
User: reproducible-builds@lists.alioth.debian.org
Usertags: toolchain
X-Debbugs-Cc: reproducible-builds@lists.alioth.debian.org

Dear Maintainer,

While working on the "reproducible builds" effort [1], we have noticed
that some packages (like python-shapely) use matplotlib in their
building process, leading to unreproducible builds (due to the
timestamps inserted in PS/PDF files).

To solve this kind of issues, it would be nice to make matplotlib
support the SOURCE_DATE_EPOCH environment variable [2], so that the
sources last modification date can be used for the timestamps in these
PS and PDF files.

See the attached patch for a proposed solution.

Regards,
Alexis Bienvenüe.

[1] https://wiki.debian.org/ReproducibleBuilds
[2] https://reproducible-builds.org/specs/source-date-epoch/




diff -Nru matplotlib-1.5.2~rc2/debian/changelog matplotlib-1.5.2~rc2/debian/changelog
--- matplotlib-1.5.2~rc2/debian/changelog	2016-05-30 20:36:55.000000000 +0200
+++ matplotlib-1.5.2~rc2/debian/changelog	2016-06-14 19:42:45.000000000 +0200
@@ -1,3 +1,9 @@
+matplotlib (1.5.2~rc2-1.0~reproducible1) UNRELEASED; urgency=medium
+
+  * Reproducible PS/PDF output, using SOURCE_DATE_EPOCH (when set)
+
+ -- Alexis Bienvenüe <p...@passoire.fr>  Tue, 14 Jun 2016 19:42:45 +0200
+
 matplotlib (1.5.2~rc2-1) unstable; urgency=medium
 
   [ Sandro Tosi ]
diff -Nru matplotlib-1.5.2~rc2/debian/patches/honour-SOURCE_DATE_EPOCH.patch matplotlib-1.5.2~rc2/debian/patches/honour-SOURCE_DATE_EPOCH.patch
--- matplotlib-1.5.2~rc2/debian/patches/honour-SOURCE_DATE_EPOCH.patch	1970-01-01 01:00:00.000000000 +0100
+++ matplotlib-1.5.2~rc2/debian/patches/honour-SOURCE_DATE_EPOCH.patch	2016-06-14 23:27:09.000000000 +0200
@@ -0,0 +1,99 @@
+Description: Honour SOURCE_DATE_EPOCH
+ Honour the SOURCE_DATE_EPOCH environment variable, to build timestamps
+ in PS/PDF outputs. This allows reproducible output.
+ See https://reproducible-builds.org/specs/source-date-epoch/
+Author: Alexis Bienvenüe <p...@passoire.fr>
+
+Index: matplotlib-1.5.2~rc2/lib/matplotlib/backends/backend_pdf.py
+===================================================================
+--- matplotlib-1.5.2~rc2.orig/lib/matplotlib/backends/backend_pdf.py
++++ matplotlib-1.5.2~rc2/lib/matplotlib/backends/backend_pdf.py
+@@ -23,7 +23,7 @@ import numpy as np
+ from matplotlib.externals.six import unichr
+ 
+ 
+-from datetime import datetime
++from datetime import datetime, tzinfo, timedelta
+ from math import ceil, cos, floor, pi, sin
+ 
+ import matplotlib
+@@ -134,6 +134,20 @@ def _string_escape(match):
+     assert False
+ 
+ 
++# tzinfo class for UTC
++class UTCtimezone(tzinfo):
++    """UTC"""
++
++    def utcoffset(self, dt):
++        return timedelta(0)
++
++    def tzname(self, dt):
++        return "UTC"
++
++    def dst(self, dt):
++        return timedelta(0)
++
++
+ def pdfRepr(obj):
+     """Map Python objects to PDF syntax."""
+ 
+@@ -201,10 +215,14 @@ def pdfRepr(obj):
+     # A date.
+     elif isinstance(obj, datetime):
+         r = obj.strftime('D:%Y%m%d%H%M%S')
+-        if time.daylight:
+-            z = time.altzone
++        z = obj.utcoffset()
++        if z is not None:
++            z = z.seconds
+         else:
+-            z = time.timezone
++            if time.daylight:
++                z = time.altzone
++            else:
++                z = time.timezone
+         if z == 0:
+             r += 'Z'
+         elif z < 0:
+@@ -457,10 +475,19 @@ class PdfFile(object):
+         self.writeObject(self.rootObject, root)
+ 
+         revision = ''
++        # get source date from SOURCE_DATE_EPOCH, if set
++        # See https://reproducible-builds.org/specs/source-date-epoch/
++        source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
++        if source_date_epoch:
++            source_date = datetime.utcfromtimestamp(int(source_date_epoch))
++            source_date = source_date.replace(tzinfo=UTCtimezone())
++        else:
++            source_date = datetime.today()
++
+         self.infoDict = {
+             'Creator': 'matplotlib %s, http://matplotlib.org' % __version__,
+             'Producer': 'matplotlib pdf backend%s' % revision,
+-            'CreationDate': datetime.today()
++            'CreationDate': source_date
+             }
+ 
+         self.fontNames = {}     # maps filenames to internal font names
+Index: matplotlib-1.5.2~rc2/lib/matplotlib/backends/backend_ps.py
+===================================================================
+--- matplotlib-1.5.2~rc2.orig/lib/matplotlib/backends/backend_ps.py
++++ matplotlib-1.5.2~rc2/lib/matplotlib/backends/backend_ps.py
+@@ -1126,7 +1126,14 @@ class FigureCanvasPS(FigureCanvasBase):
+             if title: print("%%Title: "+title, file=fh)
+             print(("%%Creator: matplotlib version "
+                          +__version__+", http://matplotlib.org/";), file=fh)
+-            print("%%CreationDate: "+time.ctime(time.time()), file=fh)
++            # get source date from SOURCE_DATE_EPOCH, if set
++            # See https://reproducible-builds.org/specs/source-date-epoch/
++            source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
++            if source_date_epoch:
++                source_date = time.asctime(time.gmtime(int(source_date_epoch)))
++            else:
++                source_date = time.ctime()
++            print("%%CreationDate: "+source_date, file=fh)
+             print("%%Orientation: " + orientation, file=fh)
+             if not isEPSF: print("%%DocumentPaperSizes: "+papertype, file=fh)
+             print("%%%%BoundingBox: %d %d %d %d" % bbox, file=fh)
diff -Nru matplotlib-1.5.2~rc2/debian/patches/series matplotlib-1.5.2~rc2/debian/patches/series
--- matplotlib-1.5.2~rc2/debian/patches/series	2016-05-30 20:36:55.000000000 +0200
+++ matplotlib-1.5.2~rc2/debian/patches/series	2016-06-14 19:40:12.000000000 +0200
@@ -5,3 +5,4 @@
 0005-bts800803-disable-the-GitHub-Fork-Me-ribbon.patch
 0006-bts800803-dont-use-the-Raleway-font-from-the-Google-.patch
 0007-bts800803-remote-the-Google-Analytics-tracking.patch
+honour-SOURCE_DATE_EPOCH.patch

_______________________________________________
Reproducible-builds mailing list
Reproducible-builds@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/reproducible-builds

Reply via email to