Skip to content

Commit 08d688f

Browse files
authored
All PEPs: Move to peps/ folder (python#3418)
1 parent 0f22268 commit 08d688f

File tree

678 files changed

+732
-762
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

678 files changed

+732
-762
lines changed

.github/CODEOWNERS

+655-655
Large diffs are not rendered by default.

.github/PULL_REQUEST_TEMPLATE/Add a new PEP.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ If your PEP is not Standards Track, remove the corresponding section.
1010
## Basic requirements (all PEP Types)
1111

1212
* [ ] Read and followed [PEP 1](https://peps.python.org/1) & [PEP 12](https://peps.python.org/12)
13-
* [ ] File created from the [latest PEP template](https://github.com/python/peps/blob/main/pep-0012/pep-NNNN.rst?plain=1)
13+
* [ ] File created from the [latest PEP template](https://github.com/python/peps/blob/main/peps/pep-0012/pep-NNNN.rst?plain=1)
1414
* [ ] PEP has next available number, & set in filename (``pep-NNNN.rst``), PR title (``PEP 123: <Title of PEP>``) and ``PEP`` header
1515
* [ ] Title clearly, accurately and concisely describes the content in 79 characters or less
1616
* [ ] Core dev/PEP editor listed as ``Author`` or ``Sponsor``, and formally confirmed their approval

.gitignore

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
coverage.xml
2-
pep-0000.txt
1+
# PEPs
32
pep-0000.rst
4-
pep-????.html
53
peps.rss
4+
topic
5+
/build
6+
7+
# Bytecode
68
__pycache__
7-
*.pyc
8-
*.pyo
9+
*.py[co]
10+
11+
# Editors
912
*~
10-
*env
11-
.coverage
12-
.tox
13+
.idea
1314
.vscode
1415
*.swp
15-
/build
16-
/package
17-
/topic
16+
17+
# Tests
18+
coverage.xml
19+
.coverage
20+
.tox
21+
22+
# Virtual environments
23+
*env
1824
/venv

.pre-commit-config.yaml

+25-55
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,12 @@ repos:
8282
hooks:
8383
- id: rst-backticks
8484
name: "Check RST: No single backticks"
85-
files: '^pep-\d+\.(rst|txt)$'
86-
types: [text]
85+
8786
- id: rst-inline-touching-normal
8887
name: "Check RST: No backticks touching text"
89-
files: '^pep-\d+\.(rst|txt)$'
90-
types: [text]
88+
9189
- id: rst-directive-colons
9290
name: "Check RST: 2 colons after directives"
93-
files: '^pep-\d+\.(rst|txt)$'
94-
types: [text]
9591

9692
# Manual codespell check
9793
- repo: https://github.com/codespell-project/codespell
@@ -112,152 +108,126 @@ repos:
112108
# files: "^pep-\d{4}\.(rst|txt)$"
113109
# require_serial: true
114110

115-
- id: check-no-tabs
116-
name: "Check tabs not used in PEPs"
117-
language: pygrep
118-
entry: '\t'
119-
files: '^pep-\d+\.(rst|txt)$'
120-
types: [text]
121-
122111
- id: check-required-headers
123112
name: "PEPs must have all required headers"
124113
language: pygrep
125114
entry: '(?-m:^PEP:(?=[\s\S]*\nTitle:)(?=[\s\S]*\nAuthor:)(?=[\s\S]*\nStatus:)(?=[\s\S]*\nType:)(?=[\s\S]*\nContent-Type:)(?=[\s\S]*\nCreated:))'
126115
args: ['--negate', '--multiline']
127-
files: '^pep-\d+\.(rst|txt)$'
128-
types: [text]
116+
files: '^peps/pep-\d+\.rst$'
129117

130118
- id: check-header-order
131119
name: "PEP header order must follow PEP 12"
132120
language: pygrep
133121
entry: '^PEP:[^\n]+\nTitle:[^\n]+\n(Version:[^\n]+\n)?(Last-Modified:[^\n]+\n)?Author:[^\n]+\n( +\S[^\n]+\n)*(Sponsor:[^\n]+\n)?((PEP|BDFL)-Delegate:[^\n]*\n)?(Discussions-To:[^\n]*\n)?Status:[^\n]+\nType:[^\n]+\n(Topic:[^\n]+\n)?Content-Type:[^\n]+\n(Requires:[^\n]+\n)?Created:[^\n]+\n(Python-Version:[^\n]*\n)?(Post-History:[^\n]*\n( +\S[^\n]*\n)*)?(Replaces:[^\n]+\n)?(Superseded-By:[^\n]+\n)?(Resolution:[^\n]*\n)?\n'
134122
args: ['--negate', '--multiline']
135-
files: '^pep-\d+\.(rst|txt)$'
136-
types: [text]
123+
files: '^peps/pep-\d+\.rst$'
137124

138125
- id: validate-pep-number
139126
name: "'PEP' header must be a number 1-9999"
140127
language: pygrep
141128
entry: '(?-m:^PEP:(?:(?! +(0|[1-9][0-9]{0,3})\n)))'
142129
args: ['--multiline']
143-
files: '^pep-\d+\.(rst|txt)$'
144-
types: [text]
130+
files: '^peps/pep-\d+\.rst$'
145131

146132
- id: validate-title
147133
name: "'Title' must be 1-79 characters"
148134
language: pygrep
149135
entry: '(?<=\n)Title:(?:(?! +\S.{1,78}\n(?=[A-Z])))'
150136
args: ['--multiline']
151-
files: '^pep-\d+\.(rst|txt)$'
152-
exclude: '^pep-(0499)\.(rst|txt)$'
153-
types: [text]
137+
files: '^peps/pep-\d+\.rst$'
138+
exclude: '^peps/pep-(0499)\.rst$'
154139

155140
- id: validate-author
156141
name: "'Author' must be list of 'Name <[email protected]>, ...'"
157142
language: pygrep
158143
entry: '(?<=\n)Author:(?:(?!((( +|\n {1,8})[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?)(,|(?=\n[^ ])))+\n(?=[A-Z])))'
159-
args: [--multiline]
160-
files: '^pep-\d+\.(rst|txt)$'
161-
types: [text]
144+
args: ["--multiline"]
145+
files: '^peps/pep-\d+\.rst$'
162146

163147
- id: validate-sponsor
164148
name: "'Sponsor' must have format 'Name <[email protected]>'"
165149
language: pygrep
166150
entry: '^Sponsor:(?: (?! *[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?$))'
167-
files: '^pep-\d+\.(rst|txt)$'
168-
types: [text]
151+
files: '^peps/pep-\d+\.rst$'
169152

170153
- id: validate-delegate
171154
name: "'Delegate' must have format 'Name <[email protected]>'"
172155
language: pygrep
173156
entry: '^(PEP|BDFL)-Delegate: (?:(?! *[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?$))'
174-
files: '^pep-\d+\.(rst|txt)$'
175-
exclude: '^pep-(0451)\.(rst|txt)$'
176-
types: [text]
157+
files: '^peps/pep-\d+\.rst$'
158+
exclude: '^peps/pep-(0451)\.rst$'
177159

178160
- id: validate-discussions-to
179161
name: "'Discussions-To' must be a thread URL"
180162
language: pygrep
181163
entry: '^Discussions-To: (?:(?!([\w\-]+@(python\.org|googlegroups\.com))|https://((discuss\.python\.org/t/([\w\-]+/)?\d+/?)|(mail\.python\.org/pipermail/[\w\-]+/\d{4}-[A-Za-z]+/[A-Za-z0-9]+\.html)|(mail\.python\.org/archives/list/[\w\-]+@python\.org/thread/[A-Za-z0-9]+/?))$))'
182-
files: '^pep-\d+\.(rst|txt)$'
183-
types: [text]
164+
files: '^peps/pep-\d+\.rst$'
184165

185166
- id: validate-status
186167
name: "'Status' must be a valid PEP status"
187168
language: pygrep
188169
entry: '^Status:(?:(?! +(Draft|Withdrawn|Rejected|Accepted|Final|Active|Provisional|Deferred|Superseded|April Fool!)$))'
189-
files: '^pep-\d+\.(rst|txt)$'
190-
types: [text]
170+
files: '^peps/pep-\d+\.rst$'
191171

192172
- id: validate-type
193173
name: "'Type' must be a valid PEP type"
194174
language: pygrep
195175
entry: '^Type:(?:(?! +(Standards Track|Informational|Process)$))'
196-
files: '^pep-\d+\.(rst|txt)$'
197-
types: [text]
176+
files: '^peps/pep-\d+\.rst$'
198177

199178
- id: validate-topic
200179
name: "'Topic' must be for a valid sub-index"
201180
language: pygrep
202181
entry: '^Topic:(?:(?! +(Governance|Packaging|Typing|Release)(, (Governance|Packaging|Typing|Release))*$))'
203-
files: '^pep-\d+\.(rst|txt)$'
204-
types: [text]
182+
files: '^peps/pep-\d+\.rst$'
205183

206184
- id: validate-content-type
207185
name: "'Content-Type' must be 'text/x-rst'"
208186
language: pygrep
209187
entry: '^Content-Type:(?:(?! +text/x-rst$))'
210-
files: '^pep-\d+\.(rst|txt)$'
211-
types: [text]
188+
files: '^peps/pep-\d+\.rst$'
212189

213190
- id: validate-pep-references
214191
name: "`Requires`/`Replaces`/`Superseded-By` must be 'NNN' PEP IDs"
215192
language: pygrep
216193
entry: '^(Requires|Replaces|Superseded-By):(?:(?! *( (0|[1-9][0-9]{0,3})(,|$))+$))'
217-
files: '^pep-\d+\.(rst|txt)$'
218-
types: [text]
194+
files: '^peps/pep-\d+\.rst$'
219195

220196
- id: validate-created
221197
name: "'Created' must be a 'DD-mmm-YYYY' date"
222198
language: pygrep
223199
entry: '^Created:(?:(?! +([0-2][0-9]|(3[01]))-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(199[0-9]|20[0-9][0-9])$))'
224-
files: '^pep-\d+\.(rst|txt)$'
225-
types: [text]
200+
files: '^peps/pep-\d+\.rst$'
226201

227202
- id: validate-python-version
228203
name: "'Python-Version' must be a 'X.Y[.Z]` version"
229204
language: pygrep
230205
entry: '^Python-Version:(?:(?! *( [1-9]\.([0-9][0-9]?|x)(\.[1-9][0-9]?)?(,|$))+$))'
231-
files: '^pep-\d+\.(rst|txt)$'
232-
types: [text]
206+
files: '^peps/pep-\d+\.rst$'
233207

234208
- id: validate-post-history
235209
name: "'Post-History' must be '`DD-mmm-YYYY <Thread URL>`__, ...'"
236210
language: pygrep
237211
entry: '(?<=\n)Post-History:(?:(?! ?\n|((( +|\n {1,14})(([0-2][0-9]|(3[01]))-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(199[0-9]|20[0-9][0-9])|`([0-2][0-9]|(3[01]))-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(199[0-9]|20[0-9][0-9]) <https://((discuss\.python\.org/t/([\w\-]+/)?\d+(?:/\d+/|/?))|(mail\.python\.org/pipermail/[\w\-]+/\d{4}-[A-Za-z]+/[A-Za-z0-9]+\.html)|(mail\.python\.org/archives/list/[\w\-]+@python\.org/thread/[A-Za-z0-9]+/?(#[A-Za-z0-9]+)?))>`__)(,|(?=\n[^ ])))+\n(?=[A-Z\n]))))'
238212
args: [--multiline]
239-
files: '^pep-\d+\.(rst|txt)$'
240-
types: [text]
213+
files: '^peps/pep-\d+\.rst$'
241214

242215
- id: validate-resolution
243216
name: "'Resolution' must be a direct thread/message URL"
244217
language: pygrep
245218
entry: '(?<!\n\n)(?<=\n)Resolution: (?:(?!https://((discuss\.python\.org/t/([\w\-]+/)?\d+(/\d+)?/?)|(mail\.python\.org/pipermail/[\w\-]+/\d{4}-[A-Za-z]+/[A-Za-z0-9]+\.html)|(mail\.python\.org/archives/list/[\w\-]+@python\.org/(message|thread)/[A-Za-z0-9]+/?(#[A-Za-z0-9]+)?))\n))'
246219
args: ['--multiline']
247-
files: '^pep-\d+\.(rst|txt)$'
248-
types: [text]
220+
files: '^peps/pep-\d+\.rst$'
249221

250222
- id: check-direct-pep-links
251223
name: "Check that PEPs aren't linked directly"
252224
language: pygrep
253225
entry: '(dev/peps|peps\.python\.org)/pep-\d+'
254-
files: '^pep-\d+\.(rst|txt)$'
255-
exclude: '^pep-(0009|0287|0676|0684|8001)\.(rst|txt)$'
256-
types: [text]
226+
files: '^peps/pep-\d+\.rst$'
227+
exclude: '^peps/pep-(0009|0287|0676|0684|8001)\.rst$'
257228

258229
- id: check-direct-rfc-links
259230
name: "Check that RFCs aren't linked directly"
260231
language: pygrep
261232
entry: '(rfc-editor\.org|ietf\.org)/[\.\-_\?\&\#\w/]*[Rr][Ff][Cc][\-_]?\d+'
262-
files: '\.(rst|txt)$'
263-
types: [text]
233+
types: ['rst']

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ OUTPUT_DIR = build
1212
SPHINXERRORHANDLING = -W --keep-going -w sphinx-warnings.txt
1313

1414
ALLSPHINXOPTS = -b $(BUILDER) -j $(JOBS) \
15-
$(SPHINXOPTS) $(SPHINXERRORHANDLING) . $(OUTPUT_DIR) $(SOURCES)
15+
$(SPHINXOPTS) $(SPHINXERRORHANDLING) peps $(OUTPUT_DIR) $(SOURCES)
1616

1717
## html to render PEPs to "pep-NNNN.html" files
1818
.PHONY: html

build.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def create_index_file(html_root: Path, builder: str) -> None:
5454
args = create_parser()
5555

5656
root_directory = Path(__file__).resolve().parent
57-
source_directory = root_directory
57+
source_directory = root_directory / "peps"
5858
build_directory = root_directory / args.output_dir
5959

6060
# builder configuration

check-peps.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from __future__ import annotations
1717

1818
import datetime as dt
19-
import itertools
2019
import re
2120
import sys
2221
from pathlib import Path
@@ -32,7 +31,8 @@
3231

3332

3433
# get the directory with the PEP sources
35-
PEP_ROOT = Path(__file__).resolve().parent
34+
ROOT_DIR = Path(__file__).resolve().parent
35+
PEP_ROOT = ROOT_DIR / "peps"
3636

3737
# See PEP 12 for the order
3838
# Note we retain "BDFL-Delegate"
@@ -101,7 +101,7 @@ def check(filenames: Sequence[str] = (), /) -> int:
101101
if filenames:
102102
filenames = map(Path, filenames)
103103
else:
104-
filenames = itertools.chain(PEP_ROOT.glob("pep-????.txt"), PEP_ROOT.glob("pep-????.rst"))
104+
filenames = PEP_ROOT.glob("pep-????.rst")
105105
if (count := sum(map(check_file, filenames))) > 0:
106106
s = "s" * (count != 1)
107107
print(f"check-peps failed: {count} error{s}", file=sys.stderr)
@@ -207,7 +207,7 @@ def check_direct_links(line_num: int, line: str) -> MessageIterator:
207207

208208

209209
def _output_error(filename: Path, lines: Sequence[str], errors: Iterable[Message]) -> int:
210-
relative_filename = filename.relative_to(PEP_ROOT)
210+
relative_filename = filename.relative_to(ROOT_DIR)
211211
err_count = 0
212212
for line_num, msg in errors:
213213
err_count += 1

docs/rendering_system.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ to `PEP 676 <https://peps.python.org/pep-0676/>`__.
1717

1818
Configuration is stored in three files:
1919

20-
- ``conf.py`` contains the majority of the Sphinx configuration
21-
- ``contents.rst`` contains the compulsory table of contents directive
20+
- ``peps/conf.py`` contains the majority of the Sphinx configuration
21+
- ``peps/contents.rst`` contains the compulsory table of contents directive
2222
- ``pep_sphinx_extensions/pep_theme/theme.conf`` sets the Pygments themes
2323

2424
The configuration:
2525

2626
- registers the custom Sphinx extension
27-
- sets both ``.txt`` and ``.rst`` suffixes to be parsed as PEPs
27+
- sets the ``.rst`` suffix to be parsed as PEPs
2828
- tells Sphinx which source files to use
2929
- registers the PEP theme, maths renderer, and template
3030
- disables some default settings that are covered in the extension
@@ -35,7 +35,7 @@ The configuration:
3535
----------------
3636

3737
``build.py`` manages the rendering process.
38-
Usage is covered in :doc:`build`.
38+
Usage is covered in `Building PEPs Locally <./build.rst>`_.
3939

4040

4141
3. Extension

pep_sphinx_extensions/pep_processor/html/pep_html_builder.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from pathlib import Path
2-
31
from docutils import nodes
42
from docutils.frontend import OptionParser
53
from sphinx.builders.html import StandaloneHTMLBuilder
@@ -31,10 +29,6 @@ def get_doc_context(self, docname: str, body: str, _metatags: str) -> dict:
3129
except KeyError:
3230
title = ""
3331

34-
# source filename
35-
file_is_rst = Path(self.env.srcdir, docname + ".rst").exists()
36-
source_name = f"{docname}.rst" if file_is_rst else f"{docname}.txt"
37-
3832
# local table of contents
3933
toc_tree = self.env.tocs[docname].deepcopy()
4034
if len(toc_tree) and len(toc_tree[0]) > 1:
@@ -46,7 +40,7 @@ def get_doc_context(self, docname: str, body: str, _metatags: str) -> dict:
4640
else:
4741
toc = "" # PEPs with no sections -- 9, 210
4842

49-
return {"title": title, "sourcename": source_name, "toc": toc, "body": body}
43+
return {"title": title, "toc": toc, "body": body}
5044

5145

5246
class DirectoryBuilder(FileBuilder):

pep_sphinx_extensions/pep_processor/transforms/pep_footer.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def apply(self) -> None:
5454

5555
def _add_source_link(pep_source_path: Path) -> nodes.paragraph:
5656
"""Add link to source text on VCS (GitHub)"""
57-
source_link = f"https://github.com/python/peps/blob/main/{pep_source_path.name}"
57+
source_link = f"https://github.com/python/peps/blob/main/peps/{pep_source_path.name}"
5858
link_node = nodes.reference("", source_link, refuri=source_link)
5959
return nodes.paragraph("", "Source: ", link_node)
6060

@@ -79,9 +79,12 @@ def _get_last_modified_timestamps():
7979
return {}
8080
all_modified = ret.stdout
8181

82+
# remove "peps/" prefix from file names
83+
all_modified = all_modified.replace("\npeps/", "\n")
84+
8285
# set up the dictionary with the *current* files
83-
peps_dir = Path(__file__, "..", "..", "..", "..").resolve()
84-
last_modified = {path.stem: "" for path in peps_dir.glob("pep-????.???") if path.suffix in {".txt", ".rst"}}
86+
peps_dir = Path(__file__, "..", "..", "..", "..", "peps").resolve()
87+
last_modified = {path.stem: "" for path in peps_dir.glob("pep-????.rst")}
8588

8689
# iterate through newest to oldest, updating per file timestamps
8790
change_sets = all_modified.removeprefix("#").split("#")

pep_sphinx_extensions/pep_theme/templates/page.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ <h1>Python Enhancement Proposals</h1>
4343
<h2>Contents</h2>
4444
{{ toc }}
4545
<br>
46-
{%- if not sourcename.startswith(("pep-0000", "topic")) %}
47-
<a id="source" href="https://github.com/python/peps/blob/main/{{sourcename}}">Page Source (GitHub)</a>
46+
{%- if not pagename.startswith(("pep-0000", "topic")) %}
47+
<a id="source" href="https://github.com/python/peps/blob/main/peps/{{pagename}}.rst">Page Source (GitHub)</a>
4848
{%- endif %}
4949
</nav>
5050
</section>

pep_sphinx_extensions/pep_zero_generator/pep_index_generator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def _parse_peps(path: Path) -> list[parser.PEP]:
4141
continue # Skip directories etc.
4242
if file_path.match("pep-0000*"):
4343
continue # Skip pre-existing PEP 0 files
44-
if file_path.match("pep-????.???") and file_path.suffix in {".txt", ".rst"}:
44+
if file_path.match("pep-????.rst"):
4545
pep = parser.PEP(path.joinpath(file_path).absolute())
4646
peps.append(pep)
4747

pep_sphinx_extensions/tests/conftest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from pathlib import Path
44

55
_ROOT_PATH = Path(__file__, "..", "..", "..").resolve()
6-
PEP_ROOT = _ROOT_PATH
6+
PEP_ROOT = _ROOT_PATH / "peps"
77

88
# Import "check-peps.py" as "check_peps"
99
CHECK_PEPS_PATH = _ROOT_PATH / "check-peps.py"

0 commit comments

Comments
 (0)