[diffoscope] 01/05: comparators: Use a singleton to manage our Comparator classes.

Chris Lamb chris at chris-lamb.co.uk
Sat Feb 4 03:45:27 CET 2017


This is an automated email from the git hooks/post-receive script.

lamby pushed a commit to branch master
in repository diffoscope.

commit 4cdfa577f090ca942db42127811937357ae7135a
Author: Chris Lamb <lamby at debian.org>
Date:   Sat Feb 4 14:46:57 2017 +1300

    comparators: Use a singleton to manage our Comparator classes.
    
    This will help testing some of our "fallback" modules.
    
    Signed-off-by: Chris Lamb <lamby at debian.org>
---
 diffoscope/comparators/__init__.py         | 143 ++++++++++++++++++-----------
 diffoscope/comparators/utils/specialize.py |  30 +-----
 2 files changed, 93 insertions(+), 80 deletions(-)

diff --git a/diffoscope/comparators/__init__.py b/diffoscope/comparators/__init__.py
index 29a5749..572e895 100644
--- a/diffoscope/comparators/__init__.py
+++ b/diffoscope/comparators/__init__.py
@@ -4,6 +4,7 @@
 #
 # Copyright © 2014-2015 Jérémy Bobbio <lunar at debian.org>
 #           ©      2015  Helmut Grohne <helmut at subdivi.de>
+#           ©      2017  Chris Lamb <lamby at debian.org>
 #
 # diffoscope is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,55 +19,93 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <https://www.gnu.org/licenses/>.
 
