Path 1: 1181 calls (0.33)

21 (60) 6 (29) 1 (27) 3 (23) 0 (16) 13 (6) 16 (5) 31 (4) 9 (4) 5 (3)

23 (55) 4 (24) 10 (22) 2 (16) 1 (11) 7 (11) 5 (8) 3 (8) 35 (6) 22 (6)

21 (54) 6 (29) 1 (25) 3 (22) 0 (16) 13 (9) 9 (7) 2 (6) 16 (5) 31 (4)

23 (55) 7 (29) 4 (24) 2 (15) 1 (12) 14 (9) 5 (8) 3 (8) 10 (7) 35 (5)

Match (1181)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 2: 1011 calls (0.28)

0 (10) 6 (2) 2 (1) 4 (1) 8 (1) 10 (1) 12 (1) 14 (1) 16 (1) 18 (1)

2000 (999) 45 (4) 39 (3) 41 (3) 10 (2)

0 (10) 6 (2) 20 (2) 2 (1) 4 (1) 8 (1) 10 (1) 12 (1) 14 (1) 16 (1)

2000 (999) 45 (4) 41 (3) 10 (2) 35 (2) 38 (1)

Match (1011)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 3: 137 calls (0.04)

40 (38) 23 (36) 13 (34) 46 (6) 34 (4) 38 (4) 48 (4) 57 (3) 54 (3) 29 (2)

41 (38) 27 (36) 15 (34) 55 (7) 43 (4) 48 (4) 60 (4) 58 (4) 31 (2) 47 (2)

25 (36) 17 (36) 15 (34) 34 (8) 40 (8) 38 (4) 42 (3) 48 (3) 29 (2) 39 (2)

41 (40) 29 (36) 17 (34) 43 (11) 50 (9) 48 (4) 31 (2) 101 (1)

Match (137)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 4: 110 calls (0.03)

16 (102) 5 (6) 29 (2)

36 (52) 30 (51) 14 (6) 40 (1)

16 (102) 5 (6) 29 (2)

36 (51) 30 (51) 14 (6) 35 (2)

Match (110)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 5: 108 calls (0.03)

0 (106) 5 (2)

5 (88) 16 (18) 11 (2)

0 (106) 5 (2)

5 (54) 7 (34) 13 (18) 11 (2)

Match (108)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 6: 103 calls (0.03)

0 (103)

27 (36) 30 (36) 23 (11) 35 (9) 25 (5) 13 (4) 8 (2)

0 (103)

29 (36) 7 (36) 23 (8) 15 (7) 25 (6) 13 (4) 27 (4) 10 (2)

Match (103)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 7: 102 calls (0.03)

21 (54) 29 (18) 13 (12) 31 (7) 33 (4) 11 (3) 14 (3) 41 (1)

25 (54) 41 (21) 16 (18) 45 (4) 36 (3) 55 (1) 39 (1)

21 (54) 26 (18) 13 (12) 31 (7) 11 (3) 14 (3) 37 (3) 41 (1) 34 (1)

25 (54) 33 (18) 16 (18) 45 (4) 36 (3) 41 (3) 55 (1) 38 (1)

Match (102)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 8: 102 calls (0.03)

0 (102)

36 (55) 41 (20) 55 (7) 43 (4) 48 (4) 60 (4) 58 (4) 47 (2) 50 (1) 40 (1)

0 (102)

36 (54) 33 (18) 43 (11) 50 (9) 48 (4) 41 (4) 35 (2)

Match (102)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 9: 85 calls (0.02)

16 (54) 24 (18) 5 (3) 25 (2) 34 (2) 21 (2) 31 (2) 40 (2)

25 (54) 41 (22) 47 (4) 22 (3) 36 (1) 40 (1)

16 (54) 21 (20) 25 (4) 34 (4) 5 (3)

25 (54) 33 (18) 41 (8) 22 (3) 35 (2)

Match (85)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 10: 69 calls (0.02)

0 (32) 33 (15) 5 (6) 23 (5) 21 (4) 2 (3) 13 (2) 40 (1) 3 (1)

