config.py 3.1 KB
Newer Older
1 2 3 4 5
# -*- coding: utf-8 -*-
#
# diffoscope: in-depth comparison of files, archives, and directories
#
# Copyright © 2015 Reiner Herrmann <reiner@reiner-h.de>
6
# Copyright © 2016 Chris Lamb <lamby@debian.org>
7 8 9 10 11 12 13 14 15 16 17 18
#
# diffoscope is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# diffoscope is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
19
# along with diffoscope.  If not, see <https://www.gnu.org/licenses/>.
20 21


22 23 24 25 26 27 28 29 30 31
import logging


logger = logging.getLogger(__name__)


class defaultint(int):
    pass


32 33
# Avoid setting values on this anywhere other than main.run_diffoscope(),
# otherwise tests may fail unpredictably depending on order-of-execution.
34
class Config(object):
35
    _singleton = {}
36

37 38
    def __init__(self):
        self.__dict__ = self._singleton
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
        if not self._singleton:
            self.reset()

    def reset(self):
        # GNU diff cannot process arbitrary large files :(
        self.max_diff_input_lines = 2 ** 22
        self.max_diff_block_lines_saved = float("inf")

        # hard limits, restricts single-file and multi-file formats
        self.max_report_size = defaultint(40 * 2 ** 20)  # 40 MB
        self.max_diff_block_lines = defaultint(2 ** 10)  # 1024 lines
        # structural limits, restricts single-file formats
        # semi-restricts multi-file formats
        self.max_page_size = defaultint(400 * 2 ** 10)  # 400 kB
        self.max_page_size_child = defaultint(200 * 2 ** 10)  # 200 kB
        self.max_page_diff_block_lines = defaultint(2 ** 7)  # 128 lines

        self.max_text_report_size = 0

        self.new_file = False
        self.fuzzy_threshold = 60
        self.enforce_constraints = True
        self.excludes = ()
        self.exclude_commands = ()
        self.exclude_directory_metadata = False
        self.compute_visual_diffs = False
        self.max_container_depth = 50
        self.force_details = False
67 68 69 70

    def __setattr__(self, k, v):
        super(Config, self).__setattr__(k, v)

71 72 73 74
    def check_ge(self, a, b):
        va = getattr(self, a)
        vb = getattr(self, b)
        if va < vb:
75
            if isinstance(vb, defaultint):
Mattia Rizzolo's avatar
Mattia Rizzolo committed
76 77 78 79
                logger.warn(
                    "%s (%s) < default value of %s (%s), setting latter to %s",
                    a, va, b, vb, va
                )
80 81
                setattr(self, b, va)
            else:
Mattia Rizzolo's avatar
Mattia Rizzolo committed
82 83 84 85 86
                raise ValueError(
                    "{0} ({1}) cannot be smaller than {2} ({3})".format(
                        a, va, b, vb
                    )
                )
87 88

    def check_constraints(self):
89 90 91
        self.check_ge("max_diff_block_lines", "max_page_diff_block_lines")
        self.check_ge("max_report_size", "max_page_size")
        self.check_ge("max_report_size", "max_page_size_child")