Essentially the only subtle case: >>> _ellipsis_match('aa...aa', 'aaa') False
(want, got)
| 290 | |
| 291 | # Worst-case linear-time ellipsis matching. |
| 292 | def _ellipsis_match(want, got): |
| 293 | """ |
| 294 | Essentially the only subtle case: |
| 295 | >>> _ellipsis_match('aa...aa', 'aaa') |
| 296 | False |
| 297 | """ |
| 298 | if ELLIPSIS_MARKER not in want: |
| 299 | return want == got |
| 300 | |
| 301 | # Find "the real" strings. |
| 302 | ws = want.split(ELLIPSIS_MARKER) |
| 303 | assert len(ws) >= 2 |
| 304 | |
| 305 | # Deal with exact matches possibly needed at one or both ends. |
| 306 | startpos, endpos = 0, len(got) |
| 307 | w = ws[0] |
| 308 | if w: # starts with exact match |
| 309 | if got.startswith(w): |
| 310 | startpos = len(w) |
| 311 | del ws[0] |
| 312 | else: |
| 313 | return False |
| 314 | w = ws[-1] |
| 315 | if w: # ends with exact match |
| 316 | if got.endswith(w): |
| 317 | endpos -= len(w) |
| 318 | del ws[-1] |
| 319 | else: |
| 320 | return False |
| 321 | |
| 322 | if startpos > endpos: |
| 323 | # Exact end matches required more characters than we have, as in |
| 324 | # _ellipsis_match('aa...aa', 'aaa') |
| 325 | return False |
| 326 | |
| 327 | # For the rest, we only need to find the leftmost non-overlapping |
| 328 | # match for each piece. If there's no overall match that way alone, |
| 329 | # there's no overall match period. |
| 330 | for w in ws: |
| 331 | # w may be '' at times, if there are consecutive ellipses, or |
| 332 | # due to an ellipsis at the start or end of `want`. That's OK. |
| 333 | # Search for an empty string succeeds, and doesn't change startpos. |
| 334 | startpos = got.find(w, startpos, endpos) |
| 335 | if startpos < 0: |
| 336 | return False |
| 337 | startpos += len(w) |
| 338 | |
| 339 | return True |
| 340 | |
| 341 | def _comment_line(line): |
| 342 | "Return a commented form of the given line" |
no test coverage detected
searching dependent graphs…