summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal Norwitz <nnorwitz@gmail.com>2003-07-01 14:59:46 (GMT)
committerNeal Norwitz <nnorwitz@gmail.com>2003-07-01 14:59:46 (GMT)
commite7dfe21bed410baff8191aebd679f647c9e95a0a (patch)
treefd5391274e451d0b05dec84624ca1062fb2f93dc
parent37ca8c12dc0fb34736749d1224e1e013f4afd5b4 (diff)
downloadcpython-e7dfe21bed410baff8191aebd679f647c9e95a0a.zip
cpython-e7dfe21bed410baff8191aebd679f647c9e95a0a.tar.gz
cpython-e7dfe21bed410baff8191aebd679f647c9e95a0a.tar.bz2
Fix SF bug #763023, difflib.py: ratio() zero division not caught
Backport candidate
-rw-r--r--Lib/difflib.py11
-rw-r--r--Lib/test/test_difflib.py12
-rw-r--r--Misc/NEWS3
3 files changed, 23 insertions, 3 deletions
diff --git a/Lib/difflib.py b/Lib/difflib.py
index 198114d..eb0eccf 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -29,6 +29,11 @@ __all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher',
'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff',
'unified_diff']
+def _calculate_ratio(matches, length):
+ if length:
+ return 2.0 * matches / length
+ return 1.0
+
class SequenceMatcher:
"""
@@ -611,7 +616,7 @@ class SequenceMatcher:
matches = reduce(lambda sum, triple: sum + triple[-1],
self.get_matching_blocks(), 0)
- return 2.0 * matches / (len(self.a) + len(self.b))
+ return _calculate_ratio(matches, len(self.a) + len(self.b))
def quick_ratio(self):
"""Return an upper bound on ratio() relatively quickly.
@@ -640,7 +645,7 @@ class SequenceMatcher:
avail[elt] = numb - 1
if numb > 0:
matches = matches + 1
- return 2.0 * matches / (len(self.a) + len(self.b))
+ return _calculate_ratio(matches, len(self.a) + len(self.b))
def real_quick_ratio(self):
"""Return an upper bound on ratio() very quickly.
@@ -652,7 +657,7 @@ class SequenceMatcher:
la, lb = len(self.a), len(self.b)
# can't have more matches than the number of elements in the
# shorter sequence
- return 2.0 * min(la, lb) / (la + lb)
+ return _calculate_ratio(min(la, lb), la + lb)
def get_close_matches(word, possibilities, n=3, cutoff=0.6):
"""Use SequenceMatcher to return list of the best "good enough" matches.
diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py
index 5687e32..e33539a 100644
--- a/Lib/test/test_difflib.py
+++ b/Lib/test/test_difflib.py
@@ -1,3 +1,15 @@
import difflib
from test import test_support
+import unittest
+
+class TestSFbugs(unittest.TestCase):
+
+ def test_ratio_for_null_seqn(self):
+ # Check clearing of SF bug 763023
+ s = difflib.SequenceMatcher(None, [], [])
+ self.assertEqual(s.ratio(), 1)
+ self.assertEqual(s.quick_ratio(), 1)
+ self.assertEqual(s.real_quick_ratio(), 1)
+
+test_support.run_unittest(TestSFbugs)
test_support.run_doctest(difflib)
diff --git a/Misc/NEWS b/Misc/NEWS
index 76ec673..d3761f9 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -24,6 +24,9 @@ Extension modules
Library
-------
+- SF bug 763023: fix uncaught ZeroDivisionError in difflib ratio methods
+ when there are no lines.
+
Tools/Demos
-----------