Ejemplo n.º 1
0
    def __add__(self, other):
        """
        Adds another diff to this one. Will throw an exception if this is not
        possible. (This will *not* be done in place.)
        """
        if not isinstance(other, Diff):
            raise TypeError('Only diffs can be added to a diff.')

        if self.rename != other.rename and False not in (self.rename,
                                                         other.rename):
            raise ConflictError('Diffs contain conflicting renamings.')

        result = copy.deepcopy(self)
        result.rename = self.rename or other.rename
        result.delete = self.delete or other.delete

        for line_nr in other._changes:
            change = other._changes[line_nr]
            if change.delete is True:
                result.delete_line(line_nr)
            if change.add_after is not False:
                result.add_lines(line_nr, change.add_after)
            if change.change is not False:
                result.change_line(line_nr, change.change[0], change.change[1])

        return result
Ejemplo n.º 2
0
    def change_line(self, line_nr, original_line, replacement):
        """
        Changes the given line with the given line number. The replacement will
        be there instead.
        """
        linediff = self._get_change(line_nr)
        if linediff.change is not False and linediff.change[1] != replacement:
            raise ConflictError("An already changed line cannot be changed.")

        linediff.change = (original_line, replacement)
        self._changes[line_nr] = linediff
Ejemplo n.º 3
0
    def change_line(self, line_nr, original_line, replacement):
        r"""
        Changes the given line with the given line number. The replacement will
        be there instead.

        Given an empty diff object:

        >>> diff = Diff(['Hey there! Gorgeous.\n',
        ...              "It's nice that we're here.\n"])

        We can change a line easily:

        >>> diff.change_line(1,
        ...                  'Hey there! Gorgeous.\n',
        ...                  'Hey there! This is sad.\n')
        >>> diff.modified
        ['Hey there! This is sad.\n', "It's nice that we're here.\n"]

        We can even merge changes within one line:

        >>> diff.change_line(1,
        ...                  'Hey there! Gorgeous.\n',
        ...                  'Hello. :( Gorgeous.\n')
        >>> diff.modified
        ['Hello. :( This is sad.\n', "It's nice that we're here.\n"]

        However, if we change something that has been changed before, we'll get
        a conflict:

        >>> diff.change_line(1,  # +ELLIPSIS
        ...                  'Hey there! Gorgeous.\n',
        ...                  'Hello. This is not ok. Gorgeous.\n')
        Traceback (most recent call last):
         ...
        coalib.results.LineDiff.ConflictError: ...
        """
        linediff = self._get_change(line_nr)
        if linediff.change is not False and linediff.change[1] != replacement:
            if len(replacement) == len(linediff.change[1]) == 1:
                raise ConflictError('Cannot merge the given line changes.')

            orig_diff = Diff.from_string_arrays(linediff.change[0],
                                                linediff.change[1])
            new_diff = Diff.from_string_arrays(linediff.change[0],
                                               replacement)
            replacement = ''.join((orig_diff + new_diff).modified)

        linediff.change = (original_line, replacement)
        self._changes[line_nr] = linediff
Ejemplo n.º 4
0
    def add_lines(self, line_nr_before, lines):
        """
        Adds lines after the given line number.

        :param line_nr_before: Line number of the line before the additions.
                               Use 0 for insert lines before everything.
        :param lines:          A list of lines to add.
        """
        if lines == []:
            return  # No action

        linediff = self._get_change(line_nr_before, min_line=0)
        if linediff.add_after is not False:
            raise ConflictError('Cannot add lines after the given line since '
                                'there are already lines.')

        linediff.add_after = lines
        self._changes[line_nr_before] = linediff