-COMPARATORS = (
-    ('directory.Directory',),
-    ('missing_file.MissingFile',),
-    ('symlink.Symlink',),
-    ('device.Device',),
-    ('debian.DotChangesFile', 'debian_fallback.DotChangesFile'),
-    ('debian.DotDscFile', 'debian_fallback.DotDscFile'),
-    ('debian.DotBuildinfoFile', 'debian_fallback.DotBuildinfoFile'),
-    ('deb.Md5sumsFile',),
-    ('deb.DebDataTarFile',),
-    ('elf.ElfSection',),
-    ('ps.PsFile',),
-    ('javascript.JavaScriptFile',),
-    ('json.JSONFile',),
-    ('text.TextFile',),
-    ('bzip2.Bzip2File',),
-    ('cpio.CpioFile',),
-    ('deb.DebFile',),
-    ('dex.DexFile',),
-    ('elf.ElfFile',),
-    ('macho.MachoFile',),
-    ('fsimage.FsImageFile',),
-    ('elf.StaticLibFile',),
-    ('llvm.LlvmBitCodeFile',),
-    ('sqlite.Sqlite3Database',),
-    ('fonts.TtfFile',),
-    ('gettext.MoFile',),
-    ('ipk.IpkFile',),
-    ('rust.RustObjectFile',),
-    ('gzip.GzipFile',),
-    ('haskell.HiFile',),
-    ('icc.IccFile',),
-    ('iso9660.Iso9660File',),
-    ('java.ClassFile',),
-    ('mono.MonoExeFile',),
-    ('pdf.PdfFile',),
-    ('png.PngFile',),
-    ('ppu.PpuFile',),
-    ('rpm.RpmFile', 'rpm_fallback.RpmFile'),
-    ('squashfs.SquashfsFile',),
-    ('ar.ArFile',),
-    ('tar.TarFile',),
-    ('xz.XzFile',),
-    ('apk.ApkFile',),
-    ('zip.ZipFile',),
-    ('zip.MozillaZipFile',),
-    ('image.JPEGImageFile',),
-    ('image.ICOImageFile',),
-    ('cbfs.CbfsFile',),
-    ('git.GitIndexFile',),
-    ('openssh.PublicKeyFile',),
-)
+import logging
+import importlib
+
+logger = logging.getLogger(__name__)
+
+
+class ComparatorManager(object):
+    COMPARATORS = (
+        ('directory.Directory',),
+        ('missing_file.MissingFile',),
+        ('symlink.Symlink',),
+        ('device.Device',),
+        ('debian.DotChangesFile', 'debian_fallback.DotChangesFile'),
+        ('debian.DotDscFile', 'debian_fallback.DotDscFile'),
+        ('debian.DotBuildinfoFile', 'debian_fallback.DotBuildinfoFile'),
+        ('deb.Md5sumsFile',),
+        ('deb.DebDataTarFile',),
+        ('elf.ElfSection',),
+        ('ps.PsFile',),
+        ('javascript.JavaScriptFile',),
+        ('json.JSONFile',),
+        ('text.TextFile',),
+        ('bzip2.Bzip2File',),
+        ('cpio.CpioFile',),
+        ('deb.DebFile',),
+        ('dex.DexFile',),
+        ('elf.ElfFile',),
+        ('macho.MachoFile',),
+        ('fsimage.FsImageFile',),
+        ('elf.StaticLibFile',),
+        ('llvm.LlvmBitCodeFile',),
+        ('sqlite.Sqlite3Database',),
+        ('fonts.TtfFile',),
+        ('gettext.MoFile',),
+        ('ipk.IpkFile',),
+        ('rust.RustObjectFile',),
+        ('gzip.GzipFile',),
+        ('haskell.HiFile',),
+        ('icc.IccFile',),
+        ('iso9660.Iso9660File',),
+        ('java.ClassFile',),
+        ('mono.MonoExeFile',),
+        ('pdf.PdfFile',),
+        ('png.PngFile',),
+        ('ppu.PpuFile',),
+        ('rpm.RpmFile', 'rpm_fallback.RpmFile'),
+        ('squashfs.SquashfsFile',),
+        ('ar.ArFile',),
+        ('tar.TarFile',),
+        ('xz.XzFile',),
+        ('apk.ApkFile',),
+        ('zip.ZipFile',),
+        ('zip.MozillaZipFile',),
+        ('image.JPEGImageFile',),
+        ('image.ICOImageFile',),
+        ('cbfs.CbfsFile',),
+        ('git.GitIndexFile',),
+        ('openssh.PublicKeyFile',),
+    )
+
+    _singleton = {}
+
+    def __init__(self):
+        self.__dict__ = self._singleton
+
+        if not self._singleton:
+            self.reload()
+
+    def reload(self):
+        self.classes = []
+
+        for xs in self.COMPARATORS:
+            for x in xs:
+                package, klass_name = x.rsplit('.', 1)
+
+                try:
+                    mod = importlib.import_module(
+                        'diffoscope.comparators.{}'.format(package)
+                    )
+                except ImportError:
+                    continue
+
+                self.classes.append(getattr(mod, klass_name))
+                break
+            else:  # noqa
+                raise ImportError(
+                    "Could not import any of {}".format(', '.join(xs))
+                )
+
+        logger.debug("Loaded %d comparator classes", len(self.classes))
diff --git a/diffoscope/comparators/utils/specialize.py b/diffoscope/comparators/utils/specialize.py
index 75c8585..998c949 100644
--- a/diffoscope/comparators/utils/specialize.py
+++ b/diffoscope/comparators/utils/specialize.py
@@ -18,17 +18,16 @@
 # along with diffoscope.  If not, see <https://www.gnu.org/licenses/>.
 
 import logging
-import importlib
 
 from diffoscope.profiling import profile
 
-from .. import COMPARATORS
+from .. import ComparatorManager
 
 logger = logging.getLogger(__name__)
 
 
 def specialize(file):
-    for cls in FILE_CLASSES:
+    for cls in ComparatorManager().classes:
         if isinstance(file, cls):
             return file
 
@@ -60,28 +59,3 @@ def specialize(file):
     logger.debug("Unidentified file. Magic says: %s", file.magic_file_type)
 
     return file
-
-def import_comparators(comparators):
-    result = []
-
-    for xs in comparators:
-        for x in xs:
-            package, klass_name = x.rsplit('.', 1)
-
-            try:
-                mod = importlib.import_module(
-                    'diffoscope.comparators.{}'.format(package)
-                )
-            except ImportError:
-                continue
-
-            result.append(getattr(mod, klass_name))
-            break
-        else:  # noqa
-            raise ImportError(
-                "Could not import any of {}".format(', '.join(xs))
-            )
-
-    return result
-
-FILE_CLASSES = import_comparators(COMPARATORS)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list