Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e7dfe21

Browse files
committed
Fix SF bug #763023, difflib.py: ratio() zero division not caught
Backport candidate
1 parent 37ca8c1 commit e7dfe21

3 files changed

Lines changed: 23 additions & 3 deletions

File tree

Lib/difflib.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff',
3030
'unified_diff']
3131

32+
def _calculate_ratio(matches, length):
33+
if length:
34+
return 2.0 * matches / length
35+
return 1.0
36+
3237
class SequenceMatcher:
3338

3439
"""
@@ -611,7 +616,7 @@ def ratio(self):
611616

612617
matches = reduce(lambda sum, triple: sum + triple[-1],
613618
self.get_matching_blocks(), 0)
614-
return 2.0 * matches / (len(self.a) + len(self.b))
619+
return _calculate_ratio(matches, len(self.a) + len(self.b))
615620

616621
def quick_ratio(self):
617622
"""Return an upper bound on ratio() relatively quickly.
@@ -640,7 +645,7 @@ def quick_ratio(self):
640645
avail[elt] = numb - 1
641646
if numb > 0:
642647
matches = matches + 1
643-
return 2.0 * matches / (len(self.a) + len(self.b))
648+
return _calculate_ratio(matches, len(self.a) + len(self.b))
644649

645650
def real_quick_ratio(self):
646651
"""Return an upper bound on ratio() very quickly.
@@ -652,7 +657,7 @@ def real_quick_ratio(self):
652657
la, lb = len(self.a), len(self.b)
653658
# can't have more matches than the number of elements in the
654659
# shorter sequence
655-
return 2.0 * min(la, lb) / (la + lb)
660+
return _calculate_ratio(min(la, lb), la + lb)
656661

657662
def get_close_matches(word, possibilities, n=3, cutoff=0.6):
658663
"""Use SequenceMatcher to return list of the best "good enough" matches.

Lib/test/test_difflib.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
import difflib
22
from test import test_support
3+
import unittest
4+
5+
class TestSFbugs(unittest.TestCase):
6+
7+
def test_ratio_for_null_seqn(self):
8+
# Check clearing of SF bug 763023
9+
s = difflib.SequenceMatcher(None, [], [])
10+
self.assertEqual(s.ratio(), 1)
11+
self.assertEqual(s.quick_ratio(), 1)
12+
self.assertEqual(s.real_quick_ratio(), 1)
13+
14+
test_support.run_unittest(TestSFbugs)
315
test_support.run_doctest(difflib)

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ Extension modules
2424
Library
2525
-------
2626

27+
- SF bug 763023: fix uncaught ZeroDivisionError in difflib ratio methods
28+
when there are no lines.
29+
2730
Tools/Demos
2831
-----------
2932

0 commit comments

Comments
 (0)