All PEPs: Move to ``peps/`` folder (#3418)
This commit is contained in:
parent
0f22268963
commit
08d688fdca
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,7 @@ If your PEP is not Standards Track, remove the corresponding section.
|
||||||
## Basic requirements (all PEP Types)
|
## Basic requirements (all PEP Types)
|
||||||
|
|
||||||
* [ ] Read and followed [PEP 1](https://peps.python.org/1) & [PEP 12](https://peps.python.org/12)
|
* [ ] 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
|
* [ ] 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
|
* [ ] 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
|
* [ ] Core dev/PEP editor listed as ``Author`` or ``Sponsor``, and formally confirmed their approval
|
||||||
|
|
|
@ -1,18 +1,24 @@
|
||||||
coverage.xml
|
# PEPs
|
||||||
pep-0000.txt
|
|
||||||
pep-0000.rst
|
pep-0000.rst
|
||||||
pep-????.html
|
|
||||||
peps.rss
|
peps.rss
|
||||||
|
topic
|
||||||
|
/build
|
||||||
|
|
||||||
|
# Bytecode
|
||||||
__pycache__
|
__pycache__
|
||||||
*.pyc
|
*.py[co]
|
||||||
*.pyo
|
|
||||||
|
# Editors
|
||||||
*~
|
*~
|
||||||
*env
|
.idea
|
||||||
.coverage
|
|
||||||
.tox
|
|
||||||
.vscode
|
.vscode
|
||||||
*.swp
|
*.swp
|
||||||
/build
|
|
||||||
/package
|
# Tests
|
||||||
/topic
|
coverage.xml
|
||||||
|
.coverage
|
||||||
|
.tox
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
*env
|
||||||
/venv
|
/venv
|
||||||
|
|
|
@ -82,16 +82,12 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: rst-backticks
|
- id: rst-backticks
|
||||||
name: "Check RST: No single backticks"
|
name: "Check RST: No single backticks"
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
|
||||||
types: [text]
|
|
||||||
- id: rst-inline-touching-normal
|
- id: rst-inline-touching-normal
|
||||||
name: "Check RST: No backticks touching text"
|
name: "Check RST: No backticks touching text"
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
|
||||||
types: [text]
|
|
||||||
- id: rst-directive-colons
|
- id: rst-directive-colons
|
||||||
name: "Check RST: 2 colons after directives"
|
name: "Check RST: 2 colons after directives"
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
|
||||||
types: [text]
|
|
||||||
|
|
||||||
# Manual codespell check
|
# Manual codespell check
|
||||||
- repo: https://github.com/codespell-project/codespell
|
- repo: https://github.com/codespell-project/codespell
|
||||||
|
@ -112,152 +108,126 @@ repos:
|
||||||
# files: "^pep-\d{4}\.(rst|txt)$"
|
# files: "^pep-\d{4}\.(rst|txt)$"
|
||||||
# require_serial: true
|
# 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
|
- id: check-required-headers
|
||||||
name: "PEPs must have all required headers"
|
name: "PEPs must have all required headers"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '(?-m:^PEP:(?=[\s\S]*\nTitle:)(?=[\s\S]*\nAuthor:)(?=[\s\S]*\nStatus:)(?=[\s\S]*\nType:)(?=[\s\S]*\nContent-Type:)(?=[\s\S]*\nCreated:))'
|
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']
|
args: ['--negate', '--multiline']
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: check-header-order
|
- id: check-header-order
|
||||||
name: "PEP header order must follow PEP 12"
|
name: "PEP header order must follow PEP 12"
|
||||||
language: pygrep
|
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'
|
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']
|
args: ['--negate', '--multiline']
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-pep-number
|
- id: validate-pep-number
|
||||||
name: "'PEP' header must be a number 1-9999"
|
name: "'PEP' header must be a number 1-9999"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '(?-m:^PEP:(?:(?! +(0|[1-9][0-9]{0,3})\n)))'
|
entry: '(?-m:^PEP:(?:(?! +(0|[1-9][0-9]{0,3})\n)))'
|
||||||
args: ['--multiline']
|
args: ['--multiline']
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-title
|
- id: validate-title
|
||||||
name: "'Title' must be 1-79 characters"
|
name: "'Title' must be 1-79 characters"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '(?<=\n)Title:(?:(?! +\S.{1,78}\n(?=[A-Z])))'
|
entry: '(?<=\n)Title:(?:(?! +\S.{1,78}\n(?=[A-Z])))'
|
||||||
args: ['--multiline']
|
args: ['--multiline']
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
exclude: '^pep-(0499)\.(rst|txt)$'
|
exclude: '^peps/pep-(0499)\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-author
|
- id: validate-author
|
||||||
name: "'Author' must be list of 'Name <email@example.com>, ...'"
|
name: "'Author' must be list of 'Name <email@example.com>, ...'"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '(?<=\n)Author:(?:(?!((( +|\n {1,8})[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?)(,|(?=\n[^ ])))+\n(?=[A-Z])))'
|
entry: '(?<=\n)Author:(?:(?!((( +|\n {1,8})[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?)(,|(?=\n[^ ])))+\n(?=[A-Z])))'
|
||||||
args: [--multiline]
|
args: ["--multiline"]
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-sponsor
|
- id: validate-sponsor
|
||||||
name: "'Sponsor' must have format 'Name <email@example.com>'"
|
name: "'Sponsor' must have format 'Name <email@example.com>'"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '^Sponsor:(?: (?! *[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?$))'
|
entry: '^Sponsor:(?: (?! *[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?$))'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-delegate
|
- id: validate-delegate
|
||||||
name: "'Delegate' must have format 'Name <email@example.com>'"
|
name: "'Delegate' must have format 'Name <email@example.com>'"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '^(PEP|BDFL)-Delegate: (?:(?! *[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?$))'
|
entry: '^(PEP|BDFL)-Delegate: (?:(?! *[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?$))'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
exclude: '^pep-(0451)\.(rst|txt)$'
|
exclude: '^peps/pep-(0451)\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-discussions-to
|
- id: validate-discussions-to
|
||||||
name: "'Discussions-To' must be a thread URL"
|
name: "'Discussions-To' must be a thread URL"
|
||||||
language: pygrep
|
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]+/?))$))'
|
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)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-status
|
- id: validate-status
|
||||||
name: "'Status' must be a valid PEP status"
|
name: "'Status' must be a valid PEP status"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '^Status:(?:(?! +(Draft|Withdrawn|Rejected|Accepted|Final|Active|Provisional|Deferred|Superseded|April Fool!)$))'
|
entry: '^Status:(?:(?! +(Draft|Withdrawn|Rejected|Accepted|Final|Active|Provisional|Deferred|Superseded|April Fool!)$))'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-type
|
- id: validate-type
|
||||||
name: "'Type' must be a valid PEP type"
|
name: "'Type' must be a valid PEP type"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '^Type:(?:(?! +(Standards Track|Informational|Process)$))'
|
entry: '^Type:(?:(?! +(Standards Track|Informational|Process)$))'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-topic
|
- id: validate-topic
|
||||||
name: "'Topic' must be for a valid sub-index"
|
name: "'Topic' must be for a valid sub-index"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '^Topic:(?:(?! +(Governance|Packaging|Typing|Release)(, (Governance|Packaging|Typing|Release))*$))'
|
entry: '^Topic:(?:(?! +(Governance|Packaging|Typing|Release)(, (Governance|Packaging|Typing|Release))*$))'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-content-type
|
- id: validate-content-type
|
||||||
name: "'Content-Type' must be 'text/x-rst'"
|
name: "'Content-Type' must be 'text/x-rst'"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '^Content-Type:(?:(?! +text/x-rst$))'
|
entry: '^Content-Type:(?:(?! +text/x-rst$))'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-pep-references
|
- id: validate-pep-references
|
||||||
name: "`Requires`/`Replaces`/`Superseded-By` must be 'NNN' PEP IDs"
|
name: "`Requires`/`Replaces`/`Superseded-By` must be 'NNN' PEP IDs"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '^(Requires|Replaces|Superseded-By):(?:(?! *( (0|[1-9][0-9]{0,3})(,|$))+$))'
|
entry: '^(Requires|Replaces|Superseded-By):(?:(?! *( (0|[1-9][0-9]{0,3})(,|$))+$))'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-created
|
- id: validate-created
|
||||||
name: "'Created' must be a 'DD-mmm-YYYY' date"
|
name: "'Created' must be a 'DD-mmm-YYYY' date"
|
||||||
language: pygrep
|
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])$))'
|
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)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-python-version
|
- id: validate-python-version
|
||||||
name: "'Python-Version' must be a 'X.Y[.Z]` version"
|
name: "'Python-Version' must be a 'X.Y[.Z]` version"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '^Python-Version:(?:(?! *( [1-9]\.([0-9][0-9]?|x)(\.[1-9][0-9]?)?(,|$))+$))'
|
entry: '^Python-Version:(?:(?! *( [1-9]\.([0-9][0-9]?|x)(\.[1-9][0-9]?)?(,|$))+$))'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-post-history
|
- id: validate-post-history
|
||||||
name: "'Post-History' must be '`DD-mmm-YYYY <Thread URL>`__, ...'"
|
name: "'Post-History' must be '`DD-mmm-YYYY <Thread URL>`__, ...'"
|
||||||
language: pygrep
|
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]))))'
|
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]
|
args: [--multiline]
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: validate-resolution
|
- id: validate-resolution
|
||||||
name: "'Resolution' must be a direct thread/message URL"
|
name: "'Resolution' must be a direct thread/message URL"
|
||||||
language: pygrep
|
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))'
|
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']
|
args: ['--multiline']
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: check-direct-pep-links
|
- id: check-direct-pep-links
|
||||||
name: "Check that PEPs aren't linked directly"
|
name: "Check that PEPs aren't linked directly"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '(dev/peps|peps\.python\.org)/pep-\d+'
|
entry: '(dev/peps|peps\.python\.org)/pep-\d+'
|
||||||
files: '^pep-\d+\.(rst|txt)$'
|
files: '^peps/pep-\d+\.rst$'
|
||||||
exclude: '^pep-(0009|0287|0676|0684|8001)\.(rst|txt)$'
|
exclude: '^peps/pep-(0009|0287|0676|0684|8001)\.rst$'
|
||||||
types: [text]
|
|
||||||
|
|
||||||
- id: check-direct-rfc-links
|
- id: check-direct-rfc-links
|
||||||
name: "Check that RFCs aren't linked directly"
|
name: "Check that RFCs aren't linked directly"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: '(rfc-editor\.org|ietf\.org)/[\.\-_\?\&\#\w/]*[Rr][Ff][Cc][\-_]?\d+'
|
entry: '(rfc-editor\.org|ietf\.org)/[\.\-_\?\&\#\w/]*[Rr][Ff][Cc][\-_]?\d+'
|
||||||
files: '\.(rst|txt)$'
|
types: ['rst']
|
||||||
types: [text]
|
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -12,7 +12,7 @@ OUTPUT_DIR = build
|
||||||
SPHINXERRORHANDLING = -W --keep-going -w sphinx-warnings.txt
|
SPHINXERRORHANDLING = -W --keep-going -w sphinx-warnings.txt
|
||||||
|
|
||||||
ALLSPHINXOPTS = -b $(BUILDER) -j $(JOBS) \
|
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
|
## html to render PEPs to "pep-NNNN.html" files
|
||||||
.PHONY: html
|
.PHONY: html
|
||||||
|
|
2
build.py
2
build.py
|
@ -54,7 +54,7 @@ if __name__ == "__main__":
|
||||||
args = create_parser()
|
args = create_parser()
|
||||||
|
|
||||||
root_directory = Path(__file__).resolve().parent
|
root_directory = Path(__file__).resolve().parent
|
||||||
source_directory = root_directory
|
source_directory = root_directory / "peps"
|
||||||
build_directory = root_directory / args.output_dir
|
build_directory = root_directory / args.output_dir
|
||||||
|
|
||||||
# builder configuration
|
# builder configuration
|
||||||
|
|
|
@ -16,7 +16,6 @@ Use "--detailed" to show the contents of lines where errors were found.
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import itertools
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -32,7 +31,8 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
|
|
||||||
# get the directory with the PEP sources
|
# 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
|
# See PEP 12 for the order
|
||||||
# Note we retain "BDFL-Delegate"
|
# Note we retain "BDFL-Delegate"
|
||||||
|
@ -101,7 +101,7 @@ def check(filenames: Sequence[str] = (), /) -> int:
|
||||||
if filenames:
|
if filenames:
|
||||||
filenames = map(Path, filenames)
|
filenames = map(Path, filenames)
|
||||||
else:
|
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:
|
if (count := sum(map(check_file, filenames))) > 0:
|
||||||
s = "s" * (count != 1)
|
s = "s" * (count != 1)
|
||||||
print(f"check-peps failed: {count} error{s}", file=sys.stderr)
|
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:
|
||||||
|
|
||||||
|
|
||||||
def _output_error(filename: Path, lines: Sequence[str], errors: Iterable[Message]) -> int:
|
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
|
err_count = 0
|
||||||
for line_num, msg in errors:
|
for line_num, msg in errors:
|
||||||
err_count += 1
|
err_count += 1
|
||||||
|
|
|
@ -17,14 +17,14 @@ to `PEP 676 <https://peps.python.org/pep-0676/>`__.
|
||||||
|
|
||||||
Configuration is stored in three files:
|
Configuration is stored in three files:
|
||||||
|
|
||||||
- ``conf.py`` contains the majority of the Sphinx configuration
|
- ``peps/conf.py`` contains the majority of the Sphinx configuration
|
||||||
- ``contents.rst`` contains the compulsory table of contents directive
|
- ``peps/contents.rst`` contains the compulsory table of contents directive
|
||||||
- ``pep_sphinx_extensions/pep_theme/theme.conf`` sets the Pygments themes
|
- ``pep_sphinx_extensions/pep_theme/theme.conf`` sets the Pygments themes
|
||||||
|
|
||||||
The configuration:
|
The configuration:
|
||||||
|
|
||||||
- registers the custom Sphinx extension
|
- 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
|
- tells Sphinx which source files to use
|
||||||
- registers the PEP theme, maths renderer, and template
|
- registers the PEP theme, maths renderer, and template
|
||||||
- disables some default settings that are covered in the extension
|
- disables some default settings that are covered in the extension
|
||||||
|
@ -35,7 +35,7 @@ The configuration:
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
``build.py`` manages the rendering process.
|
``build.py`` manages the rendering process.
|
||||||
Usage is covered in :doc:`build`.
|
Usage is covered in `Building PEPs Locally <./build.rst>`_.
|
||||||
|
|
||||||
|
|
||||||
3. Extension
|
3. Extension
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.frontend import OptionParser
|
from docutils.frontend import OptionParser
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
|
@ -31,10 +29,6 @@ class FileBuilder(StandaloneHTMLBuilder):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
title = ""
|
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
|
# local table of contents
|
||||||
toc_tree = self.env.tocs[docname].deepcopy()
|
toc_tree = self.env.tocs[docname].deepcopy()
|
||||||
if len(toc_tree) and len(toc_tree[0]) > 1:
|
if len(toc_tree) and len(toc_tree[0]) > 1:
|
||||||
|
@ -46,7 +40,7 @@ class FileBuilder(StandaloneHTMLBuilder):
|
||||||
else:
|
else:
|
||||||
toc = "" # PEPs with no sections -- 9, 210
|
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):
|
class DirectoryBuilder(FileBuilder):
|
||||||
|
|
|
@ -54,7 +54,7 @@ class PEPFooter(transforms.Transform):
|
||||||
|
|
||||||
def _add_source_link(pep_source_path: Path) -> nodes.paragraph:
|
def _add_source_link(pep_source_path: Path) -> nodes.paragraph:
|
||||||
"""Add link to source text on VCS (GitHub)"""
|
"""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)
|
link_node = nodes.reference("", source_link, refuri=source_link)
|
||||||
return nodes.paragraph("", "Source: ", link_node)
|
return nodes.paragraph("", "Source: ", link_node)
|
||||||
|
|
||||||
|
@ -79,9 +79,12 @@ def _get_last_modified_timestamps():
|
||||||
return {}
|
return {}
|
||||||
all_modified = ret.stdout
|
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
|
# set up the dictionary with the *current* files
|
||||||
peps_dir = Path(__file__, "..", "..", "..", "..").resolve()
|
peps_dir = Path(__file__, "..", "..", "..", "..", "peps").resolve()
|
||||||
last_modified = {path.stem: "" for path in peps_dir.glob("pep-????.???") if path.suffix in {".txt", ".rst"}}
|
last_modified = {path.stem: "" for path in peps_dir.glob("pep-????.rst")}
|
||||||
|
|
||||||
# iterate through newest to oldest, updating per file timestamps
|
# iterate through newest to oldest, updating per file timestamps
|
||||||
change_sets = all_modified.removeprefix("#").split("#")
|
change_sets = all_modified.removeprefix("#").split("#")
|
||||||
|
|
|
@ -43,8 +43,8 @@
|
||||||
<h2>Contents</h2>
|
<h2>Contents</h2>
|
||||||
{{ toc }}
|
{{ toc }}
|
||||||
<br>
|
<br>
|
||||||
{%- if not sourcename.startswith(("pep-0000", "topic")) %}
|
{%- if not pagename.startswith(("pep-0000", "topic")) %}
|
||||||
<a id="source" href="https://github.com/python/peps/blob/main/{{sourcename}}">Page Source (GitHub)</a>
|
<a id="source" href="https://github.com/python/peps/blob/main/peps/{{pagename}}.rst">Page Source (GitHub)</a>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
</nav>
|
</nav>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -41,7 +41,7 @@ def _parse_peps(path: Path) -> list[parser.PEP]:
|
||||||
continue # Skip directories etc.
|
continue # Skip directories etc.
|
||||||
if file_path.match("pep-0000*"):
|
if file_path.match("pep-0000*"):
|
||||||
continue # Skip pre-existing PEP 0 files
|
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())
|
pep = parser.PEP(path.joinpath(file_path).absolute())
|
||||||
peps.append(pep)
|
peps.append(pep)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
_ROOT_PATH = Path(__file__, "..", "..", "..").resolve()
|
_ROOT_PATH = Path(__file__, "..", "..", "..").resolve()
|
||||||
PEP_ROOT = _ROOT_PATH
|
PEP_ROOT = _ROOT_PATH / "peps"
|
||||||
|
|
||||||
# Import "check-peps.py" as "check_peps"
|
# Import "check-peps.py" as "check_peps"
|
||||||
CHECK_PEPS_PATH = _ROOT_PATH / "check-peps.py"
|
CHECK_PEPS_PATH = _ROOT_PATH / "check-peps.py"
|
||||||
|
|
|
@ -6,17 +6,17 @@ from ...conftest import PEP_ROOT
|
||||||
|
|
||||||
|
|
||||||
def test_add_source_link():
|
def test_add_source_link():
|
||||||
out = pep_footer._add_source_link(PEP_ROOT / "pep-0008.txt")
|
out = pep_footer._add_source_link(PEP_ROOT / "pep-0008.rst")
|
||||||
|
|
||||||
assert "https://github.com/python/peps/blob/main/pep-0008.txt" in str(out)
|
assert "https://github.com/python/peps/blob/main/peps/pep-0008.rst" in str(out)
|
||||||
|
|
||||||
|
|
||||||
def test_add_commit_history_info():
|
def test_add_commit_history_info():
|
||||||
out = pep_footer._add_commit_history_info(PEP_ROOT / "pep-0008.txt")
|
out = pep_footer._add_commit_history_info(PEP_ROOT / "pep-0008.rst")
|
||||||
|
|
||||||
assert str(out).startswith(
|
assert str(out).startswith(
|
||||||
"<paragraph>Last modified: "
|
"<paragraph>Last modified: "
|
||||||
'<reference refuri="https://github.com/python/peps/commits/main/pep-0008.txt">'
|
'<reference refuri="https://github.com/python/peps/commits/main/pep-0008.rst">'
|
||||||
)
|
)
|
||||||
# A variable timestamp comes next, don't test that
|
# A variable timestamp comes next, don't test that
|
||||||
assert str(out).endswith("</reference></paragraph>")
|
assert str(out).endswith("</reference></paragraph>")
|
||||||
|
|
|
@ -21,27 +21,27 @@ from ..conftest import PEP_ROOT
|
||||||
|
|
||||||
|
|
||||||
def test_pep_repr():
|
def test_pep_repr():
|
||||||
pep8 = parser.PEP(PEP_ROOT / "pep-0008.txt")
|
pep8 = parser.PEP(PEP_ROOT / "pep-0008.rst")
|
||||||
|
|
||||||
assert repr(pep8) == "<PEP 0008 - Style Guide for Python Code>"
|
assert repr(pep8) == "<PEP 0008 - Style Guide for Python Code>"
|
||||||
|
|
||||||
|
|
||||||
def test_pep_less_than():
|
def test_pep_less_than():
|
||||||
pep8 = parser.PEP(PEP_ROOT / "pep-0008.txt")
|
pep8 = parser.PEP(PEP_ROOT / "pep-0008.rst")
|
||||||
pep3333 = parser.PEP(PEP_ROOT / "pep-3333.txt")
|
pep3333 = parser.PEP(PEP_ROOT / "pep-3333.rst")
|
||||||
|
|
||||||
assert pep8 < pep3333
|
assert pep8 < pep3333
|
||||||
|
|
||||||
|
|
||||||
def test_pep_equal():
|
def test_pep_equal():
|
||||||
pep_a = parser.PEP(PEP_ROOT / "pep-0008.txt")
|
pep_a = parser.PEP(PEP_ROOT / "pep-0008.rst")
|
||||||
pep_b = parser.PEP(PEP_ROOT / "pep-0008.txt")
|
pep_b = parser.PEP(PEP_ROOT / "pep-0008.rst")
|
||||||
|
|
||||||
assert pep_a == pep_b
|
assert pep_a == pep_b
|
||||||
|
|
||||||
|
|
||||||
def test_pep_details(monkeypatch):
|
def test_pep_details(monkeypatch):
|
||||||
pep8 = parser.PEP(PEP_ROOT / "pep-0008.txt")
|
pep8 = parser.PEP(PEP_ROOT / "pep-0008.rst")
|
||||||
|
|
||||||
assert pep8.details == {
|
assert pep8.details == {
|
||||||
"authors": "Guido van Rossum, Barry Warsaw, Nick Coghlan",
|
"authors": "Guido van Rossum, Barry Warsaw, Nick Coghlan",
|
||||||
|
@ -106,7 +106,7 @@ def test_parse_authors_invalid():
|
||||||
)
|
)
|
||||||
def test_abbreviate_type_status(test_type, test_status, expected):
|
def test_abbreviate_type_status(test_type, test_status, expected):
|
||||||
# set up dummy PEP object and monkeypatch attributes
|
# set up dummy PEP object and monkeypatch attributes
|
||||||
pep = parser.PEP(PEP_ROOT / "pep-0008.txt")
|
pep = parser.PEP(PEP_ROOT / "pep-0008.rst")
|
||||||
pep.pep_type = test_type
|
pep.pep_type = test_type
|
||||||
pep.status = test_status
|
pep.status = test_status
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from ..conftest import PEP_ROOT
|
||||||
|
|
||||||
|
|
||||||
def test_create_pep_json():
|
def test_create_pep_json():
|
||||||
peps = [parser.PEP(PEP_ROOT / "pep-0008.txt")]
|
peps = [parser.PEP(PEP_ROOT / "pep-0008.rst")]
|
||||||
|
|
||||||
out = pep_index_generator.create_pep_json(peps)
|
out = pep_index_generator.create_pep_json(peps)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
_ROOT = Path(__file__).resolve().parent
|
_ROOT = Path(__file__).resolve().parent.parent
|
||||||
sys.path.append(os.fspath(_ROOT))
|
sys.path.append(os.fspath(_ROOT))
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
@ -27,7 +27,6 @@ extensions = [
|
||||||
# The file extensions of source files. Sphinx uses these suffixes as sources.
|
# The file extensions of source files. Sphinx uses these suffixes as sources.
|
||||||
source_suffix = {
|
source_suffix = {
|
||||||
".rst": "pep",
|
".rst": "pep",
|
||||||
".txt": "pep",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# List of patterns (relative to source dir) to ignore when looking for source files.
|
# List of patterns (relative to source dir) to ignore when looking for source files.
|
||||||
|
@ -36,7 +35,6 @@ include_patterns = [
|
||||||
"contents.rst",
|
"contents.rst",
|
||||||
# PEP files
|
# PEP files
|
||||||
"pep-????.rst",
|
"pep-????.rst",
|
||||||
"pep-????.txt",
|
|
||||||
# PEP ancillary files
|
# PEP ancillary files
|
||||||
"pep-????/*.rst",
|
"pep-????/*.rst",
|
||||||
# Documentation
|
# Documentation
|
|
@ -14,6 +14,5 @@ This is an internal Sphinx page; please go to the :doc:`PEP Index <pep-0000>`.
|
||||||
:glob:
|
:glob:
|
||||||
:caption: PEP Table of Contents (needed for Sphinx):
|
:caption: PEP Table of Contents (needed for Sphinx):
|
||||||
|
|
||||||
docs/*
|
|
||||||
pep-*
|
pep-*
|
||||||
topic/*
|
topic/*
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue