From 5ddcc223b26984d0817bcd7414b44caa3e21413c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 24 Jun 2024 18:59:11 +0300 Subject: [PATCH 1/2] Add --gh and --section flags to "blurb add" Co-authored-by: Larry Hastings --- README.md | 8 ++++++ src/blurb/blurb.py | 71 ++++++++++++++++++++++++++++++---------------- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index d1dcc8d..07988b5 100644 --- a/README.md +++ b/README.md @@ -110,11 +110,13 @@ Here's how you interact with the file: * Add the GitHub issue number for this commit to the end of the `.. gh-issue:` line. + Can be passed on the CLI via the `--gh` flag. * Uncomment the line with the relevant `Misc/NEWS` section for this entry. For example, if this should go in the `Library` section, uncomment the line reading `#.. section: Library`. To uncomment, just delete the `#` at the front of the line. + Can be passed on the CLI via the `--section` flag. * Finally, go to the end of the file, and enter your `NEWS` entry. This should be a single paragraph of English text using @@ -239,6 +241,12 @@ part of the cherry-picking process. ## Changelog +### 1.2.0 + +- Add the `--gh` and `--section` flags to the `add` command. + This lets you pre-fill-in the `gh-issue` and `section` fields + in the template. + ### 1.1.0 - Support GitHub Issues in addition to b.p.o (bugs.python.org). diff --git a/src/blurb/blurb.py b/src/blurb/blurb.py index cb1c4c8..6e9348d 100755 --- a/src/blurb/blurb.py +++ b/src/blurb/blurb.py @@ -73,7 +73,7 @@ # # Please enter the relevant GitHub issue number here: # -.. gh-issue: +.. gh-issue: {gh} # # Uncomment one of these "section:" lines to specify which section @@ -90,6 +90,7 @@ #.. section: IDLE #.. section: Tools/Demos #.. section: C API +{section} # Write your Misc/NEWS.d entry below. It should be a simple ReST paragraph. # Don't start with "- Issue #: " or "- gh-issue-: " or that sort of stuff. @@ -451,6 +452,8 @@ def parse(self, text, *, metadata=None, filename="input"): line_number = None def throw(s): + nonlocal filename + nonlocal line_number raise BlurbError(f"Error in {filename}:{line_number}:\n{s}") def finish_entry(): @@ -870,7 +873,7 @@ def find_editor(): @subcommand -def add(): +def add(*, gh="", section=""): """ Add a blurb (a Misc/NEWS.d/next entry) to the current CPython repo. """ @@ -881,24 +884,23 @@ def add(): os.close(handle) atexit.register(lambda : os.unlink(tmp_path)) - def init_tmp_with_template(): - with open(tmp_path, "wt", encoding="utf-8") as file: - # hack: - # my editor likes to strip trailing whitespace from lines. - # normally this is a good idea. but in the case of the template - # it's unhelpful. - # so, manually ensure there's a space at the end of the gh-issue line. - text = template - - issue_line = ".. gh-issue:" - without_space = "\n" + issue_line + "\n" - with_space = "\n" + issue_line + " \n" - if without_space not in text: - sys.exit("Can't find gh-issue line to ensure there's a space on the end!") - text = text.replace(without_space, with_space) - file.write(text) + if gh: + try: + int(gh) + except ValueError: + error(f"blurb add --gh argument {gh} is not a valid integer!") + + if section: + if section not in sections: + error( + f"blurb add --section argument {section!r} is not a valid section!" + " Use one of:\n" + "\n".join(sections) + ) - init_tmp_with_template() + section = f".. section: {section}\n" + + with open(tmp_path, "wt", encoding="utf-8") as file: + file.write(template.format(gh=gh, section=section)) # We need to be clever about EDITOR. # On the one hand, it might be a legitimate path to an @@ -1221,36 +1223,55 @@ def main(): kwargs = {} for name, p in inspect.signature(fn).parameters.items(): if p.kind == inspect.Parameter.KEYWORD_ONLY: - assert isinstance(p.default, bool), "blurb command-line processing only handles boolean options" + assert isinstance( + p.default, (bool, str) + ), "blurb command-line processing only handles boolean options" kwargs[name] = p.default short_options[name[0]] = name long_options[name] = name filtered_args = [] done_with_options = False + needs_oparg = None - def handle_option(s, dict): + def handle_option(s, dict, fn_name): + nonlocal needs_oparg name = dict.get(s, None) if not name: - sys.exit(f'blurb: Unknown option for {subcommand}: "{s}"') - kwargs[name] = not kwargs[name] + sys.exit(f'blurb: Unknown option for {fn_name}: "{s}"') + + value = kwargs[name] + if isinstance(value, bool): + kwargs[name] = not value + else: + needs_oparg = name # print(f"short_options {short_options} long_options {long_options}") for a in args: + if needs_oparg: + kwargs[needs_oparg] = a + needs_oparg = None + continue + if done_with_options: filtered_args.append(a) continue + if a.startswith('-'): if a == "--": done_with_options = True elif a.startswith("--"): - handle_option(a[2:], long_options) + handle_option(a[2:], long_options, fn.__name__) else: for s in a[1:]: - handle_option(s, short_options) + handle_option(s, short_options, fn.__name__) continue filtered_args.append(a) + if needs_oparg: + sys.exit( + f"Error: blurb: {fn_name} {needs_oparg} most be followed by an option argument" + ) sys.exit(fn(*filtered_args, **kwargs)) except TypeError as e: From fe85acfd5f999c357e23ad7e484206284909e4a9 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:57:54 +0300 Subject: [PATCH 2/2] Temporarily remove 3.13 from CI pending pytest-dev/pyfakefs#1017 --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 388811d..5c2d790 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,9 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + # Temporarily remove 3.13 pending: + # https://github.com/pytest-dev/pyfakefs/issues/1017 + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4