wip: refuctoring on the road to v201812

This commit is contained in:
Manuel Barkhau 2018-12-05 09:38:27 +01:00
parent 70f4e01104
commit fe06833764
5 changed files with 468 additions and 302 deletions

View file

@ -29,8 +29,8 @@
import re
import logging
import typing as typ
import pkg_resources
from . import version
log = logging.getLogger("pycalver.parse")
@ -89,42 +89,36 @@ RE_PATTERN_PARTS = {
class VersionInfo(typ.NamedTuple):
"""Container for parsed version string."""
version: str
calver : str
year : str
month : str
build : str
release: typ.Optional[str]
version : str
pep440_version: str
calver : str
year : str
month : str
build : str
release : typ.Optional[str]
@property
def pep440_version(self) -> str:
"""Generate pep440 compliant version string.
>>> vnfo = VersionInfo.parse("v201712.0033-beta")
>>> vnfo.pep440_version
'201712.33b0'
"""
return str(pkg_resources.parse_version(self.version))
def parse_version_info(version_str: str) -> VersionInfo:
"""Parse a PyCalVer string.
@staticmethod
def parse(version: str) -> 'VersionInfo':
"""Parse a PyCalVer string.
>>> vnfo = parse_version_info("v201712.0033-beta")
>>> assert vnfo == VersionInfo(
... version="v201712.0033-beta",
... pep440_version="201712.33b0",
... calver="v201712",
... year="2017",
... month="12",
... build=".0033",
... release="-beta",
... )
"""
match = PYCALVER_RE.match(version_str)
if match is None:
raise ValueError(f"Invalid PyCalVer string: {version_str}")
>>> vnfo = VersionInfo.parse("v201712.0033-beta")
>>> assert vnfo == VersionInfo(
... version="v201712.0033-beta",
... calver="v201712",
... year="2017",
... month="12",
... build=".0033",
... release="-beta",
... )
"""
match = PYCALVER_RE.match(version)
if match is None:
raise ValueError(f"Invalid pycalver: {version}")
return VersionInfo(**match.groupdict())
kwargs = match.groupdict()
kwargs['pep440_version'] = version.pycalver_to_pep440(kwargs['version'])
return VersionInfo(**kwargs)
class PatternMatch(typ.NamedTuple):
@ -136,38 +130,41 @@ class PatternMatch(typ.NamedTuple):
span : typ.Tuple[int, int]
match : str
@staticmethod
def _iter_for_pattern(lines: typ.List[str], pattern: str) -> typ.Iterable['PatternMatch']:
# The pattern is escaped, so that everything besides the format
# string variables is treated literally.
pattern_tmpl = pattern
PatternMatches = typ.Iterable[PatternMatch]
for char, escaped in PATTERN_ESCAPES:
pattern_tmpl = pattern_tmpl.replace(char, escaped)
pattern_str = pattern_tmpl.format(**RE_PATTERN_PARTS)
pattern_re = re.compile(pattern_str)
for lineno, line in enumerate(lines):
match = pattern_re.search(line)
if match:
yield PatternMatch(lineno, line, pattern, match.span(), match.group(0))
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.
@staticmethod
def iter_matches(lines: typ.List[str], patterns: typ.List[str]) -> typ.Iterable['PatternMatch']:
"""Iterate over all matches of any pattern on any line.
pattern_tmpl = pattern
>>> lines = ["__version__ = 'v201712.0002-alpha'"]
>>> patterns = ["{version}", "{pep440_version}"]
>>> matches = list(PatternMatch.iter_matches(lines, patterns))
>>> assert matches[0] == PatternMatch(
... lineno = 0,
... line = "__version__ = 'v201712.0002-alpha'",
... pattern= "{version}",
... span = (15, 33),
... match = "v201712.0002-alpha",
... )
"""
for pattern in patterns:
for match in PatternMatch._iter_for_pattern(lines, pattern):
yield match
for char, escaped in PATTERN_ESCAPES:
pattern_tmpl = pattern_tmpl.replace(char, escaped)
pattern_str = pattern_tmpl.format(**RE_PATTERN_PARTS)
pattern_re = re.compile(pattern_str)
for lineno, line in enumerate(lines):
match = pattern_re.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:
"""Iterate over all matches of any pattern on any line.
>>> lines = ["__version__ = 'v201712.0002-alpha'"]
>>> patterns = ["{version}", "{pep440_version}"]
>>> matches = list(iter_matches(lines, patterns))
>>> assert matches[0] == PatternMatch(
... lineno = 0,
... line = "__version__ = 'v201712.0002-alpha'",
... pattern= "{version}",
... span = (15, 33),
... match = "v201712.0002-alpha",
... )
"""
for pattern in patterns:
for match in _iter_for_pattern(lines, pattern):
yield match