File fix-getting-pyc-mtime-on-python-37.patch of Package rpmlint.37325

From 2bf599d7ed9d4b557b3806fa29439e740cae7f95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
Date: Thu, 1 Mar 2018 17:39:10 +0100
Subject: [PATCH] Fix getting pyc mtime on Python 3.7

Fixes https://github.com/rpm-software-management/rpmlint/issues/128
---
 FilesCheck.py                      |  28 +++++++++++++++++++++++++---
 tools/Testing.py                   |   8 ++++++--
 6 files changed, 51 insertions(+), 5 deletions(-)

Index: rpmlint-rpmlint-1.10/FilesCheck.py
===================================================================
--- rpmlint-rpmlint-1.10.orig/FilesCheck.py
+++ rpmlint-rpmlint-1.10/FilesCheck.py
@@ -380,6 +380,27 @@ def py_demarshal_long(b):
     return (b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24))
 
 
+def pyc_magic_from_chunk(chunk):
+    """From given chunk (beginning of the file), return Python magic number"""
+    return py_demarshal_long(chunk[:4]) & 0xffff
+
+
+def pyc_mtime_from_chunk(chunk):
+    """From given chunk (beginning of the file), return mtime or None
+
+    From Python 3.7, mtime is not always present.
+
+    See https://www.python.org/dev/peps/pep-0552/#specification
+    """
+    magic = pyc_magic_from_chunk(chunk)
+    second = py_demarshal_long(chunk[4:8])
+    if magic >= _python_magic_values['3.7'][0]:
+        if second == 0:
+            return py_demarshal_long(chunk[8:12])
+        return None  # No mtime saved, TODO check hashes instead
+    return second
+
+
 def python_bytecode_to_script(path):
     """
     Given a python bytecode path, give the path of the .py file
@@ -736,7 +757,7 @@ class FilesCheck(AbstractCheck.AbstractC
                         if chunk:
                             # Verify that the magic ABI value embedded in the
                             # .pyc header is correct
-                            found_magic = py_demarshal_long(chunk[:4]) & 0xffff
+                            found_magic = pyc_magic_from_chunk(chunk)
                             exp_magic, exp_version = get_expected_pyc_magic(f)
                             if exp_magic and found_magic not in exp_magic:
                                 found_version = 'unknown'
@@ -759,13 +780,14 @@ class FilesCheck(AbstractCheck.AbstractC
 
                             # Verify that the timestamp embedded in the .pyc
                             # header matches the mtime of the .py file:
-                            pyc_timestamp = py_demarshal_long(chunk[4:8])
+                            pyc_timestamp = pyc_mtime_from_chunk(chunk)
                             # If it's a symlink, check target file mtime.
                             srcfile = pkg.readlink(files[source_file])
                             if not srcfile:
                                 printWarning(
                                     pkg, 'python-bytecode-without-source', f)
-                            elif pyc_timestamp != srcfile.mtime:
+                            elif (pyc_timestamp is not None and
+                                  pyc_timestamp != srcfile.mtime):
                                 cts = datetime.fromtimestamp(
                                     pyc_timestamp).isoformat()
                                 sts = datetime.fromtimestamp(
Index: rpmlint-rpmlint-1.10/tools/Testing.py
===================================================================
--- rpmlint-rpmlint-1.10.orig/tools/Testing.py
+++ rpmlint-rpmlint-1.10/tools/Testing.py
@@ -43,13 +43,17 @@ def getOutput():
     return output
 
 
+def getTestedPath(path):
+    return os.path.join(_testpath(), path)
+
+
 def getTestedPackage(name):
-    pkg_path = glob.glob(os.path.join(_testpath(), name) + "-*.rpm")[0]
+    pkg_path = glob.glob(getTestedPath(name) + "-*.rpm")[0]
     return Pkg.Pkg(pkg_path, tempfile.gettempdir())
 
 
 def getTestedSpecPackage(name):
-    pkg_path = glob.glob(os.path.join(_testpath(), name) + ".spec")[0]
+    pkg_path = glob.glob(getTestedPath(name) + ".spec")[0]
     return Pkg.FakePkg(pkg_path)
 
 
openSUSE Build Service is sponsored by