# Path: diffoscope/config.py
# class Config(object):
#     max_diff_block_lines = 256
#     max_diff_block_lines_parent = 50
#     max_diff_block_lines_saved = float("inf")
#     # html-dir output uses ratio * max-diff-block-lines as its limit
#     max_diff_block_lines_html_dir_ratio = 4
#     # GNU diff cannot process arbitrary large files :(
#     max_diff_input_lines = 2 ** 20
#     max_report_size = 2000 * 2 ** 10 # 2000 kB
#     max_text_report_size = 0
#     max_report_child_size = 500 * 2 ** 10
#     new_file = False
#     fuzzy_threshold = 60
#     enforce_constraints = True
#     excludes = ()
# 
#     _singleton = {}
# 
#     def __init__(self):
#         self.__dict__ = self._singleton
# 
#     def __setattr__(self, k, v):
#         super(Config, self).__setattr__(k, v)
# 
#         if self.enforce_constraints:
#             self.check_constraints()
# 
#     def check_constraints(self):
#         if self.max_diff_block_lines < self.max_diff_block_lines_parent:  # noqa
#             raise ValueError("max_diff_block_lines ({0.max_diff_block_lines}) "
#                 "cannot be smaller than max_diff_block_lines_parent "
#                 "({0.max_diff_block_lines_parent})".format(self),
#             )
# 
#         max_ = self.max_diff_block_lines_html_dir_ratio * \
#             self.max_diff_block_lines
#         if self.max_diff_block_lines_saved < max_:  # noqa
#             raise ValueError("max_diff_block_lines_saved "
#                 "({0.max_diff_block_lines_saved}) cannot be smaller than "
#                 "{0.max_diff_block_lines_html_dir_ratio} * "
#                 "max_diff_block_lines ({1})".format(self, max_),
#             )
# 
# Path: diffoscope/progress.py
# class Progress(object):
#     def __init__(self, total, msg=""):
#         self.current = 0
#         self.total = total
# 
#         ProgressManager().new_total(total, msg)
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, exc_type, exc_value, exc_traceback):
#         self.step(self.total - self.current)
# 
#     def step(self, delta=1, msg=""):
#         delta = min(self.total - self.current, delta) # clamp
#         if not delta:
#             return
# 
#         self.current += delta
#         ProgressManager().step(delta, msg)
# 
# Path: diffoscope/comparators/utils/fuzzy.py
# def perform_fuzzy_matching(members1, members2):
#     if tlsh == None or Config().fuzzy_threshold == 0:
#         return
#     already_compared = set()
#     # Perform local copies because they will be modified by consumer
#     members1 = dict(members1)
#     members2 = dict(members2)
#     for name1, file1 in members1.items():
#         if file1.is_directory() or not file1.fuzzy_hash:
#             continue
#         comparisons = []
#         for name2, file2 in members2.items():
#             if name2 in already_compared or file2.is_directory() or not file2.fuzzy_hash:
#                 continue
#             comparisons.append((tlsh.diff(file1.fuzzy_hash, file2.fuzzy_hash), name2))
#         if comparisons:
#             comparisons.sort(key=operator.itemgetter(0))
#             score, name2 = comparisons[0]
#             logger.debug('fuzzy top match %s %s: %d difference score', name1, name2, score)
#             if score < Config().fuzzy_threshold:
#                 yield name1, name2, score
#                 already_compared.add(name2)


import abc
import logging
import itertools
import collections
from diffoscope.config import Config
from diffoscope.progress import Progress
from ..missing_file import MissingFile
from .fuzzy import perform_fuzzy_matching
        from .specialize import specialize
        from .compare import compare_commented_files
# -*- coding: utf-8 -*-
#
# diffoscope: in-depth comparison of files, archives, and directories
#
# Copyright © 2016 Chris Lamb <lamby@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
# 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
# along with diffoscope.  If not, see <https://www.gnu.org/licenses/>.





NO_COMMENT = None

logger = logging.getLogger(__name__)


class Container(object, metaclass=abc.ABCMeta):
    def __new__(cls, source):

