Given a QueryRun, yield more query runs broken down on boundaries discovered from matched rules and matched rule starts and ends.
(query_run)
| 653 | |
| 654 | |
| 655 | def break_on_boundaries(query_run): |
| 656 | """ |
| 657 | Given a QueryRun, yield more query runs broken down on boundaries discovered |
| 658 | from matched rules and matched rule starts and ends. |
| 659 | """ |
| 660 | if len(query_run) < 150: |
| 661 | yield query_run |
| 662 | else: |
| 663 | from licensedcode.match_aho import get_matched_starts |
| 664 | |
| 665 | qr_tokens = query_run.tokens |
| 666 | qr_start = query_run.start |
| 667 | qr_end = query_run.end |
| 668 | query = query_run.query |
| 669 | idx = query.idx |
| 670 | |
| 671 | matched_starts = get_matched_starts( |
| 672 | qr_tokens, qr_start, automaton=idx.starts_automaton) |
| 673 | |
| 674 | starts = dict(matched_starts) |
| 675 | |
| 676 | if TRACE_QR_BREAK: |
| 677 | logger_debug('break_on_boundaries: len(starts):', len(starts),) |
| 678 | |
| 679 | if not starts: |
| 680 | if TRACE_QR_BREAK: logger_debug('break_on_boundaries: Qr returned unchanged') |
| 681 | yield query_run |
| 682 | |
| 683 | else: |
| 684 | positions = deque() |
| 685 | pos = qr_start |
| 686 | while pos < qr_end: |
| 687 | matches = starts.get(pos, None) |
| 688 | if matches: |
| 689 | min_length, _ridentifier = matches[0] |
| 690 | if len(positions) >= min_length: |
| 691 | qr = QueryRun(query, positions[0], positions[-1]) |
| 692 | if TRACE_QR_BREAK: |
| 693 | logger_debug('\nbreak_on_boundaries: new QueryRun', qr, '\n', matches, '\n') |
| 694 | yield qr |
| 695 | positions.clear() |
| 696 | positions.append(pos) |
| 697 | pos += 1 |
| 698 | |
| 699 | if positions: |
| 700 | qr = QueryRun(query, positions[0], positions[-1]) |
| 701 | yield qr |
| 702 | if TRACE_QR_BREAK: |
| 703 | print() |
| 704 | logger_debug('\nbreak_on_boundaries: final QueryRun', qr, '\n', matches, '\n') |
| 705 | |
| 706 | |
| 707 | is_only_digit_and_punct = re.compile('^[^A-Za-z]+$').match |
no test coverage detected