Skip to content

Fix: KeyError 'filename'. #386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 29, 2021
Merged
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
109 changes: 40 additions & 69 deletions blurb/blurb.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import atexit
import base64
import builtins
from collections import OrderedDict
import glob
import hashlib
import inspect
Expand All @@ -61,9 +60,7 @@
import tempfile
import textwrap
import time
import types
import unittest
import uuid


#
Expand Down Expand Up @@ -112,32 +109,6 @@
sections.append(section.strip())


def f(s):
"""
Basic support for 3.6's f-strings, in 3.5!

Formats "s" using appropriate globals and locals
dictionaries. This f-string:
f"hello a is {a}"
simply becomes
f("hello a is {a}")
In other words, just throw parentheses around the
string, and you're done!

Implemented internally using str.format_map().
This means it doesn't support expressions:
f("two minus three is {2-3}")
And it doesn't support function calls:
f("how many elements? {len(my_list)}")
But most other f-string features work.
"""
frame = sys._getframe(1)
d = dict(builtins.__dict__)
d.update(frame.f_globals)
d.update(frame.f_locals)
return s.format_map(d)


def sanitize_section(section):
"""
Cleans up a section string, making it viable as a directory name.
Expand Down Expand Up @@ -250,10 +221,10 @@ def sortable_datetime():


def prompt(prompt):
return input(f("[{prompt}> "))
return input(f"[{prompt}> ")

def require_ok(prompt):
prompt = f("[{prompt}> ")
prompt = f"[{prompt}> "
while True:
s = input(prompt).strip()
if s == 'ok':
Expand Down Expand Up @@ -483,7 +454,7 @@ def parse(self, text, *, metadata=None, filename="input"):
line_number = None

def throw(s):
raise BlurbError(f("Error in {filename}:{line_number}:\n{s}"))
raise BlurbError(f"Error in {filename}:{line_number}:\n{s}")

def finish_entry():
nonlocal body
Expand Down Expand Up @@ -563,7 +534,7 @@ def __str__(self):
add_separator = True
if metadata:
for name, value in sorted(metadata.items()):
add(f(".. {name}: {value}\n"))
add(f".. {name}: {value}\n")
add("\n")
add(textwrap_body(body))
return "".join(output)
Expand All @@ -585,10 +556,10 @@ def _parse_next_filename(filename):
components = filename.split(os.sep)
section, filename = components[-2:]
section = unsanitize_section(section)
assert section in sections, f("Unknown section {section}")
assert section in sections, f"Unknown section {section}"

fields = [x.strip() for x in filename.split(".")]
assert len(fields) >= 4, f("Can't parse 'next' filename! filename {filename!r} fields {fields}")
assert len(fields) >= 4, f"Can't parse 'next' filename! filename {filename!r} fields {fields}"
assert fields[-1] == "rst"

metadata = {"date": fields[0], "nonce": fields[-2], "section": section}
Expand Down Expand Up @@ -777,7 +748,7 @@ def subcommand(fn):
def get_subcommand(subcommand):
fn = subcommands.get(subcommand)
if not fn:
error(f("Unknown subcommand: {subcommand}\nRun 'blurb help' for help."))
error(f"Unknown subcommand: {subcommand}\nRun 'blurb help' for help.")
return fn


Expand Down Expand Up @@ -839,19 +810,19 @@ def help(subcommand=None):
for name, p in inspect.signature(fn).parameters.items():
if p.kind == inspect.Parameter.KEYWORD_ONLY:
short_option = name[0]
options.append(f(" [-{short_option}|--{name}]"))
options.append(f" [-{short_option}|--{name}]")
elif p.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD:
positionals.append(" ")
has_default = (p.default != inspect._empty)
if has_default:
positionals.append("[")
nesting += 1
positionals.append(f("<{name}>"))
positionals.append(f"<{name}>")
positionals.append("]" * nesting)


parameters = "".join(options + positionals)
print(f("blurb {subcommand}{parameters}"))
print(f"blurb {subcommand}{parameters}")
print()
print(doc)
sys.exit(0)
Expand Down Expand Up @@ -942,7 +913,7 @@ def init_tmp_with_template():
else:
args = list(shlex.split(editor))
if not shutil.which(args[0]):
sys.exit(f("Invalid GIT_EDITOR / EDITOR value: {editor}"))
sys.exit(f"Invalid GIT_EDITOR / EDITOR value: {editor}")
args.append(tmp_path)

while True:
Expand All @@ -962,7 +933,7 @@ def init_tmp_with_template():

if failure:
print()
print(f("Error: {failure}"))
print(f"Error: {failure}")
print()
try:
prompt("Hit return to retry (or Ctrl-C to abort)")
Expand Down Expand Up @@ -996,20 +967,20 @@ def release(version):
if existing_filenames:
error("Sorry, can't handle appending 'next' files to an existing version (yet).")

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

if not filenames:
print(f("No blurbs found. Setting {version} as having no changes."))
body = f("There were no new changes in version {version}.\n")
print(f"No blurbs found. Setting {version} as having no changes.")
body = f"There were no new changes in version {version}.\n"
metadata = {"no changes": "True", "bpo": "0", "section": "Library", "date": date, "nonce": nonceify(body)}
blurbs.append((metadata, body))
else:
no_changes = None
count = len(filenames)
print(f('Merging {count} blurbs to "{output}".'))
print(f'Merging {count} blurbs to "{output}".')

for filename in filenames:
if not filename.endswith(".rst"):
Expand All @@ -1026,14 +997,14 @@ def release(version):
flush_git_add_files()

how_many = len(filenames)
print(f("Removing {how_many} 'next' files from git."))
print(f"Removing {how_many} '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.load(output)
assert blurbs2 == blurbs, f("Reloading {output} isn't reproducible?!")
assert blurbs2 == blurbs, f"Reloading {output} isn't reproducible?!"

print()
print("Ready for commit.")
Expand Down Expand Up @@ -1104,7 +1075,7 @@ def print(*a, sep=" "):
metadata, body = blurbs[0]
release_date = metadata["release date"]

print(f("*Release date: {release_date}*"))
print(f"*Release date: {release_date}*")
print()

if "no changes" in metadata:
Expand Down Expand Up @@ -1172,11 +1143,11 @@ def populate():

for section in sections:
dir_name = sanitize_section(section)
dir_path = f("NEWS.d/next/{dir_name}")
dir_path = f"NEWS.d/next/{dir_name}"
safe_mkdir(dir_path)
readme_path = f("NEWS.d/next/{dir_name}/README.rst")
readme_path = f"NEWS.d/next/{dir_name}/README.rst"
with open(readme_path, "wt", encoding="utf-8") as readme:
readme.write(f("Put news entry ``blurb`` files for the *{section}* section in this directory.\n"))
readme.write(f"Put news entry ``blurb`` files for the *{section}* section in this directory.\n")
git_add_files.append(dir_path)
git_add_files.append(readme_path)
flush_git_add_files()
Expand All @@ -1197,7 +1168,7 @@ def export():
# """
# Test function for blurb command-line processing.
# """
# print(f("arg: boolean {boolean} option {option}"))
# print(f"arg: boolean {boolean} option {option}")


@subcommand
Expand Down Expand Up @@ -1282,7 +1253,7 @@ def flush_blurb():
fields.append(field)
see_also = ", ".join(fields)
# print("see_also: ", repr(see_also))
accumulator.append(f("(See also: {see_also})"))
accumulator.append(f"(See also: {see_also})")
see_also = None
if not accumulator:
return
Expand Down Expand Up @@ -1328,8 +1299,8 @@ def flush_version():
if version is None:
assert not blurbs, "version should only be None initially, we shouldn't have blurbs yet"
return
assert blurbs, f("No blurbs defined when flushing version {version}!")
output = f("NEWS.d/{version}.rst")
assert blurbs, f"No blurbs defined when flushing version {version}!"
output = f"NEWS.d/{version}.rst"

if released:
# saving merged blurb file for version, e.g. Misc/NEWS.d/3.7.0a1.rst
Expand Down Expand Up @@ -1447,11 +1418,11 @@ def flush_version():
elif line.startswith("- Issue #9516: Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET"):
line = "- Issue #9516 and Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET"
elif line.title().startswith(("- Request #", "- Bug #", "- Patch #", "- Patches #")):
# print(f("FIXING LINE {line_number}: {line!r}"))
# print(f"FIXING LINE {line_number}: {line!r}")
line = "- Issue #" + line.partition('#')[2]
# print(f("FIXED LINE {line_number}: {line!r}"))
# print(f"FIXED LINE {line_number}: {line!r}")
# else:
# print(f("NOT FIXING LINE {line_number}: {line!r}"))
# print(f"NOT FIXING LINE {line_number}: {line!r}")


