Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.11
rev: v0.16.0
hooks:
- id: ruff-check
args: [--exit-non-zero-on-fix]
Expand All @@ -20,7 +20,7 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.37.1
rev: 0.37.4
hooks:
- id: check-dependabot
- id: check-github-workflows
Expand All @@ -31,12 +31,12 @@ repos:
- id: actionlint

- repo: https://github.com/zizmorcore/zizmor-pre-commit
rev: v1.24.1
rev: v1.28.0
hooks:
- id: zizmor

- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.21.1
rev: v2.25.3
hooks:
- id: pyproject-fmt

Expand All @@ -46,7 +46,7 @@ repos:
- id: validate-pyproject

- repo: https://github.com/tox-dev/tox-ini-fmt
rev: 1.7.1
rev: 1.8.0
hooks:
- id: tox-ini-fmt

Expand Down
16 changes: 0 additions & 16 deletions .ruff.toml

This file was deleted.

18 changes: 14 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ name = "blurb"
description = "Command-line tool to manage CPython Misc/NEWS.d entries."
readme = "README.md"
maintainers = [
{ name = "Python Core Developers", email = "[email protected]" },
{ name = "Python Core Team", email = "[email protected]" },
]
authors = [
{ name = "Larry Hastings", email = "[email protected]" },
Expand All @@ -27,9 +27,7 @@ classifiers = [
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.15",
]
dynamic = [
"version",
]
dynamic = [ "version" ]
optional-dependencies.tests = [
"pyfakefs",
"pytest",
Expand All @@ -46,5 +44,17 @@ version.source = "vcs"
version.raw-options.local_scheme = "no-local-version"
build.hooks.vcs.version-file = "src/blurb/_version.py"

[tool.ruff]
fix = true
format.preview = true
format.docstring-code-format = true
lint.select = [
"I", # isort
]
lint.ignore = [
"E501", # Ignore line length errors (we use auto-formatting)
]
lint.preview = true

[tool.pyproject-fmt]
max_supported_python = "3.15"
2 changes: 1 addition & 1 deletion src/blurb/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

from blurb._cli import main

if __name__ == '__main__':
if __name__ == "__main__":
main()
58 changes: 29 additions & 29 deletions src/blurb/_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
if TYPE_CHECKING:
from collections.abc import Sequence

if sys.platform == 'win32':
FALLBACK_EDITORS = ('notepad.exe',)
if sys.platform == "win32":
FALLBACK_EDITORS = ("notepad.exe",)
else:
FALLBACK_EDITORS = ('/etc/alternatives/editor', 'nano')
FALLBACK_EDITORS = ("/etc/alternatives/editor", "nano")


def add(*, issue: str | None = None, section: str | None = None):
Expand All @@ -44,12 +44,12 @@ def add(*, issue: str | None = None, section: str | None = None):
{sections}
""" # fmt: skip

handle, tmp_path = tempfile.mkstemp('.rst')
handle, tmp_path = tempfile.mkstemp(".rst")
os.close(handle)
atexit.register(lambda: os.unlink(tmp_path))

text = _blurb_template_text(issue=issue, section=section)
with open(tmp_path, 'w', encoding='utf-8') as file:
with open(tmp_path, "w", encoding="utf-8") as file:
file.write(text)

args = _editor_args()
Expand All @@ -59,7 +59,7 @@ def add(*, issue: str | None = None, section: str | None = None):
blurb = _add_blurb_from_template(args, tmp_path)
if blurb is None:
try:
prompt('Hit return to retry (or Ctrl-C to abort)')
prompt("Hit return to retry (or Ctrl-C to abort)")
except KeyboardInterrupt:
print()
return
Expand All @@ -70,10 +70,10 @@ def add(*, issue: str | None = None, section: str | None = None):
path = blurb.save_next()
git_add_files.append(path)
flush_git_add_files()
print('Ready for commit.')
print("Ready for commit.")


add.__doc__ = add.__doc__.format(sections='\n'.join(f'* {s}' for s in sections))
add.__doc__ = add.__doc__.format(sections="\n".join(f"* {s}" for s in sections))


def _editor_args() -> list[str]:
Expand All @@ -89,12 +89,12 @@ def _editor_args() -> list[str]:
else:
args = list(shlex.split(editor))
if not shutil.which(args[0]):
raise SystemExit(f'Invalid GIT_EDITOR / EDITOR value: {editor}')
raise SystemExit(f"Invalid GIT_EDITOR / EDITOR value: {editor}")
return args


def _find_editor() -> str:
for var in 'GIT_EDITOR', 'EDITOR':
for var in "GIT_EDITOR", "EDITOR":
editor = os.environ.get(var)
if editor is not None:
return editor
Expand All @@ -105,7 +105,7 @@ def _find_editor() -> str:
found_path = shutil.which(fallback)
if found_path and os.path.exists(found_path):
return found_path
error('Could not find an editor! Set the EDITOR environment variable.')
error("Could not find an editor! Set the EDITOR environment variable.")


def _blurb_template_text(*, issue: str | None, section: str | None) -> str:
Expand All @@ -117,21 +117,21 @@ def _blurb_template_text(*, issue: str | None, section: str | None) -> str:
# Ensure that there is a trailing space after '.. gh-issue:' to make
# filling in the template easier, unless an issue number was given
# through the --issue command-line flag.
issue_line = '.. gh-issue:'
without_space = f'\n{issue_line}\n'
issue_line = ".. gh-issue:"
without_space = f"\n{issue_line}\n"
if without_space not in text:
raise SystemExit("Can't find gh-issue line in the template!")
if issue_number is None:
with_space = f'\n{issue_line} \n'
with_space = f"\n{issue_line} \n"
text = text.replace(without_space, with_space)
else:
with_issue_number = f'\n{issue_line} {issue_number}\n'
with_issue_number = f"\n{issue_line} {issue_number}\n"
text = text.replace(without_space, with_issue_number)

# Uncomment the section if needed.
if section_name is not None:
pattern = f'.. section: {section_name}'
text = text.replace(f'#{pattern}', pattern)
pattern = f".. section: {section_name}"
text = text.replace(f"#{pattern}", pattern)

return text

Expand All @@ -141,26 +141,26 @@ def _extract_issue_number(issue: str | None, /) -> int | None:
return None
issue = issue.strip()

if issue.startswith(('GH-', 'gh-')):
if issue.startswith(("GH-", "gh-")):
stripped = issue[3:]
else:
stripped = issue.removeprefix('#')
stripped = issue.removeprefix("#")
try:
if stripped.isdecimal():
return int(stripped)
except ValueError:
pass

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

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


def _extract_section_name(section: str | None, /) -> str | None:
Expand All @@ -169,7 +169,7 @@ def _extract_section_name(section: str | None, /) -> str | None:

section = section.strip()
if not section:
raise SystemExit('Empty section name!')
raise SystemExit("Empty section name!")

matches = []
# Try an exact or lowercase match
Expand All @@ -178,22 +178,22 @@ def _extract_section_name(section: str | None, /) -> str | None:
matches.append(section_name)

if not matches:
section_list = '\n'.join(f'* {s}' for s in sections)
section_list = "\n".join(f"* {s}" for s in sections)
raise SystemExit(
f'Invalid section name: {section!r}\n\nValid names are:\n\n{section_list}'
f"Invalid section name: {section!r}\n\nValid names are:\n\n{section_list}"
)

if len(matches) > 1:
multiple_matches = ', '.join(f'* {m}' for m in sorted(matches))
raise SystemExit(f'More than one match for {section!r}:\n\n{multiple_matches}')
multiple_matches = ", ".join(f"* {m}" for m in sorted(matches))
raise SystemExit(f"More than one match for {section!r}:\n\n{multiple_matches}")

return matches[0]


def _add_blurb_from_template(args: Sequence[str], tmp_path: str) -> Blurbs | None:
subprocess.run(args)

failure = ''
failure = ""
blurb = Blurbs()
try:
blurb.load(tmp_path)
Expand All @@ -207,7 +207,7 @@ def _add_blurb_from_template(args: Sequence[str], tmp_path: str) -> Blurbs | Non

if failure:
print()
print(f'Error: {failure}')
print(f"Error: {failure}")
print()
return None
return blurb
Loading