35 (15) 2 (12) 6 (7) 4 (7) 3 (5) 5 (5) 25 (5) 23 (4) 45 (2) 15 (2)

0 (32) 21 (11) 25 (7) 23 (6) 5 (6) 2 (3) 15 (2) 40 (1) 3 (1)

23 (11) 4 (8) 27 (7) 2 (6) 25 (6) 6 (6) 1 (6) 3 (4) 9 (3) 5 (3)

Match (69)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 11: 64 calls (0.02)

6 (36) 21 (9) 42 (6) 11 (5) 9 (4) 5 (2) 0 (2)

30 (36) 23 (9) 13 (5) 11 (4) 46 (3) 45 (3) 7 (2) 4 (2)

6 (36) 9 (8) 11 (6) 13 (4) 30 (3) 34 (3) 5 (2) 0 (2)

7 (38) 11 (8) 13 (6) 15 (4) 31 (3) 39 (3) 6 (2)

Match (64)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 12: 57 calls (0.02)

19 (54) 33 (3)

25 (54) 39 (3)

19 (54) 37 (3)

25 (54) 39 (3)

Match (57)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 13: 48 calls (0.01)

29 (19) 13 (6) 8 (6) 11 (3) 14 (3) 21 (3) 31 (3) 38 (3) 33 (1) 2 (1)

37 (19) 15 (12) 9 (6) 22 (3) 32 (3) 39 (3) 30 (1) 5 (1)

26 (18) 13 (6) 8 (6) 11 (3) 14 (3) 21 (3) 31 (3) 38 (3) 34 (1) 29 (1)

29 (18) 15 (12) 9 (6) 22 (3) 32 (3) 39 (3) 36 (1) 31 (1) 5 (1)

Match (48)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 14: 46 calls (0.01)

0 (37) 5 (9)

2 (15) 7 (9) 5 (8) 6 (3) 16 (3) 4 (3) 55 (1) 81 (1) 100 (1) 13 (1)

0 (37) 5 (9)

2 (15) 7 (9) 5 (7) 4 (5) 6 (3) 16 (3) 55 (1) 80 (1) 101 (1) 13 (1)

Match (46)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 15: 40 calls (0.01)

0 (40)

36 (36) 28 (3) 29 (1)

0 (40)

38 (37) 28 (3)

Match (40)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 16: 36 calls (0.01)

0 (36)

41 (36)

0 (36)

41 (36)

Match (36)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 17: 34 calls (0.01)

13 (34)

27 (34)

15 (34)

29 (34)

Match (34)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 18: 31 calls (0.01)

0 (31)

4 (22) 16 (4) 12 (4) 6 (1)

0 (31)

4 (29) 6 (2)

Match (31)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 19: 28 calls (0.01)

2 (13) 0 (11) 9 (4)

16 (10) 4 (8) 12 (7) 10 (2) 6 (1)

2 (13) 0 (11) 9 (4)

4 (22) 10 (4) 6 (2)

Match (28)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 20: 26 calls (0.01)

0 (18) 3 (2) 1 (2) 1998 (1) 34 (1) 19 (1) 2 (1)

4 (11) 6 (8) 36 (2) 2000 (1) 13 (1) 39 (1) 27 (1) 5 (1)

0 (18) 2 (4) 1998 (1) 3 (1) 30 (1) 20 (1)

4 (11) 5 (7) 38 (2) 6 (2) 2000 (1) 13 (1) 35 (1) 23 (1)

Match (26)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 21: 25 calls (0.01)

11 (21) 7 (2) 5 (1) 0 (1)

13 (18) 12 (3) 8 (2) 7 (1) 2 (1)

8 (18) 15 (3) 9 (2) 5 (1) 0 (1)

10 (21) 16 (3) 2 (1)

Match (25)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 22: 21 calls (0.01)

5 (12) 33 (6) 10 (3)

16 (12) 60 (3) 55 (3) 22 (3)

5 (12) 21 (3) 25 (3) 10 (3)

