Skip to content

Commit

Permalink
All PEPs: Move to peps/ folder (#3418)
Browse files Browse the repository at this point in the history
  • Loading branch information
AA-Turner committed Sep 9, 2023
1 parent 0f22268 commit 08d688f
Show file tree
Hide file tree
Showing 678 changed files with 732 additions and 762 deletions.
1,310 changes: 655 additions & 655 deletions .github/CODEOWNERS

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE/Add a new PEP.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 10,7 @@ If your PEP is not Standards Track, remove the corresponding section.
## Basic requirements (all PEP Types)

* [ ] Read and followed [PEP 1](https://peps.python.org/1) & [PEP 12](https://peps.python.org/12)
* [ ] File created from the [latest PEP template](https://github.com/python/peps/blob/main/pep-0012/pep-NNNN.rst?plain=1)
* [ ] File created from the [latest PEP template](https://github.com/python/peps/blob/main/peps/pep-0012/pep-NNNN.rst?plain=1)
* [ ] PEP has next available number, & set in filename (``pep-NNNN.rst``), PR title (``PEP 123: <Title of PEP>``) and ``PEP`` header
* [ ] Title clearly, accurately and concisely describes the content in 79 characters or less
* [ ] Core dev/PEP editor listed as ``Author`` or ``Sponsor``, and formally confirmed their approval
Expand Down
28 changes: 17 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,18 1,24 @@
coverage.xml
pep-0000.txt
# PEPs
pep-0000.rst
pep-????.html
peps.rss
topic
/build

# Bytecode
__pycache__
*.pyc
*.pyo
*.py[co]

# Editors
*~
*env
.coverage
.tox
.idea
.vscode
*.swp
/build
/package
/topic

# Tests
coverage.xml
.coverage
.tox

# Virtual environments
*env
/venv
80 changes: 25 additions & 55 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 82,12 @@ repos:
hooks:
- id: rst-backticks
name: "Check RST: No single backticks"
files: '^pep-\d \.(rst|txt)$'
types: [text]

- id: rst-inline-touching-normal
name: "Check RST: No backticks touching text"
files: '^pep-\d \.(rst|txt)$'
types: [text]

- id: rst-directive-colons
name: "Check RST: 2 colons after directives"
files: '^pep-\d \.(rst|txt)$'
types: [text]

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

- id: check-no-tabs
name: "Check tabs not used in PEPs"
language: pygrep
entry: '\t'
files: '^pep-\d \.(rst|txt)$'
types: [text]

- id: check-required-headers
name: "PEPs must have all required headers"
language: pygrep
entry: '(?-m:^PEP:(?=[\s\S]*\nTitle:)(?=[\s\S]*\nAuthor:)(?=[\s\S]*\nStatus:)(?=[\s\S]*\nType:)(?=[\s\S]*\nContent-Type:)(?=[\s\S]*\nCreated:))'
args: ['--negate', '--multiline']
files: '^pep-\d \.(rst|txt)$'
types: [text]
files: '^peps/pep-\d \.rst$'

- id: check-header-order
name: "PEP header order must follow PEP 12"
language: pygrep
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'
args: ['--negate', '--multiline']
files: '^pep-\d \.(rst|txt)$'
types: [text]
files: '^peps/pep-\d \.rst$'

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

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

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

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

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

- id: validate-discussions-to
name: "'Discussions-To' must be a thread URL"
language: pygrep
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] /?))$))'
files: '^pep-\d \.(rst|txt)$'
types: [text]
files: '^peps/pep-\d \.rst$'

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

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

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

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

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

- id: validate-created
name: "'Created' must be a 'DD-mmm-YYYY' date"
language: pygrep
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])$))'
files: '^pep-\d \.(rst|txt)$'
types: [text]
files: '^peps/pep-\d \.rst$'

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

- id: validate-post-history
name: "'Post-History' must be '`DD-mmm-YYYY <Thread URL>`__, ...'"
language: pygrep
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]))))'
args: [--multiline]
files: '^pep-\d \.(rst|txt)$'
types: [text]
files: '^peps/pep-\d \.rst$'

- id: validate-resolution
name: "'Resolution' must be a direct thread/message URL"
language: pygrep
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))'
args: ['--multiline']
files: '^pep-\d \.(rst|txt)$'
types: [text]
files: '^peps/pep-\d \.rst$'

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

- id: check-direct-rfc-links
name: "Check that RFCs aren't linked directly"
language: pygrep
entry: '(rfc-editor\.org|ietf\.org)/[\.\-_\?\&\#\w/]*[Rr][Ff][Cc][\-_]?\d '
files: '\.(rst|txt)$'
types: [text]
types: ['rst']
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 12,7 @@ OUTPUT_DIR = build
SPHINXERRORHANDLING = -W --keep-going -w sphinx-warnings.txt

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

## html to render PEPs to "pep-NNNN.html" files
.PHONY: html
Expand Down
2 changes: 1 addition & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 54,7 @@ def create_index_file(html_root: Path, builder: str) -> None:
args = create_parser()

