From 74d5a8e0ea6eb03aa63a0df3d249302653276739 Mon Sep 17 00:00:00 2001 From: stan Date: Thu, 30 Jan 2025 18:05:29 +0000 Subject: [PATCH 1/8] Revert Availability Directive move --- Doc/conf.py | 1 - Doc/tools/extensions/pyspecific.py | 72 ++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Doc/conf.py b/Doc/conf.py index 1aeecaeb3073f5..2bf10038341d2d 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -23,7 +23,6 @@ # Our custom Sphinx extensions are found in Doc/Tools/extensions/ extensions = [ 'audit_events', - 'availability', 'c_annotations', 'changes', 'glossary_search', diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index f363dfd4216929..2a48b0e0be4697 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -18,6 +18,7 @@ from docutils.utils import unescape from sphinx import addnodes from sphinx.domains.python import PyFunction, PyMethod, PyModule +from sphinx.util import logging from sphinx.locale import _ as sphinx_gettext from sphinx.util.docutils import SphinxDirective @@ -90,6 +91,76 @@ def run(self): return [pnode] +# Support for documenting platform availability + +class Availability(SphinxDirective): + + has_content = True + required_arguments = 1 + optional_arguments = 0 + final_argument_whitespace = True + + # known platform, libc, and threading implementations + known_platforms = frozenset({ + "AIX", "Android", "BSD", "DragonFlyBSD", "Emscripten", "FreeBSD", + "GNU/kFreeBSD", "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", + "Unix", "VxWorks", "WASI", "Windows", "macOS", "iOS", + # libc + "BSD libc", "glibc", "musl", + # POSIX platforms with pthreads + "pthreads", + }) + + def run(self): + availability_ref = ':ref:`Availability `: ' + avail_nodes, avail_msgs = self.state.inline_text( + availability_ref + self.arguments[0], + self.lineno) + pnode = nodes.paragraph(availability_ref + self.arguments[0], + '', *avail_nodes, *avail_msgs) + self.set_source_info(pnode) + cnode = nodes.container("", pnode, classes=["availability"]) + self.set_source_info(cnode) + if self.content: + self.state.nested_parse(self.content, self.content_offset, cnode) + self.parse_platforms() + + return [cnode] + + def parse_platforms(self): + """Parse platform information from arguments + Arguments is a comma-separated string of platforms. A platform may + be prefixed with "not " to indicate that a feature is not available. + Example:: + .. availability:: Windows, Linux >= 4.2, not WASI + Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not + parsed into separate tokens. + """ + platforms = {} + for arg in self.arguments[0].rstrip(".").split(","): + arg = arg.strip() + platform, _, version = arg.partition(" >= ") + if platform.startswith("not "): + version = False + platform = platform[4:] + elif not version: + version = True + platforms[platform] = version + + unknown = set(platforms).difference(self.known_platforms) + if unknown: + cls = type(self) + logger = logging.getLogger(cls.__qualname__) + logger.warning( + f"Unknown platform(s) or syntax '{' '.join(sorted(unknown))}' " + f"in '.. availability:: {self.arguments[0]}', see " + f"{__file__}:{cls.__qualname__}.known_platforms for a set " + "known platforms." + ) + + return platforms + + class PyCoroutineMixin(object): def handle_signature(self, sig, signode): ret = super(PyCoroutineMixin, self).handle_signature(sig, signode) @@ -260,6 +331,7 @@ def setup(app): app.add_role('issue', issue_role) app.add_role('gh', gh_issue_role) app.add_directive('impl-detail', ImplementationDetail) + app.add_directive('availability', Availability) app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature) app.add_object_type('pdbcommand', 'pdbcmd', '%s (pdb command)', parse_pdb_command) app.add_object_type('monitoring-event', 'monitoring-event', '%s (monitoring event)', parse_monitoring_event) From 218f23a5ba3a133a4feef1bf7af4c78e290ec232 Mon Sep 17 00:00:00 2001 From: stan Date: Thu, 30 Jan 2025 18:26:44 +0000 Subject: [PATCH 2/8] Revert "Revert Availability Directive move" This reverts commit 74d5a8e0ea6eb03aa63a0df3d249302653276739. --- Doc/conf.py | 1 + Doc/tools/extensions/pyspecific.py | 72 ------------------------------ 2 files changed, 1 insertion(+), 72 deletions(-) diff --git a/Doc/conf.py b/Doc/conf.py index 2bf10038341d2d..1aeecaeb3073f5 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -23,6 +23,7 @@ # Our custom Sphinx extensions are found in Doc/Tools/extensions/ extensions = [ 'audit_events', + 'availability', 'c_annotations', 'changes', 'glossary_search', diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 2a48b0e0be4697..f363dfd4216929 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -18,7 +18,6 @@ from docutils.utils import unescape from sphinx import addnodes from sphinx.domains.python import PyFunction, PyMethod, PyModule -from sphinx.util import logging from sphinx.locale import _ as sphinx_gettext from sphinx.util.docutils import SphinxDirective @@ -91,76 +90,6 @@ def run(self): return [pnode] -# Support for documenting platform availability - -class Availability(SphinxDirective): - - has_content = True - required_arguments = 1 - optional_arguments = 0 - final_argument_whitespace = True - - # known platform, libc, and threading implementations - known_platforms = frozenset({ - "AIX", "Android", "BSD", "DragonFlyBSD", "Emscripten", "FreeBSD", - "GNU/kFreeBSD", "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", - "Unix", "VxWorks", "WASI", "Windows", "macOS", "iOS", - # libc - "BSD libc", "glibc", "musl", - # POSIX platforms with pthreads - "pthreads", - }) - - def run(self): - availability_ref = ':ref:`Availability `: ' - avail_nodes, avail_msgs = self.state.inline_text( - availability_ref + self.arguments[0], - self.lineno) - pnode = nodes.paragraph(availability_ref + self.arguments[0], - '', *avail_nodes, *avail_msgs) - self.set_source_info(pnode) - cnode = nodes.container("", pnode, classes=["availability"]) - self.set_source_info(cnode) - if self.content: - self.state.nested_parse(self.content, self.content_offset, cnode) - self.parse_platforms() - - return [cnode] - - def parse_platforms(self): - """Parse platform information from arguments - Arguments is a comma-separated string of platforms. A platform may - be prefixed with "not " to indicate that a feature is not available. - Example:: - .. availability:: Windows, Linux >= 4.2, not WASI - Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not - parsed into separate tokens. - """ - platforms = {} - for arg in self.arguments[0].rstrip(".").split(","): - arg = arg.strip() - platform, _, version = arg.partition(" >= ") - if platform.startswith("not "): - version = False - platform = platform[4:] - elif not version: - version = True - platforms[platform] = version - - unknown = set(platforms).difference(self.known_platforms) - if unknown: - cls = type(self) - logger = logging.getLogger(cls.__qualname__) - logger.warning( - f"Unknown platform(s) or syntax '{' '.join(sorted(unknown))}' " - f"in '.. availability:: {self.arguments[0]}', see " - f"{__file__}:{cls.__qualname__}.known_platforms for a set " - "known platforms." - ) - - return platforms - - class PyCoroutineMixin(object): def handle_signature(self, sig, signode): ret = super(PyCoroutineMixin, self).handle_signature(sig, signode) @@ -331,7 +260,6 @@ def setup(app): app.add_role('issue', issue_role) app.add_role('gh', gh_issue_role) app.add_directive('impl-detail', ImplementationDetail) - app.add_directive('availability', Availability) app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature) app.add_object_type('pdbcommand', 'pdbcmd', '%s (pdb command)', parse_pdb_command) app.add_object_type('monitoring-event', 'monitoring-event', '%s (monitoring event)', parse_monitoring_event) From b9f7e04fc4fcc9711fb6f7dc97d4bbae88dbb374 Mon Sep 17 00:00:00 2001 From: stan Date: Thu, 30 Jan 2025 18:28:53 +0000 Subject: [PATCH 3/8] Revert Availability Directive changes --- Doc/tools/extensions/availability.py | 106 ++++++++------------------- 1 file changed, 29 insertions(+), 77 deletions(-) diff --git a/Doc/tools/extensions/availability.py b/Doc/tools/extensions/availability.py index 47833fdcb87590..e19d3b607eb8ba 100644 --- a/Doc/tools/extensions/availability.py +++ b/Doc/tools/extensions/availability.py @@ -9,66 +9,31 @@ from sphinx.util import logging from sphinx.util.docutils import SphinxDirective -if TYPE_CHECKING: - from sphinx.application import Sphinx - from sphinx.util.typing import ExtensionMetadata - -logger = logging.getLogger("availability") - -# known platform, libc, and threading implementations -_PLATFORMS = frozenset({ - "AIX", - "Android", - "BSD", - "DragonFlyBSD", - "Emscripten", - "FreeBSD", - "GNU/kFreeBSD", - "iOS", - "Linux", - "macOS", - "NetBSD", - "OpenBSD", - "POSIX", - "Solaris", - "Unix", - "VxWorks", - "WASI", - "Windows", -}) -_LIBC = frozenset({ - "BSD libc", - "glibc", - "musl", -}) -_THREADING = frozenset({ - # POSIX platforms with pthreads - "pthreads", -}) -KNOWN_PLATFORMS = _PLATFORMS | _LIBC | _THREADING - - class Availability(SphinxDirective): + has_content = True required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True - def run(self) -> list[nodes.container]: - title = "Availability" - refnode = addnodes.pending_xref( - title, - nodes.inline(title, title, classes=["xref", "std", "std-ref"]), - refdoc=self.env.docname, - refdomain="std", - refexplicit=True, - reftarget="availability", - reftype="ref", - refwarn=True, - ) - sep = nodes.Text(": ") - parsed, msgs = self.state.inline_text(self.arguments[0], self.lineno) - pnode = nodes.paragraph(title, "", refnode, sep, *parsed, *msgs) + # known platform, libc, and threading implementations + known_platforms = frozenset({ + "AIX", "Android", "BSD", "DragonFlyBSD", "Emscripten", "FreeBSD", + "GNU/kFreeBSD", "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", + "Unix", "VxWorks", "WASI", "Windows", "macOS", "iOS", + # libc + "BSD libc", "glibc", "musl", + # POSIX platforms with pthreads + "pthreads", + }) + + def run(self): + availability_ref = ':ref:`Availability `: ' + avail_nodes, avail_msgs = self.state.inline_text( + availability_ref + self.arguments[0], + self.lineno) + pnode = nodes.paragraph(availability_ref + self.arguments[0], + '', *avail_nodes, *avail_msgs) self.set_source_info(pnode) cnode = nodes.container("", pnode, classes=["availability"]) self.set_source_info(cnode) @@ -78,16 +43,12 @@ def run(self) -> list[nodes.container]: return [cnode] - def parse_platforms(self) -> dict[str, str | bool]: + def parse_platforms(self): """Parse platform information from arguments - Arguments is a comma-separated string of platforms. A platform may be prefixed with "not " to indicate that a feature is not available. - Example:: - .. availability:: Windows, Linux >= 4.2, not WASI - Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not parsed into separate tokens. """ @@ -97,29 +58,20 @@ def parse_platforms(self) -> dict[str, str | bool]: platform, _, version = arg.partition(" >= ") if platform.startswith("not "): version = False - platform = platform.removeprefix("not ") + platform = platform[4:] elif not version: version = True platforms[platform] = version - if unknown := set(platforms).difference(KNOWN_PLATFORMS): + unknown = set(platforms).difference(self.known_platforms) + if unknown: + cls = type(self) + logger = logging.getLogger(cls.__qualname__) logger.warning( - "Unknown platform%s or syntax '%s' in '.. availability:: %s', " - "see %s:KNOWN_PLATFORMS for a set of known platforms.", - "s" if len(platforms) != 1 else "", - " ".join(sorted(unknown)), - self.arguments[0], - __file__, + f"Unknown platform(s) or syntax '{' '.join(sorted(unknown))}' " + f"in '.. availability:: {self.arguments[0]}', see " + f"{__file__}:{cls.__qualname__}.known_platforms for a set " + "known platforms." ) return platforms - - -def setup(app: Sphinx) -> ExtensionMetadata: - app.add_directive("availability", Availability) - - return { - "version": "1.0", - "parallel_read_safe": True, - "parallel_write_safe": True, - } From 2055ace5753e085d9438aa51d3a9ca2c40663bd5 Mon Sep 17 00:00:00 2001 From: stan Date: Thu, 30 Jan 2025 18:30:16 +0000 Subject: [PATCH 4/8] Add setup --- Doc/tools/extensions/availability.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Doc/tools/extensions/availability.py b/Doc/tools/extensions/availability.py index e19d3b607eb8ba..2b99bd5d496499 100644 --- a/Doc/tools/extensions/availability.py +++ b/Doc/tools/extensions/availability.py @@ -75,3 +75,14 @@ def parse_platforms(self): ) return platforms + + + +def setup(app: Sphinx) -> ExtensionMetadata: + app.add_directive("availability", Availability) + + return { + "version": "1.0", + "parallel_read_safe": True, + "parallel_write_safe": True, + } From fd05919f370bb758916b1944890d89a5465cc457 Mon Sep 17 00:00:00 2001 From: stan Date: Thu, 30 Jan 2025 18:32:24 +0000 Subject: [PATCH 5/8] Clean up Lint --- Doc/tools/extensions/availability.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Doc/tools/extensions/availability.py b/Doc/tools/extensions/availability.py index 2b99bd5d496499..e39daf60a95ed3 100644 --- a/Doc/tools/extensions/availability.py +++ b/Doc/tools/extensions/availability.py @@ -1,14 +1,11 @@ """Support for documenting platform availability""" from __future__ import annotations - -from typing import TYPE_CHECKING - from docutils import nodes -from sphinx import addnodes from sphinx.util import logging from sphinx.util.docutils import SphinxDirective + class Availability(SphinxDirective): has_content = True @@ -77,7 +74,6 @@ def parse_platforms(self): return platforms - def setup(app: Sphinx) -> ExtensionMetadata: app.add_directive("availability", Availability) From 1a95fb618c0823bed5e8670ead72825bed181006 Mon Sep 17 00:00:00 2001 From: stan Date: Thu, 30 Jan 2025 18:36:23 +0000 Subject: [PATCH 6/8] Clean up Lint --- Doc/tools/extensions/availability.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Doc/tools/extensions/availability.py b/Doc/tools/extensions/availability.py index e39daf60a95ed3..5f225469028f91 100644 --- a/Doc/tools/extensions/availability.py +++ b/Doc/tools/extensions/availability.py @@ -2,12 +2,12 @@ from __future__ import annotations from docutils import nodes +from sphinx import addnodes from sphinx.util import logging from sphinx.util.docutils import SphinxDirective class Availability(SphinxDirective): - has_content = True required_arguments = 1 optional_arguments = 0 @@ -42,10 +42,14 @@ def run(self): def parse_platforms(self): """Parse platform information from arguments + Arguments is a comma-separated string of platforms. A platform may be prefixed with "not " to indicate that a feature is not available. + Example:: + .. availability:: Windows, Linux >= 4.2, not WASI + Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not parsed into separate tokens. """ From 2b34fb3ebd03adad9757ebdcc95276e8d73c1e57 Mon Sep 17 00:00:00 2001 From: stan Date: Thu, 30 Jan 2025 18:38:36 +0000 Subject: [PATCH 7/8] Clean up Lint --- Doc/tools/extensions/availability.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/tools/extensions/availability.py b/Doc/tools/extensions/availability.py index 5f225469028f91..e33e93a9412260 100644 --- a/Doc/tools/extensions/availability.py +++ b/Doc/tools/extensions/availability.py @@ -2,10 +2,10 @@ from __future__ import annotations from docutils import nodes -from sphinx import addnodes from sphinx.util import logging from sphinx.util.docutils import SphinxDirective - +from sphinx.application import Sphinx +from sphinx.util.typing import ExtensionMetadata class Availability(SphinxDirective): has_content = True From 60d3f7a0058896ccc73e2d1ff48745bb8ef4cf74 Mon Sep 17 00:00:00 2001 From: stan Date: Thu, 30 Jan 2025 18:40:36 +0000 Subject: [PATCH 8/8] Clean up Lint --- Doc/tools/extensions/availability.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Doc/tools/extensions/availability.py b/Doc/tools/extensions/availability.py index e33e93a9412260..9c1d653c907ad8 100644 --- a/Doc/tools/extensions/availability.py +++ b/Doc/tools/extensions/availability.py @@ -1,11 +1,18 @@ """Support for documenting platform availability""" from __future__ import annotations + +from typing import TYPE_CHECKING + from docutils import nodes +from sphinx import addnodes from sphinx.util import logging from sphinx.util.docutils import SphinxDirective -from sphinx.application import Sphinx -from sphinx.util.typing import ExtensionMetadata + +if TYPE_CHECKING: + from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata + class Availability(SphinxDirective): has_content = True