Infra: Link status and type headers to descriptions (#2842)
Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
This commit is contained in:
parent
580f8e3c70
commit
67512a10ea
|
@ -7,7 +7,42 @@ from sphinx import errors
|
|||
|
||||
from pep_sphinx_extensions.pep_processor.transforms import pep_zero
|
||||
from pep_sphinx_extensions.pep_processor.transforms.pep_zero import _mask_email
|
||||
from pep_sphinx_extensions.pep_zero_generator.constants import (
|
||||
SPECIAL_STATUSES,
|
||||
STATUS_ACCEPTED,
|
||||
STATUS_ACTIVE,
|
||||
STATUS_DEFERRED,
|
||||
STATUS_DRAFT,
|
||||
STATUS_FINAL,
|
||||
STATUS_PROVISIONAL,
|
||||
STATUS_REJECTED,
|
||||
STATUS_SUPERSEDED,
|
||||
STATUS_WITHDRAWN,
|
||||
TYPE_INFO,
|
||||
TYPE_PROCESS,
|
||||
TYPE_STANDARDS,
|
||||
)
|
||||
|
||||
ABBREVIATED_STATUSES = {
|
||||
STATUS_DRAFT: "Proposal under active discussion and revision",
|
||||
STATUS_DEFERRED: "Inactive draft that may be taken up again at a later time",
|
||||
STATUS_ACCEPTED: "Normative proposal accepted for implementation",
|
||||
STATUS_ACTIVE: "Currently valid informational guidance, or an in-use process",
|
||||
STATUS_FINAL: "Accepted and implementation complete, or no longer active",
|
||||
STATUS_WITHDRAWN: "Removed from consideration by sponsor or authors",
|
||||
STATUS_REJECTED: "Formally declined and will not be accepted",
|
||||
STATUS_SUPERSEDED: "Replaced by another succeeding PEP",
|
||||
STATUS_PROVISIONAL: "Provisionally accepted but additional feedback needed",
|
||||
}
|
||||
|
||||
ABBREVIATED_TYPES = {
|
||||
TYPE_STANDARDS: "Normative PEP with a new feature for Python, implementation "
|
||||
"change for CPython or interoperability standard for the ecosystem",
|
||||
TYPE_INFO: "Non-normative PEP containing background, guidelines or other "
|
||||
"information relevant to the Python ecosystem",
|
||||
TYPE_PROCESS: "Normative PEP describing or proposing a change to a Python "
|
||||
"community process, workflow or governance",
|
||||
}
|
||||
|
||||
class PEPParsingError(errors.SphinxError):
|
||||
pass
|
||||
|
@ -109,6 +144,22 @@ class PEPHeaders(transforms.Transform):
|
|||
]
|
||||
if new_body:
|
||||
para[:] = new_body[:-1] # Drop trailing space/comma
|
||||
elif name == "status":
|
||||
para[:] = [
|
||||
nodes.abbreviation(
|
||||
body.astext(),
|
||||
body.astext(),
|
||||
explanation=_abbreviate_status(body.astext()),
|
||||
)
|
||||
]
|
||||
elif name == "type":
|
||||
para[:] = [
|
||||
nodes.abbreviation(
|
||||
body.astext(),
|
||||
body.astext(),
|
||||
explanation=_abbreviate_type(body.astext()),
|
||||
)
|
||||
]
|
||||
elif name in {"last-modified", "content-type", "version"}:
|
||||
# Mark unneeded fields
|
||||
fields_to_remove.append(field)
|
||||
|
@ -223,3 +274,20 @@ def _process_pretty_url(url: str) -> tuple[str, str]:
|
|||
def _make_link_pretty(url: str) -> str:
|
||||
item_name, item_type = _process_pretty_url(url)
|
||||
return f"{item_name} {item_type}"
|
||||
|
||||
|
||||
def _abbreviate_status(status: str) -> str:
|
||||
if status in SPECIAL_STATUSES:
|
||||
status = SPECIAL_STATUSES[status]
|
||||
|
||||
try:
|
||||
return ABBREVIATED_STATUSES[status]
|
||||
except KeyError:
|
||||
raise PEPParsingError(f"Unknown status: {status}")
|
||||
|
||||
|
||||
def _abbreviate_type(type_: str) -> str:
|
||||
try:
|
||||
return ABBREVIATED_TYPES[type_]
|
||||
except KeyError:
|
||||
raise PEPParsingError(f"Unknown type: {type_}")
|
||||
|
|
|
@ -19,8 +19,8 @@ STATUS_VALUES = {
|
|||
SPECIAL_STATUSES = {
|
||||
"April Fool!": STATUS_REJECTED, # See PEP 401 :)
|
||||
}
|
||||
# Draft PEPs have no status displayed, Active shares a key with Accepted
|
||||
HIDE_STATUS = {STATUS_DRAFT, STATUS_ACTIVE}
|
||||
# Draft PEPs have no status displayed
|
||||
HIDE_STATUS = {STATUS_DRAFT}
|
||||
# Dead PEP statuses
|
||||
DEAD_STATUSES = {STATUS_REJECTED, STATUS_WITHDRAWN, STATUS_SUPERSEDED}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ class PEP:
|
|||
"""Return reStructuredText tooltip for the PEP type and status."""
|
||||
type_code = self.pep_type[0].upper()
|
||||
if self.status in HIDE_STATUS:
|
||||
return f":abbr:`{type_code} ({self.pep_type})`"
|
||||
return f":abbr:`{type_code} ({self.pep_type}, {self.status})`"
|
||||
status_code = self.status[0].upper()
|
||||
return f":abbr:`{type_code}{status_code} ({self.pep_type}, {self.status})`"
|
||||
|
||||
|
|
|
@ -6,8 +6,11 @@ import datetime
|
|||
from typing import TYPE_CHECKING
|
||||
import unicodedata
|
||||
|
||||
from pep_sphinx_extensions.pep_processor.transforms.pep_headers import (
|
||||
ABBREVIATED_STATUSES,
|
||||
ABBREVIATED_TYPES,
|
||||
)
|
||||
from pep_sphinx_extensions.pep_zero_generator.constants import DEAD_STATUSES
|
||||
from pep_sphinx_extensions.pep_zero_generator.constants import HIDE_STATUS
|
||||
from pep_sphinx_extensions.pep_zero_generator.constants import STATUS_ACCEPTED
|
||||
from pep_sphinx_extensions.pep_zero_generator.constants import STATUS_ACTIVE
|
||||
from pep_sphinx_extensions.pep_zero_generator.constants import STATUS_DEFERRED
|
||||
|
@ -177,24 +180,25 @@ class PEPZeroWriter:
|
|||
# PEP types key
|
||||
self.emit_title("PEP Types Key")
|
||||
for type_ in sorted(TYPE_VALUES):
|
||||
self.emit_text(f" {type_[0]} - {type_} PEP")
|
||||
self.emit_text(
|
||||
f"* **{type_[0]}** --- *{type_}*: {ABBREVIATED_TYPES[type_]}"
|
||||
)
|
||||
self.emit_newline()
|
||||
|
||||
self.emit_text(":pep:`More info in PEP 1 <1#pep-types>`.")
|
||||
self.emit_newline()
|
||||
|
||||
# PEP status key
|
||||
self.emit_title("PEP Status Key")
|
||||
for status in sorted(STATUS_VALUES):
|
||||
# Draft PEPs have no status displayed, Active shares a key with Accepted
|
||||
if status in HIDE_STATUS:
|
||||
continue
|
||||
if status == STATUS_ACCEPTED:
|
||||
msg = " A - Accepted (Standards Track only) or Active proposal"
|
||||
else:
|
||||
msg = f" {status[0]} - {status} proposal"
|
||||
self.emit_text(msg)
|
||||
status_code = "<No letter>" if status == STATUS_DRAFT else status[0]
|
||||
self.emit_text(
|
||||
f"* **{status_code}** --- *{status}*: {ABBREVIATED_STATUSES[status]}"
|
||||
)
|
||||
self.emit_newline()
|
||||
|
||||
self.emit_text(":pep:`More info in PEP 1 <1#pep-review-resolution>`.")
|
||||
self.emit_newline()
|
||||
|
||||
if is_pep0:
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
import pytest
|
||||
|
||||
from pep_sphinx_extensions.pep_processor.transforms import pep_headers
|
||||
from pep_sphinx_extensions.pep_zero_generator.constants import (
|
||||
STATUS_ACCEPTED,
|
||||
STATUS_ACTIVE,
|
||||
STATUS_DEFERRED,
|
||||
STATUS_DRAFT,
|
||||
STATUS_FINAL,
|
||||
STATUS_PROVISIONAL,
|
||||
STATUS_REJECTED,
|
||||
STATUS_SUPERSEDED,
|
||||
STATUS_WITHDRAWN,
|
||||
TYPE_INFO,
|
||||
TYPE_PROCESS,
|
||||
TYPE_STANDARDS,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -112,3 +126,60 @@ def test_make_link_pretty(test_input, expected):
|
|||
out = pep_headers._make_link_pretty(test_input)
|
||||
|
||||
assert out == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(STATUS_ACCEPTED, "Normative proposal accepted for implementation"),
|
||||
(STATUS_ACTIVE, "Currently valid informational guidance, or an in-use process"),
|
||||
(STATUS_DEFERRED, "Inactive draft that may be taken up again at a later time"),
|
||||
(STATUS_DRAFT, "Proposal under active discussion and revision"),
|
||||
(STATUS_FINAL, "Accepted and implementation complete, or no longer active"),
|
||||
(STATUS_REJECTED, "Formally declined and will not be accepted"),
|
||||
("April Fool!", "Formally declined and will not be accepted"),
|
||||
(STATUS_SUPERSEDED, "Replaced by another succeeding PEP"),
|
||||
(STATUS_WITHDRAWN, "Removed from consideration by sponsor or authors"),
|
||||
(STATUS_PROVISIONAL, "Provisionally accepted but additional feedback needed"),
|
||||
],
|
||||
)
|
||||
def test_abbreviate_status(test_input, expected):
|
||||
out = pep_headers._abbreviate_status(test_input)
|
||||
|
||||
assert out == expected
|
||||
|
||||
|
||||
def test_abbreviate_status_unknown():
|
||||
with pytest.raises(pep_headers.PEPParsingError):
|
||||
pep_headers._abbreviate_status("an unknown status")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected",
|
||||
[
|
||||
(
|
||||
TYPE_INFO,
|
||||
"Non-normative PEP containing background, guidelines or other information "
|
||||
"relevant to the Python ecosystem",
|
||||
),
|
||||
(
|
||||
TYPE_PROCESS,
|
||||
"Normative PEP describing or proposing a change to a Python community "
|
||||
"process, workflow or governance",
|
||||
),
|
||||
(
|
||||
TYPE_STANDARDS,
|
||||
"Normative PEP with a new feature for Python, implementation change for "
|
||||
"CPython or interoperability standard for the ecosystem",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_abbreviate_type(test_input, expected):
|
||||
out = pep_headers._abbreviate_type(test_input)
|
||||
|
||||
assert out == expected
|
||||
|
||||
|
||||
def test_abbreviate_type_unknown():
|
||||
with pytest.raises(pep_headers.PEPParsingError):
|
||||
pep_headers._abbreviate_type("an unknown type")
|
||||
|
|
|
@ -48,7 +48,7 @@ def test_pep_details(monkeypatch):
|
|||
assert pep8.details == {
|
||||
"authors": "GvR, Warsaw, Coghlan",
|
||||
"number": 8,
|
||||
"shorthand": ":abbr:`P (Process)`",
|
||||
"shorthand": ":abbr:`PA (Process, Active)`",
|
||||
"title": "Style Guide for Python Code",
|
||||
}
|
||||
|
||||
|
@ -97,12 +97,12 @@ def test_parse_authors_invalid():
|
|||
@pytest.mark.parametrize(
|
||||
"test_type, test_status, expected",
|
||||
[
|
||||
(TYPE_INFO, STATUS_DRAFT, ":abbr:`I (Informational)`"),
|
||||
(TYPE_INFO, STATUS_ACTIVE, ":abbr:`I (Informational)`"),
|
||||
(TYPE_INFO, STATUS_DRAFT, ":abbr:`I (Informational, Draft)`"),
|
||||
(TYPE_INFO, STATUS_ACTIVE, ":abbr:`IA (Informational, Active)`"),
|
||||
(TYPE_INFO, STATUS_ACCEPTED, ":abbr:`IA (Informational, Accepted)`"),
|
||||
(TYPE_INFO, STATUS_DEFERRED, ":abbr:`ID (Informational, Deferred)`"),
|
||||
(TYPE_PROCESS, STATUS_ACCEPTED, ":abbr:`PA (Process, Accepted)`"),
|
||||
(TYPE_PROCESS, STATUS_ACTIVE, ":abbr:`P (Process)`"),
|
||||
(TYPE_PROCESS, STATUS_ACTIVE, ":abbr:`PA (Process, Active)`"),
|
||||
(TYPE_PROCESS, STATUS_FINAL, ":abbr:`PF (Process, Final)`"),
|
||||
(TYPE_PROCESS, STATUS_SUPERSEDED, ":abbr:`PS (Process, Superseded)`"),
|
||||
(TYPE_PROCESS, STATUS_WITHDRAWN, ":abbr:`PW (Process, Withdrawn)`"),
|
||||
|
|
Loading…
Reference in New Issue