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