# Path: diffoscope/config.py
# class Config(object):
#     max_diff_block_lines = 256
#     max_diff_block_lines_parent = 50
#     max_diff_block_lines_saved = float("inf")
#     # html-dir output uses ratio * max-diff-block-lines as its limit
#     max_diff_block_lines_html_dir_ratio = 4
#     # GNU diff cannot process arbitrary large files :(
#     max_diff_input_lines = 2 ** 20
#     max_report_size = 2000 * 2 ** 10 # 2000 kB
#     max_text_report_size = 0
#     max_report_child_size = 500 * 2 ** 10
#     new_file = False
#     fuzzy_threshold = 60
#     enforce_constraints = True
#     excludes = ()
# 
#     _singleton = {}
# 
#     def __init__(self):
#         self.__dict__ = self._singleton
# 
#     def __setattr__(self, k, v):
#         super(Config, self).__setattr__(k, v)
# 
#         if self.enforce_constraints:
#             self.check_constraints()
# 
#     def check_constraints(self):
#         if self.max_diff_block_lines < self.max_diff_block_lines_parent:  # noqa
#             raise ValueError("max_diff_block_lines ({0.max_diff_block_lines}) "
#                 "cannot be smaller than max_diff_block_lines_parent "
#                 "({0.max_diff_block_lines_parent})".format(self),
#             )
# 
#         max_ = self.max_diff_block_lines_html_dir_ratio * \
#             self.max_diff_block_lines
#         if self.max_diff_block_lines_saved < max_:  # noqa
#             raise ValueError("max_diff_block_lines_saved "
#                 "({0.max_diff_block_lines_saved}) cannot be smaller than "
#                 "{0.max_diff_block_lines_html_dir_ratio} * "
#                 "max_diff_block_lines ({1})".format(self, max_),
#             )
# 
# Path: diffoscope/progress.py
# class Progress(object):
#     def __init__(self, total, msg=""):
#         self.current = 0
#         self.total = total
# 
#         ProgressManager().new_total(total, msg)
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, exc_type, exc_value, exc_traceback):
#         self.step(self.total - self.current)
# 
#     def step(self, delta=1, msg=""):
#         delta = min(self.total - self.current, delta) # clamp
#         if not delta:
#             return
# 
#         self.current += delta
#         ProgressManager().step(delta, msg)
# 
# Path: diffoscope/comparators/utils/fuzzy.py
# def perform_fuzzy_matching(members1, members2):
#     if tlsh == None or Config().fuzzy_threshold == 0:
#         return
#     already_compared = set()
#     # Perform local copies because they will be modified by consumer
#     members1 = dict(members1)
#     members2 = dict(members2)
#     for name1, file1 in members1.items():
#         if file1.is_directory() or not file1.fuzzy_hash:
#             continue
#         comparisons = []
#         for name2, file2 in members2.items():
#             if name2 in already_compared or file2.is_directory() or not file2.fuzzy_hash:
#                 continue
#             comparisons.append((tlsh.diff(file1.fuzzy_hash, file2.fuzzy_hash), name2))
#         if comparisons:
#             comparisons.sort(key=operator.itemgetter(0))
#             score, name2 = comparisons[0]
#             logger.debug('fuzzy top match %s %s: %d difference score', name1, name2, score)
#             if score < Config().fuzzy_threshold:
#                 yield name1, name2, score
#                 already_compared.add(name2)


# Path: diffoscope/comparators/utils/container.py
import abc
import logging
import itertools
import collections
from diffoscope.config import Config
from diffoscope.progress import Progress
from ..missing_file import MissingFile
from .fuzzy import perform_fuzzy_matching
        from .specialize import specialize
        from .compare import compare_commented_files

# -*- coding: utf-8 -*-
#
# diffoscope: in-depth comparison of files, archives, and directories
#
# Copyright © 2016 Chris Lamb <lamby@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
# 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
# along with diffoscope.  If not, see <https://www.gnu.org/licenses/>.





NO_COMMENT = None

logger = logging.getLogger(__name__)


class Container(object, metaclass=abc.ABCMeta):
    def __new__(cls, source):

        if isinstance(source, MissingFile):