PEP 676: Display mailing list names for thread links in Discussions-To (#2351)

This commit is contained in:
Adam Turner 2022-02-21 21:04:55 +00:00 committed by GitHub
parent 2ff27508fa
commit 7efe7fb433
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 14 deletions

View File

@ -39,12 +39,12 @@ class PEPHeaders(transforms.Transform):
# Extract PEP number
value = pep_field[1].astext()
try:
pep = int(value)
pep_num = int(value)
except ValueError:
raise PEPParsingError(f"'PEP' header must contain an integer. '{value}' is invalid!")
# Special processing for PEP 0.
if pep == 0:
if pep_num == 0:
pending = nodes.pending(pep_zero.PEPZero)
self.document.insert(1, pending)
self.document.note_pending(pending)
@ -71,9 +71,16 @@ class PEPHeaders(transforms.Transform):
if name in {"author", "bdfl-delegate", "pep-delegate", "discussions-to", "sponsor"}:
# mask emails
for node in para:
if isinstance(node, nodes.reference):
pep_num = pep if name == "discussions-to" else None
node.replace_self(_mask_email(node, pep_num))
if not isinstance(node, nodes.reference):
continue
if name == "discussions-to":
if node["refuri"].startswith("http"):
node[0] = _list_name_from_thread(node)
else:
node[0] = _mask_email(node)
node["refuri"] += f"?subject=PEP%20{pep_num}"
else:
node.replace_self(_mask_email(node))
elif name in {"replaces", "superseded-by", "requires"}:
# replace PEP numbers with normalised list of links to PEPs
new_body = []
@ -88,3 +95,22 @@ class PEPHeaders(transforms.Transform):
# Remove unneeded fields
for field in fields_to_remove:
field.parent.remove(field)
def _list_name_from_thread(node: nodes.reference) -> nodes.raw:
# mailman structure is
# https://mail.python.org/archives/list/<list name>/thread/<id>
# pipermail structure is
# https://mail.python.org/pipermail/<list name>/<month-year>/<id>
parts = node[0].split("/")
try:
list_name = parts[parts.index("archives") + 2]
masked_name = list_name.replace("@", "&#32;&#97;t&#32;")
except ValueError:
try:
list_name = parts[parts.index("pipermail") + 1]
masked_name = list_name + "&#32;&#97;t&#32;python.org"
except ValueError:
# archives and pipermail not in list, e.g. PEP 245
return node[0]
return nodes.raw("", masked_name, format="html")

View File

@ -74,7 +74,7 @@ class PEPZeroSpecial(nodes.SparseNodeVisitor):
para[0] = nodes.reference("", pep_str, refuri=ref)
def _mask_email(ref: nodes.reference, pep_num: int | None = None) -> nodes.reference:
def _mask_email(ref: nodes.reference) -> nodes.reference:
"""Mask the email address in `ref` and return a replacement node.
`ref` is returned unchanged if it contains no email address.
@ -82,15 +82,12 @@ def _mask_email(ref: nodes.reference, pep_num: int | None = None) -> nodes.refer
If given an email not explicitly whitelisted, process it such that
`user@host` -> `user at host`.
If given a PEP number `pep_num`, add a default email subject.
The returned node has no refuri link attribute.
"""
if "refuri" not in ref or not ref["refuri"].startswith("mailto:"):
return ref
non_masked_addresses = {"peps@python.org", "python-list@python.org", "python-dev@python.org"}
if ref["refuri"].removeprefix("mailto:").strip() not in non_masked_addresses:
ref[0] = nodes.raw("", ref[0].replace("@", "&#32;&#97;t&#32;"), format="html")
if pep_num is None:
return ref[0] # return email text without mailto link
ref["refuri"] += f"?subject=PEP%20{pep_num}"
return ref
list_name = ref["refuri"].removeprefix("mailto:").strip()
if list_name in {"peps@python.org", "python-list@python.org", "python-dev@python.org"}:
return ref[0]
return nodes.raw("", ref[0].replace("@", "&#32;&#97;t&#32;"), format="html")