Skip to content

Commit ae19036

Browse files
hugovkCAM-Gerlachlarryhastingsmerwok
authored
blurb: replace spaces with underscores in news directory (#499)
Co-authored-by: Hugo van Kemenade <[email protected]> Co-authored-by: C.A.M. Gerlach <[email protected]> Co-authored-by: Larry Hastings <[email protected]> Co-authored-by: Éric <[email protected]>
1 parent 67b7836 commit ae19036

File tree

2 files changed

+102
-31
lines changed

2 files changed

+102
-31
lines changed

blurb/blurb.py

+39-9
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
## Licensed to the Python Software Foundation under a contributor agreement.
3939
##
4040

41-
4241
# TODO
4342
#
4443
# automatic git adds and removes
@@ -110,19 +109,46 @@
110109
sections.append(section.strip())
111110

112111

112+
_sanitize_section = {
113+
"C API": "C_API",
114+
"Core and Builtins": "Core_and_Builtins",
115+
"Tools/Demos": "Tools-Demos",
116+
}
117+
118+
113119
def sanitize_section(section):
114120
"""
115-
Cleans up a section string, making it viable as a directory name.
121+
Clean up a section string, making it viable as a directory name.
122+
"""
123+
return _sanitize_section.get(section, section)
124+
125+
126+
def sanitize_section_legacy(section):
127+
"""
128+
Clean up a section string, making it viable as a directory name (allow spaces).
116129
"""
117130
return section.replace("/", "-")
118131

132+
119133
_unsanitize_section = {
134+
"C_API": "C API",
135+
"Core_and_Builtins": "Core and Builtins",
120136
"Tools-Demos": "Tools/Demos",
121137
}
122138

139+
123140
def unsanitize_section(section):
124141
return _unsanitize_section.get(section, section)
125142

143+
def next_filename_unsanitize_sections(filename):
144+
s = filename
145+
for key, value in _unsanitize_section.items():
146+
for separator in "/\\":
147+
key = f"{separator}{key}{separator}"
148+
value = f"{separator}{value}{separator}"
149+
filename = filename.replace(key, value)
150+
return filename
151+
126152

127153
def textwrap_body(body, *, subsequent_indent=''):
128154
"""
@@ -300,14 +326,18 @@ def glob_blurbs(version):
300326
wildcard = base + ".rst"
301327
filenames.extend(glob.glob(wildcard))
302328
else:
303-
for section in sections:
304-
wildcard = os.path.join(base, sanitize_section(section), "*.rst")
329+
sanitized_sections = (
330+
{sanitize_section(section) for section in sections} |
331+
{sanitize_section_legacy(section) for section in sections}
332+
)
333+
for section in sanitized_sections:
334+
wildcard = os.path.join(base, section, "*.rst")
305335
entries = glob.glob(wildcard)
306-
entries.sort(reverse=True)
307336
deletables = [x for x in entries if x.endswith("/README.rst")]
308337
for filename in deletables:
309338
entries.remove(filename)
310339
filenames.extend(entries)
340+
filenames.sort(reverse=True, key=next_filename_unsanitize_sections)
311341
return filenames
312342

313343

@@ -537,8 +567,8 @@ def save(self, path):
537567
@staticmethod
538568
def _parse_next_filename(filename):
539569
"""
540-
Parses a "next" filename into its equivalent blurb metadata.
541-
Returns a dict.
570+
Parses a "next" filename into its equivalent blurb metadata.
571+
Returns a dict.
542572
"""
543573
components = filename.split(os.sep)
544574
section, filename = components[-2:]
@@ -552,7 +582,7 @@ def _parse_next_filename(filename):
552582
metadata = {"date": fields[0], "nonce": fields[-2], "section": section}
553583

554584
for field in fields[1:-2]:
555-
for name in ("gh-issue","bpo"):
585+
for name in ("gh-issue", "bpo"):
556586
_, got, value = field.partition(name + "-")
557587
if got:
558588
metadata[name] = value.strip()
@@ -589,7 +619,7 @@ def _extract_next_filename(self):
589619
metadata, body = self[-1]
590620
metadata['section'] = sanitize_section(metadata['section'])
591621
metadata['root'] = root
592-
if int(metadata["gh-issue"]) > 0 :
622+
if int(metadata["gh-issue"]) > 0:
593623
path = "{root}/Misc/NEWS.d/next/{section}/{date}.gh-issue-{gh-issue}.{nonce}.rst".format_map(metadata)
594624
elif int(metadata["bpo"]) > 0:
595625
# assume it's a GH issue number

blurb/tests/test_blurb.py

+63-22
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,31 @@
55

66

77
UNCHANGED_SECTIONS = (
8-
"C API",
9-
"Core and Builtins",
108
"Library",
119
)
1210

1311

1412
@pytest.mark.parametrize("section", UNCHANGED_SECTIONS)
15-
def test_sanitize_section_no_change(section: str) -> None:
13+
def test_sanitize_section_no_change(section):
1614
sanitized = blurb.sanitize_section(section)
1715
assert sanitized == section
1816

1917

2018
@pytest.mark.parametrize(
2119
"section, expected",
2220
(
21+
("C API", "C_API"),
22+
("Core and Builtins", "Core_and_Builtins"),
2323
("Tools/Demos", "Tools-Demos"),
2424
),
2525
)
26-
def test_sanitize_section_changed(section: str, expected: str) -> None:
26+
def test_sanitize_section_changed(section, expected):
2727
sanitized = blurb.sanitize_section(section)
2828
assert sanitized == expected
2929

3030

3131
@pytest.mark.parametrize("section", UNCHANGED_SECTIONS)
32-
def test_unsanitize_section_no_change(section: str) -> None:
32+
def test_unsanitize_section_no_change(section):
3333
unsanitized = blurb.unsanitize_section(section)
3434
assert unsanitized == section
3535

@@ -40,12 +40,12 @@ def test_unsanitize_section_no_change(section: str) -> None:
4040
("Tools-Demos", "Tools/Demos"),
4141
),
4242
)
43-
def test_unsanitize_section_changed(section: str, expected: str) -> None:
43+
def test_unsanitize_section_changed(section, expected):
4444
unsanitized = blurb.unsanitize_section(section)
4545
assert unsanitized == expected
4646

4747

48-
def test_glob_blurbs_next(fs: FakeFilesystem) -> None:
48+
def test_glob_blurbs_next(fs):
4949
# Arrange
5050
fake_news_entries = (
5151
"Misc/NEWS.d/next/Library/2022-04-11-18-34-33.gh-issue-11111.pC7gnM.rst",
@@ -69,28 +69,71 @@ def test_glob_blurbs_next(fs: FakeFilesystem) -> None:
6969
assert set(filenames) == set(fake_news_entries)
7070

7171

72+
def test_glob_blurbs_sort_order(fs):
73+
"""
74+
It shouldn't make a difference to sorting whether
75+
section names have spaces or underscores.
76+
"""
77+
# Arrange
78+
fake_news_entries = (
79+
"Misc/NEWS.d/next/Core and Builtins/2023-07-23-12-01-00.gh-issue-33331.Pf_BI1.rst",
80+
"Misc/NEWS.d/next/Core_and_Builtins/2023-07-23-12-02-00.gh-issue-33332.Pf_BI2.rst",
81+
"Misc/NEWS.d/next/Core and Builtins/2023-07-23-12-03-00.gh-issue-33333.Pf_BI3.rst",
82+
"Misc/NEWS.d/next/Core_and_Builtins/2023-07-23-12-04-00.gh-issue-33334.Pf_BI4.rst",
83+
)
84+
# As fake_news_entries, but reverse sorted by *filename* only
85+
expected = [
86+
"Misc/NEWS.d/next/Core_and_Builtins/2023-07-23-12-04-00.gh-issue-33334.Pf_BI4.rst",
87+
"Misc/NEWS.d/next/Core and Builtins/2023-07-23-12-03-00.gh-issue-33333.Pf_BI3.rst",
88+
"Misc/NEWS.d/next/Core_and_Builtins/2023-07-23-12-02-00.gh-issue-33332.Pf_BI2.rst",
89+
"Misc/NEWS.d/next/Core and Builtins/2023-07-23-12-01-00.gh-issue-33331.Pf_BI1.rst",
90+
]
91+
fake_readmes = (
92+
"Misc/NEWS.d/next/Library/README.rst",
93+
"Misc/NEWS.d/next/Core and Builtins/README.rst",
94+
"Misc/NEWS.d/next/Tools-Demos/README.rst",
95+
"Misc/NEWS.d/next/C API/README.rst",
96+
)
97+
for fn in fake_news_entries + fake_readmes:
98+
fs.create_file(fn)
99+
100+
# Act
101+
filenames = blurb.glob_blurbs("next")
102+
103+
# Assert
104+
assert filenames == expected
105+
106+
72107
@pytest.mark.parametrize(
73108
"news_entry, expected_section",
74109
(
75110
(
76-
"Misc/NEWS.d/next/Library/2022-04-11-18-34-33.gh-issue-55555.pC7gnM.rst",
111+
"Misc/NEWS.d/next/Library/2022-04-11-18-34-33.gh-issue-33333.pC7gnM.rst",
77112
"Library",
78113
),
79114
(
80-
"Misc/NEWS.d/next/Core and Builtins/2023-03-17-12-09-45.gh-issue-33333.Pf_BI7.rst",
115+
"Misc/NEWS.d/next/Core_and_Builtins/2023-03-17-12-09-45.gh-issue-44444.Pf_BI7.rst",
116+
"Core and Builtins",
117+
),
118+
(
119+
"Misc/NEWS.d/next/Core and Builtins/2023-03-17-12-09-45.gh-issue-55555.Pf_BI7.rst",
81120
"Core and Builtins",
82121
),
83122
(
84-
"Misc/NEWS.d/next/Tools-Demos/2023-03-21-01-27-07.gh-issue-44444.2F1Byz.rst",
123+
"Misc/NEWS.d/next/Tools-Demos/2023-03-21-01-27-07.gh-issue-66666.2F1Byz.rst",
85124
"Tools/Demos",
86125
),
87126
(
88-
"Misc/NEWS.d/next/C API/2023-03-27-22-09-07.gh-issue-66666.3SN8Bs.rst",
127+
"Misc/NEWS.d/next/C_API/2023-03-27-22-09-07.gh-issue-77777.3SN8Bs.rst",
128+
"C API",
129+
),
130+
(
131+
"Misc/NEWS.d/next/C API/2023-03-27-22-09-07.gh-issue-88888.3SN8Bs.rst",
89132
"C API",
90133
),
91134
),
92135
)
93-
def test_load_next(news_entry: str, expected_section: str, fs: FakeFilesystem) -> None:
136+
def test_load_next(news_entry, expected_section, fs):
94137
# Arrange
95138
fs.create_file(news_entry, contents="testing")
96139
blurbs = blurb.Blurbs()
@@ -107,26 +150,24 @@ def test_load_next(news_entry: str, expected_section: str, fs: FakeFilesystem) -
107150
"news_entry, expected_path",
108151
(
109152
(
110-
"Misc/NEWS.d/next/Library/2022-04-11-18-34-33.gh-issue-55555.pC7gnM.rst",
111-
"root/Misc/NEWS.d/next/Library/2022-04-11-18-34-33.gh-issue-55555.pC7gnM.rst",
153+
"Misc/NEWS.d/next/Library/2022-04-11-18-34-33.gh-issue-33333.pC7gnM.rst",
154+
"root/Misc/NEWS.d/next/Library/2022-04-11-18-34-33.gh-issue-33333.pC7gnM.rst",
112155
),
113156
(
114-
"Misc/NEWS.d/next/Core and Builtins/2023-03-17-12-09-45.gh-issue-33333.Pf_BI7.rst",
115-
"root/Misc/NEWS.d/next/Core and Builtins/2023-03-17-12-09-45.gh-issue-33333.Pf_BI7.rst",
157+
"Misc/NEWS.d/next/Core and Builtins/2023-03-17-12-09-45.gh-issue-44444.Pf_BI7.rst",
158+
"root/Misc/NEWS.d/next/Core_and_Builtins/2023-03-17-12-09-45.gh-issue-44444.Pf_BI7.rst",
116159
),
117160
(
118-
"Misc/NEWS.d/next/Tools-Demos/2023-03-21-01-27-07.gh-issue-44444.2F1Byz.rst",
119-
"root/Misc/NEWS.d/next/Tools-Demos/2023-03-21-01-27-07.gh-issue-44444.2F1Byz.rst",
161+
"Misc/NEWS.d/next/Tools-Demos/2023-03-21-01-27-07.gh-issue-55555.2F1Byz.rst",
162+
"root/Misc/NEWS.d/next/Tools-Demos/2023-03-21-01-27-07.gh-issue-55555.2F1Byz.rst",
120163
),
121164
(
122165
"Misc/NEWS.d/next/C API/2023-03-27-22-09-07.gh-issue-66666.3SN8Bs.rst",
123-
"root/Misc/NEWS.d/next/C API/2023-03-27-22-09-07.gh-issue-66666.3SN8Bs.rst",
166+
"root/Misc/NEWS.d/next/C_API/2023-03-27-22-09-07.gh-issue-66666.3SN8Bs.rst",
124167
),
125168
),
126169
)
127-
def test_extract_next_filename(
128-
news_entry: str, expected_path: str, fs: FakeFilesystem
129-
) -> None:
170+
def test_extract_next_filename(news_entry, expected_path, fs):
130171
# Arrange
131172
fs.create_file(news_entry, contents="testing")
132173
blurb.root = "root"

0 commit comments

Comments
 (0)