setup to reduce code duplication

This commit is contained in:
Manuel Barkhau 2020-09-08 20:59:52 +00:00
parent e053af589e
commit 3cbf0e82b1
10 changed files with 271 additions and 267 deletions

View file

@ -7,7 +7,7 @@
import typing as typ
from .patterns import compile_pattern
import pycalver.patterns as v1patterns
class PatternMatch(typ.NamedTuple):
@ -15,37 +15,33 @@ class PatternMatch(typ.NamedTuple):
lineno : int # zero based
line : str
pattern: str
pattern: v1patterns.Pattern
span : typ.Tuple[int, int]
match : str
PatternMatches = typ.Iterable[PatternMatch]
RegexpPatterns = typ.List[typ.Pattern[str]]
def _iter_for_pattern(lines: typ.List[str], pattern: str) -> PatternMatches:
# The pattern is escaped, so that everything besides the format
# string variables is treated literally.
pattern_re = compile_pattern(pattern)
def _iter_for_pattern(lines: typ.List[str], pattern: v1patterns.Pattern) -> PatternMatches:
for lineno, line in enumerate(lines):
match = pattern_re.search(line)
match = pattern.regexp.search(line)
if match:
yield PatternMatch(lineno, line, pattern, match.span(), match.group(0))
def iter_matches(lines: typ.List[str], patterns: typ.List[str]) -> PatternMatches:
def iter_matches(lines: typ.List[str], patterns: typ.List[v1patterns.Pattern]) -> PatternMatches:
"""Iterate over all matches of any pattern on any line.
>>> import pycalver.patterns as v1patterns
>>> lines = ["__version__ = 'v201712.0002-alpha'"]
>>> patterns = ["{pycalver}", "{pep440_pycalver}"]
>>> patterns = [v1patterns.compile_pattern(p) for p in patterns]
>>> matches = list(iter_matches(lines, patterns))
>>> assert matches[0] == PatternMatch(
... lineno = 0,
... line = "__version__ = 'v201712.0002-alpha'",
... pattern= "{pycalver}",
... pattern= v1patterns.compile_pattern("{pycalver}"),
... span = (15, 33),
... match = "v201712.0002-alpha",
... )

View file

@ -177,7 +177,18 @@ PART_FORMATS = {
}
class Pattern(typ.NamedTuple):
raw : str # "{pycalver}", "{year}.{month}", "YYYY0M.BUILD"
regexp: typ.Pattern[str]
Patterns = typ.List[typ.Pattern[str]]
def _replace_pattern_parts(pattern: str) -> str:
# The pattern is escaped, so that everything besides the format
# string variables is treated literally.
for part_name, part_pattern in PART_PATTERNS.items():
named_part_pattern = f"(?P<{part_name}>{part_pattern})"
placeholder = "\u005c{" + part_name + "\u005c}"
@ -192,9 +203,10 @@ def compile_pattern_str(pattern: str) -> str:
return _replace_pattern_parts(pattern)
def compile_pattern(pattern: str) -> typ.Pattern[str]:
def compile_pattern(pattern: str) -> Pattern:
pattern_str = compile_pattern_str(pattern)
return re.compile(pattern_str)
pattern_re = re.compile(pattern_str)
return Pattern(pattern, pattern_re)
def _init_composite_patterns() -> None:

View file

@ -94,9 +94,11 @@ def rewrite_lines(
new_lines = old_lines[:]
found_patterns = set()
for match in parse.iter_matches(old_lines, pattern_strs):
found_patterns.add(match.pattern)
replacement = v1version.format_version(new_vinfo, match.pattern)
patterns = [v1patterns.compile_pattern(p) for p in pattern_strs]
matches = parse.iter_matches(old_lines, patterns)
for match in matches:
found_patterns.add(match.pattern.raw)
replacement = v1version.format_version(new_vinfo, match.pattern.raw)
span_l, span_r = match.span
new_line = match.line[:span_l] + replacement + match.line[span_r:]
new_lines[match.lineno] = new_line

View file

@ -318,11 +318,12 @@ def parse_version_info(version_str: str, pattern: str = "{pycalver}") -> Version
>>> vnfo = parse_version_info("1.23.456", pattern="{semver}")
>>> assert vnfo == _parse_version_info({'MAJOR': "1", 'MINOR': "23", 'PATCH': "456"})
"""
regex = v1patterns.compile_pattern(pattern)
match = regex.match(version_str)
pattern_tup = v1patterns.compile_pattern(pattern)
match = pattern_tup.regexp.match(version_str)
if match is None:
err_msg = (
f"Invalid version string '{version_str}' for pattern '{pattern}'/'{regex.pattern}'"
f"Invalid version string '{version_str}' "
f"for pattern '{pattern}'/'{pattern_tup.regexp.pattern}'"
)
raise PatternError(err_msg)