|
154 | 154 | import os |
155 | 155 | import re |
156 | 156 | import sys |
157 | | -import types |
158 | 157 |
|
159 | 158 | __all__ = ("NoSectionError", "DuplicateOptionError", "DuplicateSectionError", |
160 | 159 | "NoOptionError", "InterpolationError", "InterpolationDepthError", |
@@ -574,19 +573,30 @@ def value(self): |
574 | 573 | def value(self, string): |
575 | 574 | self._value = string |
576 | 575 | string = string.strip() |
577 | | - self.clean = self._strip_full(string) and self._strip_inline(string) |
| 576 | + self.clean = self.comments.strip(string) |
578 | 577 | self.has_comments = string != self.clean |
579 | 578 |
|
580 | | - def _strip_full(self, string): |
581 | | - return '' if any(map(string.startswith, self.comments.full)) else True |
582 | 579 |
|
583 | | - def _strip_inline(self, string): |
584 | | - match = None |
585 | | - if self.comments.inline: |
586 | | - match = self.comments.inline.search(string) |
587 | | - if match: |
588 | | - return string[:match.start()].rstrip() |
589 | | - return string |
| 580 | +class _CommentSpec: |
| 581 | + def __init__(self, full_prefixes, inline_prefixes): |
| 582 | + if not full_prefixes and not inline_prefixes: |
| 583 | + # performance optimization when no prefixes (gh-128641) |
| 584 | + self.strip = lambda text: text |
| 585 | + return |
| 586 | + full_patterns = ( |
| 587 | + # prefix at the beginning of a line |
| 588 | + fr'^({re.escape(prefix)}).*' |
| 589 | + for prefix in full_prefixes |
| 590 | + ) |
| 591 | + inline_patterns = ( |
| 592 | + # prefix at the beginning of the line or following a space |
| 593 | + fr'(^|\s)({re.escape(prefix)}.*)' |
| 594 | + for prefix in inline_prefixes |
| 595 | + ) |
| 596 | + self.pattern = re.compile('|'.join(itertools.chain(full_patterns, inline_patterns))) |
| 597 | + |
| 598 | + def strip(self, text): |
| 599 | + return self.pattern.sub('', text).rstrip() |
590 | 600 |
|
591 | 601 |
|
592 | 602 | class RawConfigParser(MutableMapping): |
@@ -655,15 +665,7 @@ def __init__(self, defaults=None, dict_type=_default_dict, |
655 | 665 | else: |
656 | 666 | self._optcre = re.compile(self._OPT_TMPL.format(delim=d), |
657 | 667 | re.VERBOSE) |
658 | | - # prefix at the beginning of the line or following a space |
659 | | - inline_tmpl = lambda prefix: fr'(^|\s)({re.escape(prefix)})' |
660 | | - inline_comm = '|'.join(map(inline_tmpl, inline_comment_prefixes or ())) |
661 | | - # optional cre used with _LineParser for best performance (gh-128641) |
662 | | - inline_comment_cre = re.compile(inline_comm) if inline_comm else None |
663 | | - self._comments = types.SimpleNamespace( |
664 | | - inline=inline_comment_cre, |
665 | | - full=tuple(comment_prefixes or ()) |
666 | | - ) |
| 668 | + self._comments = _CommentSpec(comment_prefixes or (), inline_comment_prefixes or ()) |
667 | 669 | self._strict = strict |
668 | 670 | self._allow_no_value = allow_no_value |
669 | 671 | self._empty_lines_in_values = empty_lines_in_values |
|
0 commit comments