From 7efe7fb43324a6a5f294c7fde0bf1089ae753d7d Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Mon, 21 Feb 2022 21:04:55 +0000 Subject: [PATCH] PEP 676: Display mailing list names for thread links in Discussions-To (#2351) --- .../pep_processor/transforms/pep_headers.py | 36 ++++++++++++++++--- .../pep_processor/transforms/pep_zero.py | 15 ++++---- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/pep_sphinx_extensions/pep_processor/transforms/pep_headers.py b/pep_sphinx_extensions/pep_processor/transforms/pep_headers.py index efc1b87c0..7f2f905e4 100644 --- a/pep_sphinx_extensions/pep_processor/transforms/pep_headers.py +++ b/pep_sphinx_extensions/pep_processor/transforms/pep_headers.py @@ -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//thread/ + # pipermail structure is + # https://mail.python.org/pipermail/// + parts = node[0].split("/") + try: + list_name = parts[parts.index("archives") + 2] + masked_name = list_name.replace("@", " at ") + except ValueError: + try: + list_name = parts[parts.index("pipermail") + 1] + masked_name = list_name + " at python.org" + except ValueError: + # archives and pipermail not in list, e.g. PEP 245 + return node[0] + return nodes.raw("", masked_name, format="html") diff --git a/pep_sphinx_extensions/pep_processor/transforms/pep_zero.py b/pep_sphinx_extensions/pep_processor/transforms/pep_zero.py index 25a2082ab..204937fc3 100644 --- a/pep_sphinx_extensions/pep_processor/transforms/pep_zero.py +++ b/pep_sphinx_extensions/pep_processor/transforms/pep_zero.py @@ -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("@", " at "), 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("@", " at "), format="html")