Skip to content

Commit

Permalink
Remove some unused code.
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Sandve Alnæs committed Jan 4, 2016
1 parent 712d41e commit 360fa2e
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 283 deletions.
80 changes: 9 additions & 71 deletions nbdime/dformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,87 +123,25 @@ def to_dict_diff(ld):
return dd


def decompress_diff(sequence_diff):
"""Split all sequence diff actions ++,--,:: into single-line actions +,-,:.
Current implementation applies only to a single-level sequence list diff.
"""
d = []
for s in sequence_diff:
action = s[0]
if action in (INSERT, DELETE, REPLACE, PATCH):
d.append(s)
elif action == SEQINSERT:
for i, v in enumerate(s[2]):
d.append([INSERT, s[1], v])
elif action == SEQDELETE:
for i in range(s[2]):
d.append([DELETE, s[1] + i])
else:
raise NBDiffFormatError("Invalid action '{}'".format(action))
return d


#def compress_diff(sequence_diff):
# """Combine contiguous single-line actions +,-,: into sequence diff actions ++,--,:: everywhere."""
# pass # Not implemented


def count_consumed_symbols(e):
"Count how many symbols are consumed from each sequence by a single sequence diff entry."
action = e[0]
if action == INSERT:
return 0, 1
elif action == DELETE:
return 1, 0
elif action == REPLACE:
return 1, 1
elif action == PATCH:
return 1, 1
elif action == SEQINSERT:
if action == SEQINSERT:
return 0, len(e[2])
elif action == SEQDELETE:
return e[2], 0
elif action == PATCH:
return 1, 1
else:
raise NBDiffFormatError("Invalid action '{}'".format(action))


def get_equal_ranges(a, b, d):
"Return list of tuples [(i,j,n)] such that a[i:i+n] == b[j:j+n] given a diff d of sequences a and b."
# Count consumed items from a, "take" in patch_list
acons = 0
bcons = 0
ranges = []
for e in d:
#action = e[0]
index = e[1]

# Consume n more unmentioned items.
# Note that index can be larger than acons in the case where items
# have been deleted from a and then insertions from b occur.
n = max(0, index - acons)
if n > 0:
ranges.append((acons, bcons, n))

# Count consumed items
askip, bskip = count_consumed_symbols(e)
acons += n + askip
bcons += n + bskip

# Consume final items
n = len(a) - acons
assert n >= 0
assert len(b) - bcons == n
if n > 0:
ranges.append((acons, bcons, n))

# Sanity check
acons += n
bcons += n
assert acons == len(a)
assert bcons == len(b)

return ranges
def source_as_string(source):
"Return source as a single string, joined as lines if it's a list."
if isinstance(source, list):
source = "\n".join(line.strip("\n") for line in source)
assert isinstance(source, string_types)
return source


def to_json_patch_format(d, path=""):
Expand Down
82 changes: 0 additions & 82 deletions nbdime/diffing/comparing.py

This file was deleted.

8 changes: 2 additions & 6 deletions nbdime/diffing/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@

def is_atomic(x):
"Return True for values that diff should treat as a single atomic value."
atomic_strings = False # TODO: Configuration framework?
if atomic_strings:
return not isinstance(x, (list, dict))
else:
return not isinstance(x, (string_types, list, dict))
return not isinstance(x, (string_types, list, dict))


def diff(a, b, compare=operator.__eq__):
Expand Down Expand Up @@ -81,7 +77,7 @@ def diff_lists(a, b, compare=operator.__eq__, shallow_diff=None):
if not is_atomic(aval):
d = diff(aval, bval, compare=compare)
if d:
pdi.append([PATCH, acons+i, d])
pdi.append([PATCH, acons+i, d]) # FIXME: Not covered in tests, create test situation

# Keep count of consumed items
acons += n + askip
Expand Down
30 changes: 11 additions & 19 deletions nbdime/diffing/notebooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@

import difflib
import operator
from six import string_types

#from ..dformat import PATCH, SEQINSERT, SEQDELETE
#from ..dformat import decompress_diff
from ..dformat import source_as_string

#from .comparing import strings_are_similar
from .sequences import diff_sequence
from .generic import diff, diff_lists, diff_dicts
from .snakes import diff_sequence_multilevel
Expand All @@ -33,12 +32,8 @@ def compare_cell_source_approximate(x, y):
return False

# Convert from list to single string
xs = x["source"]
ys = y["source"]
if isinstance(xs, list):
xs = "\n".join(xs)
if isinstance(ys, list):
ys = "\n".join(ys)
xs = source_as_string(x["source"])
ys = source_as_string(y["source"])

# Cutoff on equality (Python has fast hash functions for strings)
if xs == ys:
Expand Down Expand Up @@ -134,9 +129,9 @@ def diff_single_outputs(a, b, compare="ignored"):

def diff_outputs(a, b, compare="ignored"):
"Diff a pair of lists of outputs from within a single cell."
return diff_sequence_multilevel(a, b,
predicates=[compare_output_data_keys, compare_output_data],
subdiff=diff_single_outputs)
predicates = [compare_output_data_keys,
compare_output_data]
return diff_sequence_multilevel(a, b, predicates, diff_single_outputs)


def diff_single_cells(a, b):
Expand All @@ -145,20 +140,17 @@ def diff_single_cells(a, b):

