Skip to content
14 changes: 4 additions & 10 deletions src/blurb/_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,20 +182,14 @@ def _extract_issue_number(issue: str | None, /) -> int | None:
stripped = issue[3:]
else:
stripped = issue.removeprefix('#')
try:
if stripped.isdecimal():
return int(stripped)
except ValueError:
pass
if stripped.isdecimal():
return int(stripped)

# Allow GitHub URL with or without the scheme
stripped = issue.removeprefix('https://')
stripped = stripped.removeprefix('github.com/python/cpython/issues/')
try:
if stripped.isdecimal():
return int(stripped)
except ValueError:
pass
if stripped.isdecimal():
return int(stripped)

raise SystemExit(f'Invalid GitHub issue number: {issue}')

Expand Down
5 changes: 2 additions & 3 deletions src/blurb/_blurb_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
* "release date" is the day a particular version of Python was released.
* "no changes", if present, notes that there were no actual changes
for this version. When used, there are two more things that must be
true about the the blurb file:
true about the blurb file:
* There should only be one entry inside the blurb file.
* That entry's gh-issue number must be 0.

Expand Down Expand Up @@ -144,7 +144,6 @@ def finish_entry() -> None:
nonlocal body
nonlocal in_metadata
nonlocal metadata
nonlocal self

if not body:
throw("Blurb 'body' text must not be empty!")
Expand Down Expand Up @@ -341,7 +340,7 @@ def _extract_next_filename(self) -> str:
metadata
)
elif int(metadata['bpo']) > 0:
# assume it's a GH issue number
# legacy bugs.python.org issue number
path = '{root}/Misc/NEWS.d/next/{section}/{date}.bpo-{bpo}.{nonce}.rst'.format_map(
metadata
)
Expand Down
32 changes: 14 additions & 18 deletions src/blurb/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Callable
from typing import NoReturn

readme_re = re.compile(r'This is \w+ version \d+\.\d+').match
Expand All @@ -23,12 +24,9 @@ def prompt(prompt: str, /) -> str:
return input(f'[{prompt}> ')


def require_ok(prompt: str, /) -> str:
prompt = f'[{prompt}> '
while True:
s = input(prompt).strip()
if s == 'ok':
return s
def require_ok(message: str, /) -> None:
while prompt(message).strip() != 'ok':
pass


def build_parser() -> argparse.ArgumentParser:
Expand Down Expand Up @@ -137,6 +135,14 @@ def main(argv: list[str] | None = None) -> None:
ns.func(ns)


def first_line_matches(filename: str, test: Callable[[str], object]) -> bool:
if not os.path.exists(filename):
return False
with open(filename, encoding='utf-8') as file:
lines = file.read().split('\n')
return bool(lines and test(lines[0]))


def chdir_to_repo_root() -> str:
# find the root of the local CPython repo
# note that we can't ask git, because we might
Expand All @@ -153,19 +159,9 @@ def chdir_to_repo_root() -> str:

os.chdir(path)

def test_first_line(filename, test):
if not os.path.exists(filename):
return False
with open(filename, encoding='utf-8') as file:
lines = file.read().split('\n')
if not (lines and test(lines[0])):
return False
return True

if not test_first_line('README.rst', readme_re):
if not first_line_matches('README.rst', readme_re):
continue

if not test_first_line('LICENSE', 'A. HISTORY OF THE SOFTWARE'.__eq__):
if not first_line_matches('LICENSE', 'A. HISTORY OF THE SOFTWARE'.__eq__):
continue
if not os.path.exists('Include/Python.h'):
continue
Expand Down
14 changes: 6 additions & 8 deletions src/blurb/_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import os
import time

import blurb._blurb_file
from blurb._blurb_file import Blurbs
from blurb import _blurb_file
from blurb._cli import error
from blurb._git import (
flush_git_add_files,
Expand All @@ -24,7 +23,7 @@ def release(version: str) -> None:
if version == '.':
# harvest version number from dirname of repo
# I remind you, we're in the Misc subdir right now
version = os.path.basename(blurb._blurb_file.root)
version = os.path.basename(_blurb_file.root)

existing_filenames = glob_blurbs(version)
if existing_filenames:
Expand All @@ -34,7 +33,8 @@ def release(version: str) -> None:

output = f'Misc/NEWS.d/{version}.rst'
filenames = glob_blurbs('next')
blurbs = Blurbs()
count = len(filenames)
blurbs = _blurb_file.Blurbs()
date = current_date()

if not filenames:
Expand All @@ -49,7 +49,6 @@ def release(version: str) -> None:
}
blurbs.append((metadata, body))
else:
count = len(filenames)
print(f'Merging {count} blurbs to "{output}".')

for filename in filenames:
Expand All @@ -66,13 +65,12 @@ def release(version: str) -> None:
git_add_files.append(output)
flush_git_add_files()

how_many = len(filenames)
print(f"Removing {how_many} 'next' files from git.")
print(f"Removing {count} 'next' files from git.")
git_rm_files.extend(filenames)
flush_git_rm_files()

# sanity check: ensuring that saving/reloading the merged blurb file works.
blurbs2 = Blurbs()
blurbs2 = _blurb_file.Blurbs()
blurbs2.load(output)
assert blurbs2 == blurbs, f"Reloading {output} isn't reproducible?!"

Expand Down
7 changes: 1 addition & 6 deletions src/blurb/_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,7 @@
'Unsupported platforms': 'Unsupported_platforms',
}

_unsanitize_section = {
'C_API': 'C API',
'Core_and_Builtins': 'Core and Builtins',
'Tools-Demos': 'Tools/Demos',
'Unsupported_platforms': 'Unsupported platforms',
}
_unsanitize_section = {v: k for k, v in _sanitize_section.items()}


def sanitize_section(section: str, /) -> str:
Expand Down
5 changes: 1 addition & 4 deletions src/blurb/_utils/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ def textwrap_body(body: str | Iterable[str], *, subsequent_indent: str = '') ->

# step 1: remove trailing whitespace from individual lines
# (this means that empty lines will just have \n, no invisible whitespace)
lines = []
for line in text.split('\n'):
lines.append(line.rstrip())
text = '\n'.join(lines)
text = '\n'.join(line.rstrip() for line in text.split('\n'))
# step 2: break into paragraphs and wrap those
paragraphs = text.split('\n\n')
paragraphs2 = []
Expand Down
2 changes: 1 addition & 1 deletion src/blurb/_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def glob_versions() -> list[str]:


def version_key(element: str, /) -> str:
fields = list(element.split('.'))
fields = element.split('.')
if len(fields) == 1:
return element

Expand Down
Loading