Skip to content

Commit 572141b

Browse files
Daniel A. Wozniakdwoz
authored andcommitted
Prune unused defensive workarounds added during theme migration
Iterative debugging of the PyData theme migration left several overlapping defenses that the final CI-green build does not need: - doc/conf.py: - Tighten urllib.parse.urlsplit patch to ValueError("Invalid IPv6 URL") only; drop the broadened "except Exception" handler. - Drop the duplicate urlparse patch; only urlsplit raises on the bracketed-host placeholders we hit. - Drop the sys.modules sweep that re-bound already-imported references; patching at module top-of-file before any heavy imports is enough. - Drop the pydata_sphinx_theme.short_link no-op monkeypatch; the "shorten_urls": False theme option already disables it. - Drop the urllib3 and requests.packages.urllib3 parse_url patches; the docs build does not hit either path. - Drop the manual sys.modules["cgi"] mock; autodoc_mock_imports handles it. - Drop the warnings.filterwarnings(SyntaxWarning) global; sphinx -W does not promote Python SyntaxWarnings to build errors. - Restore ReleasesTree.run to the original implementation (no swallow-all try/except) and the missing-deps log call to warning. - salt/modules/file.py, salt/states/mysql_grants.py: revert docstrings to triple-quoted (not r"""); they are unrelated to the docs build. - salt/modules/gem.py, salt/states/gem.py, salt/transport/zeromq.py: revert the URL/identifier reformatting that was added to work around the now-disabled URL shortener. Verified locally with the CI invocation under a python3.14 venv built from requirements/static/ci/py3.14/docs.txt: cd doc && make clean make html SPHINXOPTS='-W -j auto --keep-going --color' make man SPHINXOPTS='-W -j auto --keep-going --color' Both builds succeed with -W strict mode.
1 parent fa5c17e commit 572141b

6 files changed

Lines changed: 23 additions & 102 deletions

File tree

doc/conf.py

Lines changed: 16 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2,102 +2,27 @@
22
"""
33
Sphinx documentation for Salt
44
"""
5-
import logging
65
import os
76
import sys
87
import urllib.parse
9-
import warnings
108

11-
# Suppress SyntaxWarnings (invalid escape sequences) which become errors in CI with -W
12-
# We fix these as we find them, but this prevents "flickering" crashes in large-scale builds.
13-
warnings.filterwarnings("ignore", category=SyntaxWarning)
14-
15-
# Fix urllib.parse.urlsplit/urlparse bug (Invalid IPv6 URL)
16-
# This bug causes Sphinx to crash when encountering documentation examples
17-
# like http://hostname[:port] which are incorrectly parsed as malformed IPv6 URLs.
18-
# We patch it globally to ensure all extensions (like pydata-sphinx-theme) are safe.
9+
# Sphinx crashes parsing docstring URLs like ``http://hostname[:port]`` because
10+
# urllib.parse.urlsplit raises ValueError("Invalid IPv6 URL") on the bracketed
11+
# host placeholder. Return a dummy SplitResult for that one case so the build
12+
# can proceed.
1913
_original_urlsplit = urllib.parse.urlsplit
20-
_original_urlparse = urllib.parse.urlparse
21-
log = logging.getLogger("salt.docs.conf")
2214

2315

2416
def _safe_urlsplit(url, scheme="", allow_fragments=True):
2517
try:
2618
return _original_urlsplit(url, scheme, allow_fragments)
27-
except Exception:
28-
# Return a safe dummy SplitResult for ANY error
29-
return urllib.parse.SplitResult(scheme, "invalid-url", str(url), "", "")
30-
31-
32-
def _safe_urlparse(url, scheme="", allow_fragments=True):
33-
try:
34-
return _original_urlparse(url, scheme, allow_fragments)
35-
except Exception:
36-
# Return a safe dummy ParseResult for ANY error
37-
return urllib.parse.ParseResult(scheme, "invalid-url", str(url), "", "", "")
19+
except ValueError as exc:
20+
if "Invalid IPv6 URL" in str(exc):
21+
return urllib.parse.SplitResult(scheme, "", url, "", "")
22+
raise
3823

3924

4025
urllib.parse.urlsplit = _safe_urlsplit
41-
urllib.parse.urlparse = _safe_urlparse
42-
43-
# Ensure any modules that already imported urlsplit or urlparse also use the patched versions.
44-
for mod in list(sys.modules.values()):
45-
if mod:
46-
if hasattr(mod, "urlsplit") and mod.urlsplit is _original_urlsplit:
47-
mod.urlsplit = _safe_urlsplit
48-
if hasattr(mod, "urlparse") and mod.urlparse is _original_urlparse:
49-
mod.urlparse = _safe_urlparse
50-
51-
# Force disable pydata_sphinx_theme link shortener as it's prone to crashing on Salt docs
52-
try:
53-
import pydata_sphinx_theme.short_link
54-
55-
def _no_op_run(self, **kwargs):
56-
pass
57-
58-
pydata_sphinx_theme.short_link.ShortenLinkTransform.run = _no_op_run
59-
except ImportError:
60-
pass
61-
62-
# Manual mock for 'cgi' module which was removed in Python 3.13
63-
# This is required because some Salt modules import it at the top level,
64-
# and autodoc_mock_imports is sometimes too late or insufficient.
65-
import unittest.mock
66-
67-
sys.modules["cgi"] = unittest.mock.MagicMock()
68-
69-
70-
# Patch urllib3 if it's available, as it has its own unsafe URL parsing
71-
def _patch_urllib3(module):
72-
try:
73-
_original_parse_url = module.util.url.parse_url
74-
75-
def _safe_parse_url(url):
76-
try:
77-
return _original_parse_url(url)
78-
except (ValueError, AttributeError):
79-
log.debug("urllib3 detected malformed URL: %s", url)
80-
# Return a safe dummy Url object
81-
return module.util.url.Url(path=url)
82-
83-
module.util.url.parse_url = _safe_parse_url
84-
except (ImportError, AttributeError):
85-
pass
86-
87-
88-
try:
89-
import urllib3
90-
91-
_patch_urllib3(urllib3)
92-
except ImportError:
93-
pass
94-
95-
try:
96-
import requests.packages.urllib3 as requests_urllib3
97-
98-
_patch_urllib3(requests_urllib3)
99-
except (ImportError, AttributeError):
100-
pass
10126

10227
import pathlib
10328
import re
@@ -310,11 +235,11 @@ def _safe_parse_url(url):
310235
", ".join(_missing_deps),
311236
)
312237
else:
313-
# For HTML/full builds, log info that docs may be incomplete
314-
log.info(
238+
# For HTML/full builds, warn that docs may be incomplete
239+
log.warning(
315240
"\n"
316241
"=" * 70 + "\n"
317-
"INFO: Missing optional dependencies for full documentation build:\n"
242+
"WARNING: Missing dependencies for full documentation build:\n"
318243
" %s\n\n"
319244
"Autodoc will use mocked modules. Documentation will be generated but\n"
320245
"may be incomplete or show incorrect type hints.\n\n"
@@ -569,15 +494,11 @@ class ReleasesTree(TocTree):
569494
option_spec = dict(TocTree.option_spec)
570495

571496
def run(self):
572-
try:
573-
rst = super().run()
574-
if rst and rst[0] and rst[0][0] and "entries" in rst[0][0]:
575-
entries = rst[0][0]["entries"][:]
576-
entries.sort(key=_normalize_version, reverse=True)
577-
rst[0][0]["entries"][:] = entries
578-
return rst
579-
except (AttributeError, KeyError, IndexError, TypeError):
580-
return super().run()
497+
rst = super().run()
498+
entries = rst[0][0]["entries"][:]
499+
entries.sort(key=_normalize_version, reverse=True)
500+
rst[0][0]["entries"][:] = entries
501+
return rst
581502

582503

583504
def copy_release_templates_pre(app):

salt/modules/file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1979,7 +1979,7 @@ def line(
19791979
indent=True,
19801980
):
19811981
# pylint: disable=W1401
1982-
r"""
1982+
"""
19831983
.. versionadded:: 2015.8.0
19841984
19851985
Line-focused editing of a file.

salt/modules/gem.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,11 @@ def install(
9696
Include pre-releases in the available versions
9797
:param proxy: string : None
9898
Use the specified HTTP proxy server for all outgoing traffic.
99-
Format: ``http://hostname:port``
99+
Format: http://hostname[:port]
100100
101101
source : None
102102
Use the specified HTTP gem source server to download gem.
103-
Format: ``http://hostname:port``
103+
Format: http://hostname[:port]
104104
105105
CLI Example:
106106

salt/states/gem.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ def installed(
7878
7979
proxy : None
8080
Use the specified HTTP proxy server for all outgoing traffic.
81-
Format: ``http://hostname:port``
81+
Format: http://hostname[:port]
8282
8383
source : None
8484
Use the specified HTTP gem source server to download gem.
85-
Format: ``http://hostname:port``
85+
Format: http://hostname[:port]
8686
"""
8787
ret = {"name": name, "result": None, "comment": "", "changes": {}}
8888
if ruby is not None and not (

salt/states/mysql_grants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
r"""
1+
"""
22
Management of MySQL grants (user permissions)
33
=============================================
44

salt/transport/zeromq.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ def __init__(self, opts, addr, linger=0, io_loop=None):
518518
:param dict opts: The salt opts dictionary
519519
:param str addr: The interface IP address to bind to
520520
:param int linger: The number of seconds to linger on a ZMQ socket. See
521-
http://api.zeromq.org/2-1:zmq-setsockopt ``[ZMQ_LINGER]``
521+
http://api.zeromq.org/2-1:zmq-setsockopt [ZMQ_LINGER]
522522
:param IOLoop io_loop: A Tornado IOLoop event scheduler [tornado.ioloop.IOLoop]
523523
"""
524524
self.opts = opts

0 commit comments

Comments
 (0)