def diff_cells(a, b, compare="ignored"):
"Diff cell lists a and b. Argument compare is ignored."
# Old alternative implementation:
# shallow_diff = diff_sequence(a, b, compare_cell_source_and_outputs)
# return diff_lists(a, b, compare=operator.__eq__, shallow_diff=shallow_diff)

# Predicates to compare cells in order of low-to-high precedence
predicates = [compare_cell_source_approximate,
compare_cell_source_exact,
compare_cell_source_and_outputs]
return diff_sequence_multilevel(a, b, predicates, diff_single_cells)


def old_diff_cells(cells_a, cells_b):
"Compute the diff of two sequences of cells."
compare_cells = compare_cell_source_and_outputs
shallow_diff = diff_sequence(cells_a, cells_b, compare_cells)
return diff_lists(cells_a, cells_b, compare=operator.__eq__, shallow_diff=shallow_diff)


def diff_notebooks(nba, nbb):
"""Compute the diff of two notebooks."""
return diff_dicts(nba, nbb, subdiffs={"cells": diff_cells})
105 changes: 0 additions & 105 deletions nbdime/merging/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,35 +130,6 @@ def _merge_dicts(base, local, remote, base_local_diff, base_remote_diff):
return merged, local_conflict_diff, remote_conflict_diff


def get_deleted_indices(diff):
deleted = set()
for e in diff:
if e[0] == DELETE:
deleted.add(e[1])
elif e[0] == SEQDELETE:
deleted.update(e[1] + i for i in range(e[2]))
return deleted


def where_deleted(diff, size):
deleted = [False]*size
for e in diff:
if e[0] == DELETE:
deleted[e[1]] = True
elif e[0] == SEQDELETE:
for i in range(e[2]):
deleted[e[1] + i] = True
return deleted


def where_patched(diff, size):
patched = [False]*size
for e in diff:
if e[0] == PATCH:
patched[e[1]] = True
return patched


def _split_diff(diff, size):
deleted = [False]*size
patched = [None]*size
Expand Down Expand Up @@ -308,82 +279,6 @@ def _merge_lists(base, local, remote, base_local_diff, base_remote_diff):
return merged, local_conflict_diff, remote_conflict_diff


def __old_merge_lists(base, local, remote, base_local_diff, base_remote_diff):
"""Perform a three-way merge of lists. See docstring of merge."""
assert isinstance(base, list) and isinstance(local, list) and isinstance(remote, list)

# Compute the diff between the base->local and base->remote diffs
#diffs_diff = diff_sequences(base_local_diff, base_remote_diff)
# TODO: This will be much cleaner if the diffs are single-item only.

# Build sets of deleted indices on each side
#local_deleted = get_deleted_indices(base_local_diff)
#remote_deleted = get_deleted_indices(base_local_diff)

# Build lists of markers, True for base item indices that are deleted in local or remote
local_deleted = where_deleted(base_local_diff, len(base))
remote_deleted = where_deleted(base_remote_diff, len(base))

# Get non-deletion diff entries only
local_diff = [e for e in base_local_diff if e[0] not in (DELETE, SEQDELETE)]
remote_diff = [e for e in base_remote_diff if e[0] not in (DELETE, SEQDELETE)]

# Interleave local and remote diff entries in a merged diff object
merged_diff = []

# Data structures for storing conflicts
local_conflict_diff = []
remote_conflict_diff = []

lk = 0
rk = 0
lastindex = 0
while lk < len(local_diff) and rk < len(remote_diff):
le = local_diff[lk]
re = remote_diff[rk]
lindex = le[1]
rindex = re[1]
index = min(lindex, rindex)

# Insert deletions up to (and including) this point
for i in range(lastindex, index+1): # (+1 for including) # FIXME: include +1 or make it part of conflict resolution?
ldel = i in local_deleted
rdel = i in remote_deleted
if ldel:
local_deleted.remove(i)
if rdel:
remote_deleted.remove(i)
if ldel or rdel:
merged_diff.append([DELETE, i])
lastindex = min(lastindex, index+1) # FIXME: +1 here?

#
if lindex < rindex:
# FIXME: Conflicts if remote_deletes overlap
merged_diff.append(le)
elif lindex > rindex:
# FIXME: Conflicts if local_deletes overlap
merged_diff.append(re)
else:
# FIXME: Create conflict instead of inserting both
# FIXME: Inserting both won't even work for PATCH or REPLACE, only for INSERT
assert le[1] == INSERT and re[1] == INSERT
merged_diff.append(le)
merged_diff.append(re)

# Add trailing diff entries, only one of these can be non-empty
# FIXME: Handle deletion conflicts too here
merged_diff.extend(local_diff[lk:])
merged_diff.extend(remote_diff[rk:])

# Assert that we've inserted all the deletions
assert not local_deleted
assert not remote_deleted

merged = patch(base, merged_diff)
return merged, local_conflict_diff, remote_conflict_diff


def _merge_strings(base, local, remote, base_local_diff, base_remote_diff):
"""Perform a three-way merge of strings. See docstring of merge."""
assert isinstance(base, string_types) and isinstance(local, string_types) and isinstance(remote, string_types)
Expand Down

0 comments on commit 360fa2e

Please sign in to comment.