# 4. determine the actual content of the line
Expand Down Expand Up @@ -1516,7 +1487,7 @@ def flush_version():
line = line[4:]
parse_bpo = True
else:
# print(f("[[{line_number:8} no bpo]] {line}"))
# print(f"[[{line_number:8} no bpo]] {line}")
parse_bpo = False
if parse_bpo:
# GAAAH
Expand Down Expand Up @@ -1556,9 +1527,9 @@ def flush_version():
try:
int(bpo) # this will throw if it's not a legal int
except ValueError:
sys.exit(f("Couldn't convert bpo number to int on line {line_number}! {bpo!r}"))
sys.exit(f"Couldn't convert bpo number to int on line {line_number}! {bpo!r}")
if see_also == "partially":
sys.exit(f("What the hell on line {line_number}! {bpo!r}"))
sys.exit(f"What the hell on line {line_number}! {bpo!r}")

# 4.6.1 continuation of blurb
elif line.startswith(" "):
Expand All @@ -1567,7 +1538,7 @@ def flush_version():
elif line.startswith(" * "):
line = line[3:]
elif line:
sys.exit(f("Didn't recognize line {line_number}! {line!r}"))
sys.exit(f"Didn't recognize line {line_number}! {line!r}")
# only add blank lines if we have an initial line in the accumulator
if line or accumulator:
accumulator.append(line)
Expand All @@ -1579,7 +1550,7 @@ def flush_version():
git_rm_files.append("NEWS")
flush_git_rm_files()

print(f("Wrote {blurb_count} news items across {version_count} versions."))
print(f"Wrote {blurb_count} news items across {version_count} versions.")
print()
print("Ready for commit.")

Expand Down Expand Up @@ -1628,10 +1599,10 @@ def main():
def handle_option(s, dict):
name = dict.get(s, None)
if not name:
sys.exit(f('blurb: Unknown option for {subcommand}: "{s}"'))
sys.exit(f'blurb: Unknown option for {subcommand}: "{s}"')
kwargs[name] = not kwargs[name]

# print(f("short_options {short_options} long_options {long_options}"))
# print(f"short_options {short_options} long_options {long_options}")
for a in args:
if done_with_options:
filtered_args.append(a)
Expand Down Expand Up @@ -1665,7 +1636,7 @@ def handle_option(s, dict):
# whoops, must be a real type error, reraise
raise e

how_many = f("{specified} argument")
how_many = f"{specified} argument"
if specified != 1:
how_many += "s"

Expand All @@ -1676,12 +1647,12 @@ def handle_option(s, dict):
middle = "requires"
else:
plural = "" if required == 1 else "s"
middle = f("requires at least {required} argument{plural} and at most")
middle += f(" {total} argument")
middle = f"requires at least {required} argument{plural} and at most"
middle += f" {total} argument"
if total != 1:
middle += "s"

print(f('Error: Wrong number of arguments!\n\nblurb {subcommand} {middle},\nand you specified {how_many}.'))
print(f'Error: Wrong number of arguments!\n\nblurb {subcommand} {middle},\nand you specified {how_many}.')
print()
print("usage: ", end="")
help(subcommand)
Expand Down
9 changes: 6 additions & 3 deletions blurb/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ author-email = "[email protected]"
maintainer = "Python Core Developers"
maintainer-email = "[email protected]"
home-page = "https://github.com/python/core-workflow/tree/master/blurb"
requires-python = ">=3.5"
requires-python = ">=3.6"
description-file = "README.rst"
classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3 :: Only",]

classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3 :: Only"
]

[tool.flit.scripts]
blurb = "blurb:main"