16 (12) 43 (3) 50 (3) 22 (3)

Match (21)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 23: 20 calls (0.01)

0 (20)

13 (18) 15 (2)

0 (20)

10 (18) 17 (2)

Match (20)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 24: 19 calls (0.01)

6 (18) 5 (1)

13 (19)

6 (18) 5 (1)

10 (18) 13 (1)

Match (19)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 25: 18 calls (0.0)

0 (18)

16 (12) 14 (6)

0 (18)

16 (12) 14 (6)

Match (18)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 26: 17 calls (0.0)

0 (13) 5 (4)

7 (3) 22 (3) 13 (2) 10 (2) 11 (2) 19 (2) 16 (2) 14 (1)

0 (13) 5 (4)

13 (4) 10 (4) 7 (3) 22 (3) 11 (2) 23 (1)

Match (17)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 27: 16 calls (0.0)

16 (4) 3 (3) 5 (3) 9 (3) 11 (1) 26 (1) 29 (1)

16 (9) 45 (4) 55 (2) 39 (1)

16 (4) 3 (3) 5 (3) 9 (3) 11 (1) 26 (1) 29 (1)

16 (9) 45 (4) 55 (2) 38 (1)

Match (16)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 28: 13 calls (0.0)

0 (8) 10 (3) 6 (2)

12 (6) 5 (4) 8 (2) 13 (1)

0 (8) 10 (3) 6 (2)

16 (6) 5 (4) 10 (2) 13 (1)

Match (13)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 29: 13 calls (0.0)

0 (13)

23 (8) 11 (4) 13 (1)

0 (13)

11 (11) 13 (2)

Match (13)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 30: 9 calls (0.0)

21 (6) 42 (3)

23 (6) 48 (3)

30 (3) 9 (3) 13 (3)

33 (3) 11 (3) 15 (3)

Match (9)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 31: 6 calls (0.0)

33 (6)

48 (3) 45 (3)

21 (3) 25 (3)

33 (3) 39 (3)

Match (6)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 32: 6 calls (0.0)

5 (6)

9 (6)

5 (6)

9 (6)

Match (6)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 33: 5 calls (0.0)

0 (5)

0 (5)

0 (5)

0 (5)

Match (5)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 34: 4 calls (0.0)

5 (4)

13 (2) 19 (2)

5 (4)

13 (4)

Match (4)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 35: 4 calls (0.0)

10 (3) 8 (1)

12 (3) 14 (1)

10 (3) 8 (1)

12 (3) 23 (1)

Match (4)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 36: 3 calls (0.0)

0 (3)

16 (3)

0 (3)

16 (3)

Match (3)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 37: 3 calls (0.0)

10 (3)

16 (3)

10 (3)

16 (3)

Match (3)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 38: 3 calls (0.0)

16 (3)

36 (3)

16 (3)

36 (3)

Match (3)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 39: 1 calls (0.0)

0 (1)

None (1)

0 (1)

None (1)

Match (1)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 40: 1 calls (0.0)

2 (1)

None (1)

4 (1)

None (1)

Match (1)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 41: 1 calls (0.0)

0 (1)

None (1)

1 (1)

5 (1)

Match (1)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 42: 1 calls (0.0)

0 (1)

5 (1)

0 (1)

203 (1)

Match (1)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 43: 1 calls (0.0)

2 (1)

13 (1)

2 (1)

13 (1)

Match (1)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)
            

Path 44: 1 calls (0.0)

9 (1)

13 (1)

12 (1)

13 (1)

Match (1)

