import re
from datetime import datetime, timezone
import difflib
+import pprint
+import copy
from difflib import Differ, SequenceMatcher, IS_LINE_JUNK, IS_CHARACTER_JUNK
+# Third party modules
import six
-__version__ = '0.1.1'
+# Own modules
+
+__version__ = '0.2.1'
LOG = logging.getLogger(__name__)
+DEFAULT_COMMENT_CHAR = '#'
+
+
+# =============================================================================
+def pp(value, indent=4, width=99, depth=None):
+
+ pretty_printer = pprint.PrettyPrinter(
+ indent=indent, width=width, depth=depth)
+ return pretty_printer.pformat(value)
+
# =============================================================================
class ConfigDiffer(Differ):
pat_linejunk = r'^\s*(?:\#.*)?$'
re_linejunk = re.compile(pat_linejunk)
+ re_empty = re.compile(r'^\s*$')
# -------------------------------------------------------------------------
@classmethod
return cls.re_linejunk.search(line) is not None
# -------------------------------------------------------------------------
- def __init__(self):
+ def __init__(self, comment_chars=DEFAULT_COMMENT_CHAR, ignore_empty=False,
+ ignore_whitespace=False, ignore_comment=False, case_insensitive=False):
+
+ self.comment_chars = []
+ self.comment_re = []
+ self.token_re = []
+ self.ignore_empty = ignore_empty
+ self.ignore_whitespace = ignore_whitespace
+ self.ignore_comment = ignore_comment
+ self.case_insensitive = case_insensitive
+
+ if comment_chars:
+ if isinstance(comment_chars, (list, set, tuple)):
+ for char in comment_chars:
+ if not char:
+ continue
+ self.comment_chars.append(str(char))
+ else:
+ self.comment_chars.append(str(comment_chars))
super(ConfigDiffer, self).__init__(
linejunk=IS_LINE_JUNK, charjunk=IS_CHARACTER_JUNK)
+ pat = r'^(\s*"(?:[^"]|\\")*")'
+ self.token_re.append(re.compile(pat))
+ pat = r"^(\s*'(?:[^']|\\')*')"
+ self.token_re.append(re.compile(pat))
+
+ if self.comment_chars:
+ for char in self.comment_chars:
+
+ pat = r'^\s*[^"' + r"'" + r']*?' + re.escape(char) + r'.*$'
+ self.comment_re.append(re.compile(pat, re.MULTILINE))
+
# -------------------------------------------------------------------------
def is_equal(self, a, b):
return equal
+ # -------------------------------------------------------------------------
+ def remove_comments(self, line):
+
+ if not self.comment_chars:
+ return line
+
+ # -------------------------------------------------------------------------
+ def __str__(self):
+ """
+ Typecasting function for translating object structure
+ into a string
+
+ @return: structure as string
+ @rtype: str
+ """
+
+ return pp(self.__dict__)
+
+ # -------------------------------------------------------------------------
+ def __repr__(self):
+ """Typecasting into a string for reproduction."""
+
+ out = "<%s(" % (self.__class__.__name__)
+
+ fields = []
+ fields.append("comment_chars=%r" % (self.comment_chars))
+ fields.append("ignore_empty=%r" % (self.ignore_empty))
+ fields.append("ignore_whitespace=%r" % (self.ignore_whitespace))
+ fields.append("ignore_comment=%r" % (self.ignore_comment))
+ fields.append("case_insensitive=%r" % (self.case_insensitive))
+
+ out += ", ".join(fields) + ")>"
+ return out
+
+
# =============================================================================
class ConfigFileDiffer(ConfigDiffer):