Python difflib 模块,Differ() 实例源码
我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用difflib.Differ()。
def get_diff_with_color(expected: str, ans: str) -> Tuple[str, str]:
d = difflib.Differ()
diff = d.compare(expected, ans)
expected_with_mistake = ""
ans_with_mistake = ""
for e in diff:
if e.startswith("+"):
ans_with_mistake += colored(e[-1], "red")
elif e.startswith("-"):
expected_with_mistake += colored(e[-1], "green")
else:
expected_with_mistake += e[-1]
ans_with_mistake += e[-1]
return expected_with_mistake, ans_with_mistake
def diff_jobs():
user = root.authorized()
app = root.active_app()
selected_cases = request.query.selected_diff_cases
cases = selected_cases.rstrip(':').split(':')
cids = list()
contents = list()
for jid in cases:
cid = jobs(jid).cid
cids.append(cid)
app = jobs(jid).app
base_dir = os.path.join(user_dir, user, root.myapps[app].appname)
fn = os.path.join(base_dir, cid, root.myapps[app].simfn)
content = slurp_file(fn).splitlines(1)
contents.append(content)
import difflib
d = difflib.Differ()
result = list(d.compare(contents[0], contents[1]))
title = "diff " + cids[0] + " " + cids[1]
params = { 'cid': cid, 'contents': ' '.join(result), 'app': app, 'user': user, 'fn': title }
return template('more', params)
def __init__(self, unexpected_method, expected):
"""Init exception.
Args:
# unexpected_method: MockMethod that was called but was not at the
# head of the expected_method queue.
# expected: MockMethod or UnorderedGroup the method should have
# been in.
unexpected_method: MockMethod
expected: MockMethod or UnorderedGroup
"""
Error.__init__(self)
if expected is None:
self._str = "Unexpected method call %s" % (unexpected_method,)
else:
differ = difflib.Differ()
diff = differ.compare(str(unexpected_method).splitlines(True),
str(expected).splitlines(True))
self._str = (
"Unexpected method call. unexpected:- expected:+\n%s"
% ("\n".join(line.rstrip() for line in diff),)
)
def do_shell(tmpdir, action):
if action['cwd']:
cwd = action['file'].dirpath().join(action['cwd'])
else:
cwd = tmpdir
proc = subprocess.Popen(
action['target'],
shell=True,
cwd=str(cwd),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
out, err = proc.communicate()
out = strip_ansi_codes(out)
out = out.decode('ascii')
# XXX join with err?
if out != action['content']:
import difflib
differ = difflib.Differ()
outl = out.splitlines(True)
contl = action['content'].splitlines(True)
result = differ.compare(contl, outl)
printdiff(result)
return out
def __init__(self, unexpected_method, expected):
"""Init exception.
Args:
# unexpected_method: MockMethod that was called but was not at the head of
# the expected_method queue.
# expected: MockMethod or UnorderedGroup the method should have
# been in.
unexpected_method: MockMethod
expected: MockMethod or UnorderedGroup
"""
Error.__init__(self)
if expected is None:
self._str = "Unexpected method call %s" % (unexpected_method,)
else:
differ = difflib.Differ()
diff = differ.compare(str(unexpected_method).splitlines(True),
str(expected).splitlines(True))
self._str = ("Unexpected method call. unexpected:- expected:+\n%s"
% ("\n".join(diff),))
def diff(request, revision_id, other_revision_id=None):
revision = get_object_or_404(models.ArticleRevision, id=revision_id)
if not other_revision_id:
other_revision = revision.previous_revision
baseText = other_revision.content if other_revision else ""
newText = revision.content
differ = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
diff = differ.compare(baseText.splitlines(1), newText.splitlines(1))
other_changes = []
if not other_revision or other_revision.title != revision.title:
other_changes.append((_('New title'), revision.title))
return dict(diff=list(diff), other_changes=other_changes)
# TODO: Throw in a class-based view
def __init__(self, unexpected_method, expected):
"""Init exception.
Args:
# unexpected_method: MockMethod that was called but was not at the head of
# the expected_method queue.
# expected: MockMethod or UnorderedGroup the method should have
# been in.
unexpected_method: MockMethod
expected: MockMethod or UnorderedGroup
"""
Error.__init__(self)
if expected is None:
self._str = "Unexpected method call %s" % (unexpected_method,)
else:
differ = difflib.Differ()
diff = differ.compare(str(unexpected_method).splitlines(True),
str(expected).splitlines(True))
self._str = ("Unexpected method call. unexpected:- expected:+\n%s"
% ("\n".join(diff),))
def unified(fromlines, tolines, context):
"""Generate unified diff"""
diff = difflib.Differ().compare(fromlines, tolines)
lastrow = None
had_changes = 0
for row in _trim_context(diff, context):
if row[0].startswith("? "):
had_changes = 1
yield _differ_split(lastrow, row[0])
lastrow = None
else:
if lastrow:
had_changes = 1
yield _differ_split(lastrow, None)
lastrow = row
if lastrow:
had_changes = 1
yield _differ_split(lastrow, None)
if not had_changes:
yield _item(type=_RCSDIFF_NO_CHANGES)
def _dir_cmp(cmp, raise_exc=True):
if cmp.diff_files:
for file in cmp.diff_files:
with open(os.path.join(cmp.left, file), 'r') as left_fo, open(
os.path.join(cmp.right, file), 'r') as right_fo:
left = left_fo.readlines()
right = right_fo.readlines()
d = difflib.Differ()
diff = d.compare(left, right)
print('\n'.join(list(diff)))
if raise_exc:
raise ValueError(cmp.diff_files)
else:
return False
for sub_cmp in cmp.subdirs.values():
if not _dir_cmp(sub_cmp):
return False
else:
return True
def __init__(self, unexpected_method, expected):
"""Init exception.
Args:
# unexpected_method: MockMethod that was called but was not at the head of
# the expected_method queue.
# expected: MockMethod or UnorderedGroup the method should have
# been in.
unexpected_method: MockMethod
expected: MockMethod or UnorderedGroup
"""
Error.__init__(self)
if expected is None:
self._str = "Unexpected method call %s" % (unexpected_method,)
else:
differ = difflib.Differ()
diff = differ.compare(str(unexpected_method).splitlines(True),
str(expected).splitlines(True))
self._str = ("Unexpected method call. unexpected:- expected:+\n%s"
% ("\n".join(diff),))
def step_output_should_match_file(context, file_):
with open(os.path.join(current_dir, file_)) as output:
if file_.endswith('.json'):
context.output = json.loads(context.output)
output = json.load(output)
try:
eq_(context.output, output)
except AssertionError:
print(str(DictDiffer(context.output, output)))
raise
else:
context = list(map(str.strip, context.output.splitlines()))
expected_result = list(map(str.strip, output.readlines()))
try:
eq_(context, expected_result)
except AssertionError:
d = difflib.Differ()
for line in d.compare(context, expected_result):
print(line)
raise
def delta_contents(difflist):
"""
Generate a list of files which exist in the bundle image but not the base
image
'- ' - line unique to lhs
'+ ' - line unique to rhs
' ' - line common
'? ' - line not present in either
returns a list containing the items which are unique in the rhs
difflist --- a list containing the output of difflib.Differ.compare
where the lhs (left-hand-side) was the base image and the rhs
(right-hand-side) was base image + extras (the bundle image).
"""
cont = []
for ln in difflist:
if ln[0] == '+':
cont.append(ln[3:])
return cont
def schema_verifier(**args):
zk_prefix = SHARDED_DBS_PREFIX_MAP[args.instance_type]['zk_prefix']
seed_instance = HostAddr(args.seed_instance)
desired = show_create_table(seed_instance, args.seed_db, args.table)
tbl_hash = hashlib.md5(desired).hexdigest()
print("Desired table definition:\n{desired}").format(desired=desired)
incorrect = check_schema(zk_prefix, args.table, tbl_hash)
if len(incorrect) == 0:
print "It appears that all schema is synced"
sys.exit(0)
d = difflib.Differ()
for problem in incorrect.iteritems():
represenative = list(problem[1])[0].split(' ')
hostaddr = HostAddr(represenative[0])
create = show_create_table(hostaddr, represenative[1], args.table)
diff = d.compare(desired.splitlines(), create.splitlines())
print 'The following difference has been found:'
print '\n'.join(diff)
print "It is present on the following db's:"
print '\n'.join(list(problem[1]))
sys.exit(1)
def print_commit(commit, with_diff=False):
t = time.strftime("%a, %d %b %Y %H:%M", time.gmtime(commit.authored_date))
print(commit.hexsha, commit.author.name, t, commit.message)
print("stats:", commit.stats.total)
print()
if with_diff and len(commit.parents):
diffs = commit.diff(commit.parents[0])
for d in diffs:
print(d)
b_lines = str(d.b_blob.data_stream.read()).split()
a_lines = str(d.a_blob.data_stream.read()).split()
differ = difflib.Differ()
delta = differ.compare(b_lines, a_lines)
for i in delta:
print(i)
line_number = 0
for line in delta:
# split off the code
code = line[:2]
# if the line is in both files or just a, increment the
# line number.
if code in (" ", "+ "):
line_number += 1
# if this line is only in a, print the line number and
# the text on the line
if code == "+ ":
print("%d: %s" % (line_number, line[2:].strip()))
# print(b_lines)
# print(a_lines)
# dcont = list(difflib.unified_diff(
# b_lines, a_lines, d.b_path, d.a_path))
# for l in dcont:
# print(l)
print("------------------------")
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++")
print()
def print_file_diffs(self):
for name in self.diff_files:
if name.split('.') and name.split('.')[-1] in ['js', 'txt', 'html',
'json', 'css']:
d = difflib.Differ()
left_lines = open(os.path.join(self.left, name)).readlines()
right_lines = open(os.path.join(self.right, name)).readlines()
result = d.compare(left_lines, right_lines)
print("Diff between files {} and {}".format(
os.path.join(self.left, name),
os.path.join(self.right, name)))
print("")
sys.stdout.writelines(result)
else:
left_sha1 = hashlib.sha1(
open(os.path.join(self.left, name)).read()).hexdigest()
right_sha1 = hashlib.sha1(
open(os.path.join(self.right, name)).read()).hexdigest()
if left_sha1 != right_sha1:
print("Shasum mismatch between files {} and {}".format(
os.path.join(self.left, name),
os.path.join(self.right, name)))
for name in self.left_only:
print("Expected file {} not generated.".format(
os.path.join(self.left, name)))
for name in self.right_only:
print("Unexpected file {} generated.".format(
os.path.join(self.right, name)))
for name in self.funny_files:
print("Could not read the file {}".format(name))
def load(self, filename):
"""
Load the parameters for this network from disk.
:param filename: Load the parameters of this network from a pickle file at the named path. If this name ends in
".gz" then the input will automatically be gunzipped; otherwise the input will be treated as a "raw" pickle.
:return: None
"""
opener = gzip.open if filename.lower().endswith('.gz') else open
handle = opener(filename, 'rb')
saved = cPickle.load(handle)
handle.close()
if saved['network'] != self.__str__():
print "Possibly not matching network configuration!"
differences = list(difflib.Differ().compare(saved['network'].splitlines(), self.__str__().splitlines()))
print "Differences are:"
print "\n".join(differences)
for layer in self.layers:
if len(layer.params) != len(saved['{}-values'.format(layer.layerNum)]):
print "Warning: Layer parameters for layer {} do not match. Trying to fit on shape!".format(layer.layerNum)
n_assigned = 0
for p in layer.params:
for v in saved['{}-values'.format(layer.layerNum)]:
if p.get_value().shape == v.shape:
p.set_value(v)
n_assigned += 1
if n_assigned != len(layer.params):
raise ImportError("Could not load all necessary variables!")
else:
print "Found fitting parameters!"
else:
prms = layer.params
for p, v in zip(prms, saved['{}-values'.format(layer.layerNum)]):
if p.get_value().shape == v.shape:
p.set_value(v)
else:
print "WARNING: Skipping parameter for {}! Shape {} does not fit {}.".format(p.name, p.get_value().shape, v.shape)
print 'Loaded model parameters from {}'.format(filename)
def compute():
#open and read files compare using Lib Diff output to Tk
textbox.insert(END, "reading files please be patient... This may take a moment\n\n")
from difflib import Differ
filename1it = fil1.get()
filename1it2 = fil2.get()
filer = open(filename1it, 'rb')
filer2 = open(filename1it2, 'rb')
data1 = filer.read()
data2 = filer2.read()
d = Differ()
result = list(d.compare(data1, data2))
textbox.insert(END, "The two files compared with Difflib are " + filename1it + " and " + filename1it2 + "\n\n")
textbox.insert(END, result)
def compute():
from difflib import Differ
filename1it = fil1.get()
filename1it2 = fil2.get()
filer = open(filename1it, 'rb')
filer2 = open(filename1it2, 'rb')
data1 = filer.read()
data1 = data1.rstrip()
data2 = filer2.read()
data2 = data2.rstrip()
d = Differ()
result = list(d.compare(data1, data2))
s = "\n".join(result)
s = s.rstrip()
textbox.insert(END, "The two files compared with Difflib are " + filename1it + " and " + filename1it2 + "\n\n")
textbox.insert(END, s)
def diff(str1, str2):
"""Determine if two strings differ, emit differences to stdout."""
result = list(difflib.Differ().compare(
str1.splitlines(True), str2.splitlines(True)))
same = True
for line in result:
if line[0] in ('-', '+'):
same = False
sys.stdout.write(line)
return same
def print_diffs(expected, actual):
'''
Pretty-print the diff between the two, possibly multi-line, strings
:param str expected: Multi-line string
:param str actual: Multi-line string
'''
import difflib
from pprint import pprint
expected_lines = expected.splitlines()
actual_lines = actual.splitlines()
diff = difflib.Differ()
diff_list = list(diff.compare(expected_lines, actual_lines))
pprint(diff_list)
def getTextDiff(code1, code2):
differ = difflib.Differ()
changes = []
codeTokens1 = smartSplit(code1)
tokens1 = [t[0] for t in codeTokens1]
codeTokens2 = smartSplit(code2)
tokens2 = [t[0] for t in codeTokens2]
dif = differ.compare(tokens1, tokens2)
j = 0
type = ""
text = ""
line = 0
col = 0
totalCol = 0
for chr in dif:
changeType = chr[0]
changeChr = chr[2:]
if changeType != type or (len(text) > 0 and text[-1] == "\n"):
if text != "":
changes.append(SyntaxEdit(line, col, totalCol, type, text))
text = ""
type = changeType
if changeType in ["-", "+"]:
text = changeChr
if j < len(codeTokens1):
line = codeTokens1[j][1]
col = codeTokens1[j][2]
totalCol = codeTokens1[j][3]
else:
line = codeTokens1[j-1][1]
col = codeTokens1[j-1][2] + len(codeTokens1[j-1][0])
totalCol = codeTokens1[j-1][3] + len(codeTokens1[j-1][0])
else:
if changeType in ["-", "+"]:
text += changeChr
if changeType in ["-", " "]:
j += 1 # move forward in the codeTokens list
if text != "":
changes.append(SyntaxEdit(line, col, totalCol, type, text))
return changes
def text_compare(text1, text2, output_file):
"""
Compares two strings and if they match returns True
else writes the difference to the output_file.
"""
if text1 == text2:
return True
diff = list(difflib.Differ().compare(text1.split(), text2.split()))
te = open(output_file, 'w')
for line in diff:
te.write(line+"\n")
te.close()
return False
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
#return Differ(None, a, b).ratio()
def __init__(self, obj, snapshottest):
self.pretty = Formatter()
self.differ = Differ()
self.snapshottest = snapshottest
if isinstance(obj, dict):
obj = SortedDict(**obj)
self.obj = self.pretty(obj)
def is_pass(self, expected_results, actual_results, expected_similarity = 0.66):
"""Checks to see if a command execution passes.
If actual results compared to expected results is within
the expected similarity level then it's considered a pass.
Returns a dictionary containing the results:
{
"passed": boolean,
"command": "the command executed",
"results": "Results returned",
"expected_results": "Expected results",
"similarity": float,
"required_similarity": float
}
"""
differ = difflib.Differ()
comparison = differ.compare(actual_results, expected_results)
diff = differ.compare(actual_results, expected_results)
seq = difflib.SequenceMatcher(lambda x: x in " \t\n\r", actual_results, expected_results)
is_pass = seq.ratio() >= expected_similarity
self.ui.log("debug", "Similarity is: " + str(seq.ratio()))
message = {
"passed": is_pass,
"command": self.last_command,
"results": actual_results,
"expected_results": expected_results,
"similarity": seq.ratio(),
"required_similarity": expected_similarity
}
return message
def __check_equals(self, query):
"""Check if the query results on the two databases are equals.
Returns
-------
bool
True if the results are the same
False otherwise
list
A list with the differences
"""
self.cur1.execute(query)
records1 = self.cur1.fetchall()
self.cur2.execute(query)
records2 = self.cur2.fetchall()
result = True
differences = []
d = difflib.Differ()
records1 = [str(x) for x in records1]
records2 = [str(x) for x in records2]
for line in d.compare(records1, records2):
if line[0] in ('-', '+'):
result = False
if self.verbose_level == 1:
differences.append(line[0:79])
elif self.verbose_level == 2:
differences.append(line)
return result, differences
def test_added_tab_hint(self):
# Check fix for bug #1488943
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
self.assertEqual("- \tI am a buggy", diff[0])
self.assertEqual("? --\n", diff[1])
self.assertEqual("+ \t\tI am a bug", diff[2])
self.assertEqual("? +\n", diff[3])
def response_dif(response1,response2):
d=Differ()
diff = d.compare(response1, response2)
i=0
for el in diff:
if re.match(r'\+|-',el):
i+=1
return i
def test_added_tab_hint(self):
# Check fix for bug #1488943
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
self.assertEqual("- \tI am a buggy", diff[0])
self.assertEqual("? --\n", diff[1])
self.assertEqual("+ \t\tI am a bug", diff[2])
self.assertEqual("? +\n", diff[3])
def test_added_tab_hint(self):
# Check fix for bug #1488943
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
self.assertEqual("- \tI am a buggy", diff[0])
self.assertEqual("? --\n", diff[1])
self.assertEqual("+ \t\tI am a bug", diff[2])
self.assertEqual("? +\n", diff[3])
def __init__(self, source, proposal):
proposal = htmlescape(proposal)
differ = Differ()
self.diff = list(differ.compare(source.splitlines(1),
proposal.splitlines(1)))
def contentDiff( f1, f2 ) :
if 'text' in enabledModes :
differ = difflib.Differ()
f1_lines = f1['content'].decode('base64').splitlines()
f2_lines = f2['content'].decode('base64').splitlines()
diff = differ.compare( f1_lines, f2_lines )
__logger.info( '\n'.join( diff ) )
def test_added_tab_hint(self):
# Check fix for bug #1488943
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
self.assertEqual("- \tI am a buggy", diff[0])
self.assertEqual("? --\n", diff[1])
self.assertEqual("+ \t\tI am a bug", diff[2])
self.assertEqual("? +\n", diff[3])
def __init__(self, source, proposal):
proposal = htmlescape(proposal)
differ = Differ()
self.diff = list(differ.compare(source.splitlines(1),
proposal.splitlines(1)))
def load(self, filename):
"""
Load the parameters for this network from disk.
:param filename: Load the parameters of this network from a pickle file at the named path. If this name ends in
".gz" then the input will automatically be gunzipped; otherwise the input will be treated as a "raw" pickle.
:return: None
"""
if filename is None:
return
opener = gzip.open if filename.lower().endswith('.gz') else open
handle = opener(filename, 'rb')
saved = cPickle.load(handle)
handle.close()
if saved['network'] != self.__str__():
print "Possibly not matching network configuration!"
differences = list(difflib.Differ().compare(saved['network'].splitlines(), self.__str__().splitlines()))
print "Differences are:"
print "\n".join(differences)
for layer in self.layers:
if (len(layer.params) + len(layer.params_nontrained)) != len(saved['{}-values'.format(layer.layerNum)]):
print "Warning: Layer parameters for layer {} do not match. Trying to fit on shape!".format(layer.layerNum)
n_assigned = 0
for p in layer.params + layer.params_nontrained:
for v in saved['{}-values'.format(layer.layerNum)]:
if p.get_value().shape == v.shape:
p.set_value(v)
n_assigned += 1
if n_assigned != (len(layer.params) + len(layer.params_nontrained)):
raise ImportError("Could not load all necessary variables!")
else:
print "Found fitting parameters!"
else:
for p, v in zip(layer.params + layer.params_nontrained, saved['{}-values'.format(layer.layerNum)]):
if p.get_value().shape == v.shape:
p.set_value(v)
else:
print "WARNING: Skipping parameter for {}! Shape {} does not fit {}.".format(p.name, p.get_value().shape, v.shape)
print 'Loaded model parameters from {}'.format(filename)
def c(s, md, testcase, **kw):
print('\n\n%s\n' % ('=' * 40))
print('Testcase: %s' % testcase)
print('\n\n%s\n' % ('=' * 40))
md = dedent(md)
print('source (spaces as dots):')
print(md.replace(' ', '.'))
mdr, f = mdvl.main(md, no_print=True, **kw)
print('result:')
print(mdr)
if inspect:
return
fn = pth + '/tests/results/' + testcase
if record:
print ('recording %s' % testcase)
with open(fn, 'w') as fd:
fd.write(mdr)
return
with open(fn) as fd:
exp = fd.read()
if exp == mdr:
return
import difflib
d = difflib.Differ()
diff = d.compare(exp.splitlines(), mdr.splitlines())
print ('\n'.join(diff))
raise Exception('compare failed')
def test_added_tab_hint(self):
# Check fix for bug #1488943
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
self.assertEqual("- \tI am a buggy", diff[0])
self.assertEqual("? --\n", diff[1])
self.assertEqual("+ \t\tI am a bug", diff[2])
self.assertEqual("? +\n", diff[3])
def test_added_tab_hint(self):
# Check fix for bug #1488943
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
self.assertEqual("- \tI am a buggy", diff[0])
self.assertEqual("? --\n", diff[1])
self.assertEqual("+ \t\tI am a bug", diff[2])
self.assertEqual("? +\n", diff[3])
def test_added_tab_hint(self):
# Check fix for bug #1488943
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
self.assertEqual("- \tI am a buggy", diff[0])
self.assertEqual("? --\n", diff[1])
self.assertEqual("+ \t\tI am a bug", diff[2])
self.assertEqual("? +\n", diff[3])
def simple_merge(txt1, txt2):
"""Merges two texts"""
differ = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
diff = differ.compare(txt1.splitlines(1), txt2.splitlines(1))
content = "".join([l[2:] for l in diff])
return content
def run(bot, sess):
subs = sess.query(SiteSub).all()
for sub in subs: # type: SiteSub
async with aiohttp.ClientSession() as session:
try:
async with session.get(sub.url) as res:
new_body: str = await res.text()
if sub.body != new_body:
old_body_lines = sub.body.splitlines(keepends=True)
new_body_lines = new_body.splitlines(keepends=True)
d = Differ()
diff = [
SPACE_RE.sub(' ', x).rstrip() for x in d.compare(
old_body_lines,
new_body_lines
)
if x[0] not in [' ', '?']
]
await bot.say(
sub.user,
'`{}` ?? ??? ?????!\n```\n{}\n```'.format(
sub.url,
'\n'.join(diff),
)
)
sub.body = new_body
with sess.begin():
sess.add(sub)
except aiohttp.client_exceptions.ClientConnectorError:
await bot.say(
sub.user,
f'`{sub.url}` ? ??? ? ???!'
)
def get_diff(a, b):
import difflib
a, b = a.split('\n'), b.split('\n')
diff = difflib.Differ().compare(a, b)
return '\n'.join(diff)
def _get_diff(a, b):
a, b = a.split('\n'), b.split('\n')
diff = difflib.Differ().compare(a, b)
return '\n'.join(diff)
def _set_diffs(self):
differ = difflib.Differ()
self.lines = []
lineno = 0
for line in differ.compare(self.old.splitlines(True),
self.new.splitlines(True)):
if line.startswith(' '):
lineno += 1
elif line.startswith('-'):
lineno += 1
self.lines.append(lineno)
def test_added_tab_hint(self):
# Check fix for bug #1488943
diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
self.assertEqual("- \tI am a buggy", diff[0])
self.assertEqual("? --\n", diff[1])
self.assertEqual("+ \t\tI am a bug", diff[2])
self.assertEqual("? +\n", diff[3])
def highlight_changes(s1, s2):
"""Highlight words that are changed."""
# pylint: disable=invalid-name
l1 = s1.split(' ')
l2 = s2.split(' ')
dif = list(Differ().compare(l1, l2))
return " ".join(["\033[1m" + i[2:] + "\033[0m" if i[:1] == "+" else i[2:]
for i in dif if not i[:1] in "-?"])
def _set_diffs(self):
differ = difflib.Differ()
self.lines = []
lineno = 0
for line in differ.compare(self.old.splitlines(True),
self.new.splitlines(True)):
if line.startswith(' '):
lineno += 1
elif line.startswith('-'):
lineno += 1
self.lines.append(lineno)
def _set_diffs(self):
differ = difflib.Differ()
self.lines = []
lineno = 0
for line in differ.compare(self.old.splitlines(True),
self.new.splitlines(True)):
if line.startswith(' '):
lineno += 1
elif line.startswith('-'):
lineno += 1
self.lines.append(lineno)
def unique_contents(base_manifest_fn, image_manifest_fn):
"""
Get a list of files unique to the bundle image
Compare the bundle image manifest to the base image manifest and return
a list of files unique to the bundle image.
base_manifest_fn -- the base image manifest
image_manifest_fn -- the bundle image manifest
"""
import difflib
differ = difflib.Differ()
base_manifest_list = []
with open(base_manifest_fn) as base:
base_manifest_list = base.read().splitlines()
image_manifest_list = []
with open(image_manifest_fn) as image:
image_manifest_list = image.read().splitlines()
delta = list(differ.compare(base_manifest_list, image_manifest_list))
return delta_contents(delta)
# FIXME: Mariano proposed a similar method to OE-Core for package_manager
def output_difference(self, example, got, optionflags):
"""
Return a string describing the differences between the
expected output for a given example (`example`) and the actual
output (`got`). `optionflags` is the set of option flags used
to compare `want` and `got`.
"""
want = example.want
# If <BLANKLINE>s are being used, then replace blank lines
# with <BLANKLINE> in the actual output string.
if not (optionflags & DONT_ACCEPT_BLANKLINE):
got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got)
# Check if we should use diff.
if self._do_a_fancy_diff(want, got, optionflags):
# Split want & got into lines.
want_lines = want.splitlines(True) # True == keep line ends
got_lines = got.splitlines(True)
# Use difflib to find their differences.
if optionflags & REPORT_UDIFF:
diff = difflib.unified_diff(want_lines, got_lines, n=2)
diff = list(diff)[2:] # strip the diff header
kind = 'unified diff with -expected +actual'
elif optionflags & REPORT_CDIFF:
diff = difflib.context_diff(want_lines, got_lines, n=2)
diff = list(diff)[2:] # strip the diff header
kind = 'context diff with expected followed by actual'
elif optionflags & REPORT_NDIFF:
engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
diff = list(engine.compare(want_lines, got_lines))
kind = 'ndiff with -expected +actual'
else:
assert 0, 'Bad diff option'
# Remove trailing whitespace on diff output.
diff = [line.rstrip() + '\n' for line in diff]
return 'Differences (%s):\n' % kind + _indent(''.join(diff))
# If we're not using diff, then simply list the expected
# output followed by the actual output.
if want and got:
return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got))
elif want:
return 'Expected:\n%sGot nothing\n' % _indent(want)
elif got:
return 'Expected nothing\nGot:\n%s' % _indent(got)
else:
return 'Expected nothing\nGot nothing\n'