Skip to content

Commit

Permalink
PEP 676: Display mailing list names for thread links in Discussions-To (
Browse files Browse the repository at this point in the history
  • Loading branch information
AA-Turner authored Feb 21, 2022
1 parent 2ff2750 commit 7efe7fb
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
36 changes: 31 additions & 5 deletions pep_sphinx_extensions/pep_processor/transforms/pep_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ def apply(self) -> None:
# 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)
Expand All @@ -71,9 +71,16 @@ def apply(self) -> None:
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 = []
Expand All @@ -88,3 +95,22 @@ def apply(self) -> None:
# 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")
15 changes: 6 additions & 9 deletions pep_sphinx_extensions/pep_processor/transforms/pep_zero.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,20 @@ def visit_entry(self, node: nodes.entry) -> None:
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.
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")

0 comments on commit 7efe7fb

Please sign in to comment.