root_directory = Path(__file__).resolve().parent
source_directory = root_directory
source_directory = root_directory / "peps"
build_directory = root_directory / args.output_dir

# builder configuration
Expand Down
8 changes: 4 additions & 4 deletions check-peps.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 16,6 @@
from __future__ import annotations

import datetime as dt
import itertools
import re
import sys
from pathlib import Path
Expand All @@ -32,7 31,8 @@


# get the directory with the PEP sources
PEP_ROOT = Path(__file__).resolve().parent
ROOT_DIR = Path(__file__).resolve().parent
PEP_ROOT = ROOT_DIR / "peps"

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


def _output_error(filename: Path, lines: Sequence[str], errors: Iterable[Message]) -> int:
relative_filename = filename.relative_to(PEP_ROOT)
relative_filename = filename.relative_to(ROOT_DIR)
err_count = 0
for line_num, msg in errors:
err_count = 1
Expand Down
8 changes: 4 additions & 4 deletions docs/rendering_system.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 17,14 @@ to `PEP 676 <https://peps.python.org/pep-0676/>`__.

Configuration is stored in three files:

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

The configuration:

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

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


3. Extension
Expand Down
8 changes: 1 addition & 7 deletions pep_sphinx_extensions/pep_processor/html/pep_html_builder.py
Original file line number Diff line number Diff line change
@@ -1,5 1,3 @@
from pathlib import Path

from docutils import nodes
from docutils.frontend import OptionParser
from sphinx.builders.html import StandaloneHTMLBuilder
Expand Down Expand Up @@ -31,10 29,6 @@ def get_doc_context(self, docname: str, body: str, _metatags: str) -> dict:
except KeyError:
title = ""

# source filename
file_is_rst = Path(self.env.srcdir, docname ".rst").exists()
source_name = f"{docname}.rst" if file_is_rst else f"{docname}.txt"

# local table of contents
toc_tree = self.env.tocs[docname].deepcopy()
if len(toc_tree) and len(toc_tree[0]) > 1:
Expand All @@ -46,7 40,7 @@ def get_doc_context(self, docname: str, body: str, _metatags: str) -> dict:
else:
toc = "" # PEPs with no sections -- 9, 210

return {"title": title, "sourcename": source_name, "toc": toc, "body": body}
return {"title": title, "toc": toc, "body": body}


class DirectoryBuilder(FileBuilder):
Expand Down
9 changes: 6 additions & 3 deletions pep_sphinx_extensions/pep_processor/transforms/pep_footer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 54,7 @@ def apply(self) -> None:

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

Expand All @@ -79,9 79,12 @@ def _get_last_modified_timestamps():
return {}
all_modified = ret.stdout

# remove "peps/" prefix from file names
all_modified = all_modified.replace("\npeps/", "\n")

# set up the dictionary with the *current* files
peps_dir = Path(__file__, "..", "..", "..", "..").resolve()
last_modified = {path.stem: "" for path in peps_dir.glob("pep-????.???") if path.suffix in {".txt", ".rst"}}
peps_dir = Path(__file__, "..", "..", "..", "..", "peps").resolve()
last_modified = {path.stem: "" for path in peps_dir.glob("pep-????.rst")}

# iterate through newest to oldest, updating per file timestamps
change_sets = all_modified.removeprefix("#").split("#")
Expand Down
4 changes: 2 additions & 2 deletions pep_sphinx_extensions/pep_theme/templates/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 43,8 @@ <h1>Python Enhancement Proposals</h1>
<h2>Contents</h2>
{{ toc }}
<br>
{%- if not sourcename.startswith(("pep-0000", "topic")) %}
<a id="source" href="https://github.com/python/peps/blob/main/{{sourcename}}">Page Source (GitHub)</a>
{%- if not pagename.startswith(("pep-0000", "topic")) %}
<a id="source" href="https://github.com/python/peps/blob/main/peps/{{pagename}}.rst">Page Source (GitHub)</a>
{%- endif %}
</nav>
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 41,7 @@ def _parse_peps(path: Path) -> list[parser.PEP]:
continue # Skip directories etc.
if file_path.match("pep-0000*"):
continue # Skip pre-existing PEP 0 files
if file_path.match("pep-????.???") and file_path.suffix in {".txt", ".rst"}:
if file_path.match("pep-????.rst"):
pep = parser.PEP(path.joinpath(file_path).absolute())
peps.append(pep)

Expand Down
2 changes: 1 addition & 1 deletion pep_sphinx_extensions/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 3,7 @@
from pathlib import Path

_ROOT_PATH = Path(__file__, "..", "..", "..").resolve()
PEP_ROOT = _ROOT_PATH
PEP_ROOT = _ROOT_PATH / "peps"

# Import "check-peps.py" as "check_peps"
CHECK_PEPS_PATH = _ROOT_PATH / "check-peps.py"
Expand Down
Loading

0 comments on commit 08d688f

Please sign in to comment.