1def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
2        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
3
4        By default it will find the longest match in the entirety of a and b.
5
6        If isjunk is not defined:
7
8        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
9            alo <= i <= i+k <= ahi
10            blo <= j <= j+k <= bhi
11        and for all (i',j',k') meeting those conditions,
12            k >= k'
13            i <= i'
14            and if i == i', j <= j'
15
16        In other words, of all maximal matching blocks, return one that
17        starts earliest in a, and of all those maximal matching blocks that
18        start earliest in a, return the one that starts earliest in b.
19
20        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
21        >>> s.find_longest_match(0, 5, 0, 9)
22        Match(a=0, b=4, size=5)
23
24        If isjunk is defined, first the longest matching block is
25        determined as above, but with the additional restriction that no
26        junk element appears in the block.  Then that block is extended as
27        far as possible by matching (only) junk elements on both sides.  So
28        the resulting block never matches on junk except as identical junk
29        happens to be adjacent to an "interesting" match.
30
31        Here's the same example as before, but considering blanks to be
32        junk.  That prevents " abcd" from matching the " abcd" at the tail
33        end of the second sequence directly.  Instead only the "abcd" can
34        match, and matches the leftmost "abcd" in the second sequence:
35
36        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
37        >>> s.find_longest_match(0, 5, 0, 9)
38        Match(a=1, b=0, size=4)
39
40        If no blocks match, return (alo, blo, 0).
41
42        >>> s = SequenceMatcher(None, "ab", "c")
43        >>> s.find_longest_match(0, 2, 0, 1)
44        Match(a=0, b=0, size=0)
45        """
46
47        # CAUTION:  stripping common prefix or suffix would be incorrect.
48        # E.g.,
49        #    ab
50        #    acab
51        # Longest matching block is "ab", but if common prefix is
52        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
53        # strip, so ends up claiming that ab is changed to acab by
54        # inserting "ca" in the middle.  That's minimal but unintuitive:
55        # "it's obvious" that someone inserted "ac" at the front.
56        # Windiff ends up at the same place as diff, but by pairing up
57        # the unique 'b's and then matching the first two 'a's.
58
59        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__
60        if ahi is None:
61            ahi = len(a)
62        if bhi is None:
63            bhi = len(b)
64        besti, bestj, bestsize = alo, blo, 0
65        # find longest junk-free match
66        # during an iteration of the loop, j2len[j] = length of longest
67        # junk-free match ending with a[i-1] and b[j]
68        j2len = {}
69        nothing = []
70        for i in range(alo, ahi):
71            # look at all instances of a[i] in b; note that because
72            # b2j has no junk keys, the loop is skipped if a[i] is junk
73            j2lenget = j2len.get
74            newj2len = {}
75            for j in b2j.get(a[i], nothing):
76                # a[i] matches b[j]
77                if j < blo:
78                    continue
79                if j >= bhi:
80                    break
81                k = newj2len[j] = j2lenget(j-1, 0) + 1
82                if k > bestsize:
83                    besti, bestj, bestsize = i-k+1, j-k+1, k
84            j2len = newj2len
85
86        # Extend the best by non-junk elements on each end.  In particular,
87        # "popular" non-junk elements aren't in b2j, which greatly speeds
88        # the inner loop above, but also means "the best" match so far
89        # doesn't contain any junk *or* popular non-junk elements.
90        while besti > alo and bestj > blo and \
91              not isbjunk(b[bestj-1]) and \
92              a[besti-1] == b[bestj-1]:
93            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
94        while besti+bestsize < ahi and bestj+bestsize < bhi and \
95              not isbjunk(b[bestj+bestsize]) and \
96              a[besti+bestsize] == b[bestj+bestsize]:
97            bestsize += 1
98
99        # Now that we have a wholly interesting match (albeit possibly
100        # empty!), we may as well suck up the matching junk on each
101        # side of it too.  Can't think of a good reason not to, and it
102        # saves post-processing the (possibly considerable) expense of
103        # figuring out what to do with it.  In the case of an empty
104        # interesting match, this is clearly the right thing to do,
105        # because no other kind of match is possible in the regions.
106        while besti > alo and bestj > blo and \
107              isbjunk(b[bestj-1]) and \
108              a[besti-1] == b[bestj-1]:
109            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
110        while besti+bestsize < ahi and bestj+bestsize < bhi and \
111              isbjunk(b[bestj+bestsize]) and \
112              a[besti+bestsize] == b[bestj+bestsize]:
113            bestsize = bestsize + 1
114
115        return Match(besti, bestj, bestsize)