diff --git a/deskutils/py-khard/Makefile b/deskutils/py-khard/Makefile
index 055e73d8e275..69234ece31a8 100644
--- a/deskutils/py-khard/Makefile
+++ b/deskutils/py-khard/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=	khard
 DISTVERSION=	0.20.0
+PORTREVISION=	1
 CATEGORIES=	deskutils python
 MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
diff --git a/deskutils/py-khard/files/patch-doc_source_conf.py b/deskutils/py-khard/files/patch-doc_source_conf.py
new file mode 100644
index 000000000000..2f841185eba9
--- /dev/null
+++ b/deskutils/py-khard/files/patch-doc_source_conf.py
@@ -0,0 +1,12 @@
+--- doc/source/conf.py.orig	2026-04-22 06:58:37 UTC
++++ doc/source/conf.py
+@@ -52,8 +52,8 @@ extensions = [
+     'sphinx.ext.autodoc',  # https://pypi.org/project/sphinx-autodoc-typehints/
+     'sphinx.ext.autosectionlabel',
+     'sphinx.ext.todo',
+-    'sphinx_autodoc_typehints',  # https://pypi.org/project/sphinx-autodoc-typehints/
+     'sphinxarg.ext',
++    'sphinx_autodoc_typehints',  # https://pypi.org/project/sphinx-autodoc-typehints/
+ ]
+ 
+ autoapi_type = 'python'
diff --git a/devel/libbson/Makefile b/devel/libbson/Makefile
index 81832258dcf7..38757ec00056 100644
--- a/devel/libbson/Makefile
+++ b/devel/libbson/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=	libbson
 DISTVERSION=	1.30.7
+PORTREVISION=	1
 CATEGORIES=	devel
 
 MAINTAINER=	ports@bsdserwis.com
diff --git a/devel/libbson/files/patch-build_sphinx_mongoc__common.py b/devel/libbson/files/patch-build_sphinx_mongoc__common.py
new file mode 100644
index 000000000000..8fb833601579
--- /dev/null
+++ b/devel/libbson/files/patch-build_sphinx_mongoc__common.py
@@ -0,0 +1,25 @@
+--- build/sphinx/mongoc_common.py.orig	2026-02-03 15:13:43 UTC
++++ build/sphinx/mongoc_common.py
+@@ -146,17 +146,17 @@ def generate_html_redirs(app: Sphinx, page: str, templ
+     redirect_file = out_index_html.parent.parent / f"{slug}.html"
+     # HACK: handle_page() is not properly reentrant. Save and restore state for
+     # this page while we generate our redirects page:
+-    prev_scripts = builder.script_files[:]
+-    prev_css = builder.css_files[:]
++    prev_scripts = builder.globalcontext['script_files'][:]
++    prev_css = builder.globalcontext['css_files'][:]
+     builder.handle_page(
+         f"redirect-for-{page}",
+         {"target": page, "writing-redirect": 1},
+         str(Path(__file__).parent.resolve() / "redirect.t.html"),
+-        str(redirect_file),
++        outfilename=str(redirect_file),
+     )
+     # Restore prior state:
+-    builder.script_files[:] = prev_scripts
+-    builder.css_files[:] = prev_css
++    builder.globalcontext['script_files'][:] = prev_scripts
++    builder.globalcontext['css_files'][:] = prev_css
+     sphinx_log.debug("Wrote redirect: %r -> %r", path, page)
+ 
+ def mongoc_common_setup(app: Sphinx):
diff --git a/devel/libbson/pkg-plist b/devel/libbson/pkg-plist
index 4a87c509c350..66b5eab29ae3 100644
--- a/devel/libbson/pkg-plist
+++ b/devel/libbson/pkg-plist
@@ -45,10 +45,12 @@ lib/libbson-1.0.so.0.0.0
 lib/libbson-static-1.0.a
 libdata/pkgconfig/libbson-1.0.pc
 libdata/pkgconfig/libbson-static-1.0.pc
+%%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/base-stemmer.js
 %%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/basic.css
 %%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/debug.css
 %%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/doctools.js
 %%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/documentation_options.js
+%%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/english-stemmer.js
 %%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/file.png
 %%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/language_data.js
 %%PORTDOCS%%%%DOCSDIR%%/libbson/html/_static/minus.png
@@ -783,4 +785,5 @@ libdata/pkgconfig/libbson-static-1.0.pc
 %%PORTDOCS%%share/man/man3/bson_writer_t.3.gz
 %%PORTDOCS%%share/man/man3/bson_zero_free.3.gz
 %%PORTDOCS%%share/man/man3/libbson_legacy_extended_json.3.gz
+%%PORTDOCS%%@dir %%DOCSDIR%%/libbson/html/_sources
 %%PORTDOCS%%@dir %%DOCSDIR%%/libbson/html/index
diff --git a/devel/mongo-c-driver/Makefile b/devel/mongo-c-driver/Makefile
index 116ff47dbf35..8faadc229155 100644
--- a/devel/mongo-c-driver/Makefile
+++ b/devel/mongo-c-driver/Makefile
@@ -1,6 +1,7 @@
 PORTNAME=	mongo-c-driver
 # Note: devel/mongo-cxx-driver requires specific versions of this port
 DISTVERSION=	1.30.7
+PORTREVISION=	1
 CATEGORIES=	devel
 
 MAINTAINER=	ports@bsdserwis.com
diff --git a/devel/mongo-c-driver/files/patch-build_sphinx_mongoc__common.py b/devel/mongo-c-driver/files/patch-build_sphinx_mongoc__common.py
new file mode 100644
index 000000000000..8fb833601579
--- /dev/null
+++ b/devel/mongo-c-driver/files/patch-build_sphinx_mongoc__common.py
@@ -0,0 +1,25 @@
+--- build/sphinx/mongoc_common.py.orig	2026-02-03 15:13:43 UTC
++++ build/sphinx/mongoc_common.py
+@@ -146,17 +146,17 @@ def generate_html_redirs(app: Sphinx, page: str, templ
+     redirect_file = out_index_html.parent.parent / f"{slug}.html"
+     # HACK: handle_page() is not properly reentrant. Save and restore state for
+     # this page while we generate our redirects page:
+-    prev_scripts = builder.script_files[:]
+-    prev_css = builder.css_files[:]
++    prev_scripts = builder.globalcontext['script_files'][:]
++    prev_css = builder.globalcontext['css_files'][:]
+     builder.handle_page(
+         f"redirect-for-{page}",
+         {"target": page, "writing-redirect": 1},
+         str(Path(__file__).parent.resolve() / "redirect.t.html"),
+-        str(redirect_file),
++        outfilename=str(redirect_file),
+     )
+     # Restore prior state:
+-    builder.script_files[:] = prev_scripts
+-    builder.css_files[:] = prev_css
++    builder.globalcontext['script_files'][:] = prev_scripts
++    builder.globalcontext['css_files'][:] = prev_css
+     sphinx_log.debug("Wrote redirect: %r -> %r", path, page)
+ 
+ def mongoc_common_setup(app: Sphinx):
diff --git a/devel/mongo-c-driver/pkg-plist b/devel/mongo-c-driver/pkg-plist
index 953d8b1193cc..b6f492e67834 100644
--- a/devel/mongo-c-driver/pkg-plist
+++ b/devel/mongo-c-driver/pkg-plist
@@ -71,11 +71,13 @@ lib/libmongoc-static-1.0.a
 libdata/pkgconfig/libmongoc-1.0.pc
 %%SSL%%libdata/pkgconfig/libmongoc-ssl-1.0.pc
 libdata/pkgconfig/libmongoc-static-1.0.pc
+%%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/base-stemmer.js
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/basic.css
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/debug.css
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/design-tabs.js
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/doctools.js
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/documentation_options.js
+%%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/english-stemmer.js
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/file.png
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/language_data.js
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/minus.png
@@ -88,7 +90,7 @@ libdata/pkgconfig/libmongoc-static-1.0.pc
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/searchtools.js
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/skeleton.css
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/sphinx_highlight.js
-%%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/sphinx-design.4cbf315f70debaebd550c87a6162cf0f.min.css
+%%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/sphinx-design.min.css
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/styles/furo-extensions.css
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/styles/furo-extensions.css.map
 %%PORTDOCS%%%%DOCSDIR%%/mongo-c-driver/html/_static/styles/furo.css
@@ -2484,5 +2486,6 @@ libdata/pkgconfig/libmongoc-static-1.0.pc
 %%DATADIR%%/NEWS
 %%DATADIR%%/README.rst
 %%DATADIR%%/THIRD_PARTY_NOTICES
+%%PORTDOCS%%@dir %%DOCSDIR%%/mongo-c-driver/html/_sources
 %%PORTDOCS%%@dir %%DOCSDIR%%/mongo-c-driver/html/_sphinx_design_static
 %%PORTDOCS%%@dir %%DOCSDIR%%/mongo-c-driver/html/index
diff --git a/devel/py-breathe/Makefile b/devel/py-breathe/Makefile
index 059efe657c97..5c34f163b062 100644
--- a/devel/py-breathe/Makefile
+++ b/devel/py-breathe/Makefile
@@ -1,6 +1,5 @@
 PORTNAME=	breathe
-PORTVERSION=	4.35.0
-PORTREVISION=	3
+PORTVERSION=	4.36.0
 CATEGORIES=	devel python
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
 
@@ -12,12 +11,12 @@ LICENSE=	BSD2CLAUSE
 LICENSE_FILE=	${WRKSRC}/LICENSE
 
 BUILD_DEPENDS=	${RUN_DEPENDS} \
-		${PYTHON_PKGNAMEPREFIX}wheel>=0:devel/py-wheel@${PY_FLAVOR}
+		${PYTHON_PKGNAMEPREFIX}flit-core>=3.7:devel/py-flit-core@${PY_FLAVOR}
 RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}furo>=0:textproc/py-furo@${PY_FLAVOR} \
 		graphviz>=0:graphics/graphviz \
-		${PYTHON_PKGNAMEPREFIX}setuptools>=63.1.0:devel/py-setuptools@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinx>=0,1:textproc/py-sphinx@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx>=7.2,1:textproc/py-sphinx@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}sphinx-copybutton>=0:textproc/py-sphinx-copybutton@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-spelling>=0:textproc/py-sphinxcontrib-spelling@${PY_FLAVOR} \
 		doxygen:devel/doxygen
 
 USES=		gmake python
@@ -39,7 +38,7 @@ PORTDOCS=	*
 PORTEXAMPLES=	*
 
 post-patch:
-		${REINPLACE_CMD} "s/^git_tag = subprocess.*/git_tag = b'v${PORTVERSION}'/" \
+		${REINPLACE_CMD} "s/%%VERSION%%/v${PORTVERSION}/" \
 			${WRKSRC}/documentation/source/conf.py
 
 post-build-DOCS-on:
diff --git a/devel/py-breathe/distinfo b/devel/py-breathe/distinfo
index b80301f08de6..208b1a4e6528 100644
--- a/devel/py-breathe/distinfo
+++ b/devel/py-breathe/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1678299982
-SHA256 (michaeljones-breathe-4.35.0-v4.35.0_GH0.tar.gz) = 55b54723752fc04b892a0f868782b1df65e69db6ca94fb32cf04be495bfd7841
-SIZE (michaeljones-breathe-4.35.0-v4.35.0_GH0.tar.gz) = 212932
+TIMESTAMP = 1777191940
+SHA256 (michaeljones-breathe-4.36.0-v4.36.0_GH0.tar.gz) = 94fc2277e639929e898cb95559d9d2c51cf764b787eaf6fa04f848a6550c2ff5
+SIZE (michaeljones-breathe-4.36.0-v4.36.0_GH0.tar.gz) = 219346
diff --git a/devel/py-breathe/files/patch-documentation_source_conf.py b/devel/py-breathe/files/patch-documentation_source_conf.py
new file mode 100644
index 000000000000..53b66da2c945
--- /dev/null
+++ b/devel/py-breathe/files/patch-documentation_source_conf.py
@@ -0,0 +1,18 @@
+--- documentation/source/conf.py.orig	2026-04-26 08:35:23 UTC
++++ documentation/source/conf.py
+@@ -37,12 +37,12 @@ else:
+     version = release = "compare"
+ else:
+     # Get a description of the current position.
+-    git_tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, encoding="utf-8")
+-    if re.match(r"^v\d+\.\d+\.\d+$", git_tag.stdout):
++    git_tag = "%%VERSION%%"
++    if re.match(r"^v\d+\.\d+\.\d+$", git_tag):
+         # Check if it matches a pure tag number vX.Y.Z,
+         # rather than vX.Y.Z-91-g8676988, which is how non-tagged commits
+         # are described (relative to the last tag).
+-        version = release = git_tag.stdout
++        version = release = git_tag
+     else:
+         version = release = "latest"
+ 
diff --git a/devel/py-dbus/Makefile b/devel/py-dbus/Makefile
index 7a35ec8f7fd9..9279829d423e 100644
--- a/devel/py-dbus/Makefile
+++ b/devel/py-dbus/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=	dbus
 DISTVERSION=	1.4.0
+PORTREVISION=	1
 CATEGORIES=	devel gnome python
 MASTER_SITES=	https://dbus.freedesktop.org/releases/dbus-python/
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -21,7 +22,8 @@ SHEBANG_FILES=	test/run-test.sh \
 		test/*.py
 
 MESON_ARGS=	-Dtests=enabled \
-		-Dpython.bytecompile=1
+		-Dpython.bytecompile=1 \
+		-Dpython=${PYTHON_CMD}
 
 DOCSDIR=	${PREFIX}/share/doc/dbus-python
 EXAMPLESDIR=	${PREFIX}/share/examples/dbus-python
@@ -32,7 +34,7 @@ OPTIONS_DEFINE=	DOCS EXAMPLES
 OPTIONS_SUB=	yes
 
 DOCS_DESC=			Build and install HTML documentation (requires Sphinx)
-DOCS_BUILD_DEPENDS=		sphinx-build:textproc/py-sphinx \
+DOCS_BUILD_DEPENDS=		${PYTHON_PKGNAMEPREFIX}sphinx>0:textproc/py-sphinx@${PY_FLAVOR} \
 				${PYTHON_PKGNAMEPREFIX}sphinx_rtd_theme>0:textproc/py-sphinx_rtd_theme@${PY_FLAVOR}
 DOCS_MESON_ENABLED=		doc
 
diff --git a/devel/py-dbus/pkg-plist b/devel/py-dbus/pkg-plist
index 940c95f5c635..4c17e4432cd8 100644
--- a/devel/py-dbus/pkg-plist
+++ b/devel/py-dbus/pkg-plist
@@ -81,30 +81,6 @@ libdata/pkgconfig/dbus-python.pc
 %%PORTDOCS%%%%DOCSDIR%%/html/_static/documentation_options.js
 %%PORTDOCS%%%%DOCSDIR%%/html/_static/english-stemmer.js
 %%PORTDOCS%%%%DOCSDIR%%/html/_static/file.png
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-bold.eot
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-bold.ttf
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-bold.woff
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-bold.woff2
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-bolditalic.eot
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-bolditalic.ttf
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-bolditalic.woff
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-bolditalic.woff2
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-italic.eot
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-italic.ttf
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-italic.woff
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-italic.woff2
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-regular.eot
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-regular.ttf
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-regular.woff
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/Lato/lato-regular.woff2
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff
-%%PORTDOCS%%%%DOCSDIR%%/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2
 %%PORTDOCS%%%%DOCSDIR%%/html/_static/jquery.js
 %%PORTDOCS%%%%DOCSDIR%%/html/_static/js/badge_only.js
 %%PORTDOCS%%%%DOCSDIR%%/html/_static/js/theme.js
diff --git a/devel/py-pip/Makefile b/devel/py-pip/Makefile
index d7c1abd40788..4c65dee9c1b0 100644
--- a/devel/py-pip/Makefile
+++ b/devel/py-pip/Makefile
@@ -1,12 +1,17 @@
 PORTNAME=	pip
-PORTVERSION=	23.3.2
-PORTREVISION=	4
+DISTVERSION=	26.0.1
 CATEGORIES=	devel python
-MASTER_SITES=	https://files.pythonhosted.org/packages/c3/9e/8a7ba2c9984a060daa6c6f9fff4d576b7ace3936239d6b771541eab972ed/:test_setuptools \
-		https://files.pythonhosted.org/packages/61/86/cc8d1ff2ca31a312a25a708c891cf9facbad4eae493b3872638db6785eb5/:test_wheel
+MASTER_SITES=	${_TEST_DIST_COVERAGE} \
+		${_TEST_DIST_FLIT_CORE} \
+		${_TEST_DIST_KEYRING} \
+		${_TEST_DIST_PYTEST_SUBKET} \
+		${_TEST_DIST_SETUPTOOLS}
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
-DISTFILES=	setuptools-67.6.0-py3-none-any.whl:test_setuptools \
-		wheel-0.40.0-py3-none-any.whl:test_wheel
+DISTFILES=	${_TEST_WHEEL_COVERAGE}:test_coverage \
+		${_TEST_WHEEL_FLIT_CORE}:test_flit_core \
+		${_TEST_WHEEL_KEYRING}:test_keyring \
+		${_TEST_WHEEL_PYTEST_SUBKET}:test_pytest_subket \
+		${_TEST_WHEEL_SETUPTOOLS}:test_setuptools
 DIST_SUBDIR=	${PORTNAME}
 EXTRACT_ONLY=	${DISTNAME}${EXTRACT_SUFX}
 
@@ -17,65 +22,113 @@ WWW=		https://pip.pypa.io/en/latest/
 LICENSE=	MIT
 LICENSE_FILE=	${WRKSRC}/LICENSE.txt
 
-# Tests also need bzr, git, otherwise they fail
-TEST_DEPENDS=	${PYTHON_PKGNAMEPREFIX}freezegun>=0:devel/py-freezegun@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}installer>=0:devel/py-installer@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}pytest-cov>=0:devel/py-pytest-cov@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}pytest-rerunfailures>=0:devel/py-pytest-rerunfailures@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}pytest-xdist>=0:devel/py-pytest-xdist@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}scripttest>=0:devel/py-scripttest@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sqlite3>=0:databases/py-sqlite3@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}tomli-w>=0:textproc/py-tomli-w@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}virtualenv>=0:devel/py-virtualenv@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}werkzeug>=0:www/py-werkzeug@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}wheel>=0:devel/py-wheel@${PY_FLAVOR} \
+BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}flit-core>=3.11:devel/py-flit-core@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}furo>=0:textproc/py-furo@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}myst-parser>=0:textproc/py-myst-parser@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx-copybutton>=0:textproc/py-sphinx-copybutton@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx-inline-tabs>=0:textproc/py-sphinx-inline-tabs@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx-issues>0:textproc/py-sphinx-issues@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx>=7.0,1:textproc/py-sphinx@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-towncrier>=0.2.0a0:textproc/py-sphinxcontrib-towncrier@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}towncrier>=0:textproc/py-towncrier@${PY_FLAVOR}
+# Tests require bzr, and git
+TEST_DEPENDS=	${PYTHON_PKGNAMEPREFIX}coverage>0:devel/py-coverage@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}flit-core>=3.11:devel/py-flit-core@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}freezegun>0:devel/py-freezegun@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}installer>0:devel/py-installer@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}proxy_py>0:www/py-proxy.py@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}pytest-cov>0:devel/py-pytest-cov@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}pytest-rerunfailures>0:devel/py-pytest-rerunfailures@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}pytest-xdist>0:devel/py-pytest-xdist@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}pytest_subket>0:devel/py-pytest-subket@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}scripttest>0:devel/py-scripttest@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}setuptools>0:devel/py-setuptools@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}tomli-w>0:textproc/py-tomli-w@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}virtualenv>=20.0:devel/py-virtualenv@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}werkzeug>0:www/py-werkzeug@${PY_FLAVOR} \
+		bash:shells/bash \
+		fish:shells/fish \
+		git:devel/git \
 		hg:devel/mercurial \
-		git:devel/git
+		nox>0:devel/nox
 .if ${WITH_SUBVERSION_VER:U} == LTS
 TEST_DEPENDS+=	svn:devel/subversion-lts
 .else
 TEST_DEPENDS+=	svn:devel/subversion
 .endif
 
-USES=		cpe python shebangfix
+USES=		cpe python
 CPE_VENDOR=	pypa
-USE_PYTHON=	autoplist concurrent cryptography_test distutils pytest
+USE_GITHUB=	yes
+GH_ACCOUNT=	pypa
+USE_PYTHON=	autoplist concurrent cryptography_test pep517 pytest
 
-MAKE_ENV=	PYTHONPATH=${WRKSRC}/src/
-NO_ARCH=	yes
 TEST_ENV=	PYTHONPATH=${STAGEDIR}${PYTHON_SITELIBDIR}
 
-USE_GITHUB=	yes
-GH_ACCOUNT=	pypa
+DOCSDIR=	${PREFIX}/share/doc/${PYTHON_PKGNAMEPREFIX}${PORTNAME}
+NO_ARCH=	yes
 
-SHEBANG_FILES=	src/pip/__init__.py
+OPTIONS_DEFINE=	DOCS
 
-# OPTIONS_DEFINE=	DOCS
+DOCS_PORTDOCS=	*
 
-DOCS_BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}furo>=0:textproc/py-furo@${PY_FLAVOR} \
-			${PYTHON_PKGNAMEPREFIX}myst-parser>=0:textproc/py-myst-parser@${PY_FLAVOR} \
-			${PYTHON_PKGNAMEPREFIX}sphinx>=4.2,1<6.0,1:textproc/py-sphinx@${PY_FLAVOR} \
-			${PYTHON_PKGNAMEPREFIX}sphinx-copybutton>=0:textproc/py-sphinx-copybutton@${PY_FLAVOR} \
-			${PYTHON_PKGNAMEPREFIX}sphinx-inline-tabs>=0:textproc/py-sphinx-inline-tabs@${PY_FLAVOR} \
-			${PYTHON_PKGNAMEPREFIX}sphinxcontrib-towncrier>=0.2.0a0:textproc/py-sphinxcontrib-towncrier@${PY_FLAVOR} \
-			${PYTHON_PKGNAMEPREFIX}towncrier>=0:textproc/py-towncrier@${PY_FLAVOR}
-DOCS_PORTDOCS=		*
-DOCS_VARS=		PYDISTUTILS_BUILD_TARGET=build_sphinx \
-			PYDISTUTILS_BUILDARGS="-n --all-files --fresh-env"
+_DOCS_BUILD_ENV=	PYTHONPATH="${PYTHONPATH}:${WRKDIR}${PYTHON_SITELIBDIR}"
+_DOCS_INSTALL_EXCLUDES=	"-not -name .buildinfo -not -regex ^./.doctrees.* -not -regex ^./_sources.*"
+_DOCS_MAN_PAGES=	-type f | ${SORT} | ${SED} -e 's|${STAGEDIR}||'
+_PYTHON_WHEEL=		${BUILD_WRKSRC}/dist/${PORTNAME:C|[-_]+|_|g}-${DISTVERSION}*.whl
 
-post-patch:
-	@${RM} -r ${WRKSRC}/src/pip/_vendor/colorama/tests/
+_TEST_DATA_COMMON_WHLS=		${WRKSRC}/tests/data/common_wheels
+_TEST_DIST_COVERAGE=		https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/:test_coverage
+_TEST_DIST_FLIT_CORE=		https://files.pythonhosted.org/packages/f2/65/b6ba90634c984a4fcc02c7e3afe523fef500c4980fec67cc27536ee50acf/:test_flit_core
+_TEST_DIST_KEYRING=		https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/:test_keyring
+_TEST_DIST_PYTEST_SUBKET=	https://files.pythonhosted.org/packages/05/2c/ee98f189b169a2caa8557569e49bd24f24c68c6033165486a1473738e730/:test_pytest_subket
+_TEST_DIST_SETUPTOOLS=		https://files.pythonhosted.org/packages/55/b3/b3a3415d2debd837106ed417f8681d8af63037fed367fa1b85dbfef081f1/:test_setuptools
+_TEST_WHEEL_COVERAGE=		coverage-7.13.5-py3-none-any.whl
+_TEST_WHEEL_FLIT_CORE=		flit_core-3.12.0-py3-none-any.whl
+_TEST_WHEEL_KEYRING=		keyring-25.7.0-py3-none-any.whl
+_TEST_WHEEL_PYTEST_SUBKET=	pytest_subket-0.8.1-py3-none-any.whl
+_TEST_WHEEL_SETUPTOOLS=		setuptools-70.1.0-py3-none-any.whl
+
+post-build:
+	(${PYTHON_CMD} -m installer --destdir ${WRKDIR} --prefix ${PREFIX} \
+		${_PYTHON_WHEEL} && \
+		cd ${WRKSRC} && \
+		${SETENV} ${_DOCS_BUILD_ENV} ${PYTHON_CMD} docs/pip_sphinxext.py && \
+		${SETENV} ${_DOCS_BUILD_ENV} sphinx-build-${PYTHON_VER} \
+		-b man docs/man -c ${WRKSRC}/docs/html docs/_build/man)
+
+post-build-DOCS-on:
+	(cd ${WRKSRC} && \
+		${SETENV} ${_DOCS_BUILD_ENV} sphinx-build-${PYTHON_VER} \
+		-b html docs/html -c ${WRKSRC}/docs/html docs/_build/html)
+
+post-install:
+	${INSTALL_MAN} ${WRKSRC}/docs/_build/man/*.1 \
+		${STAGEDIR}${PREFIX}/share/man/man1/
 
 post-install-DOCS-on:
-	@${MKDIR} ${STAGEDIR}${DOCSDIR}
-	(cd ${WRKSRC}/build/sphinx/html && \
-	${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR} "! -name .buildinfo -and ! -name objects.inv")
+	${MKDIR} ${STAGEDIR}${DOCSDIR}
+	(cd ${WRKSRC}/docs/_build/html && \
+		${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR}/ ${_DOCS_INSTALL_EXCLUDES})
+
+post-stage:
+	(${FIND} ${STAGEDIR}${PREFIX}/share/man/man1/ ${_DOCS_MAN_PAGES} \
+		>> ${_PYTHONPKGLIST})
 
 pre-test:
-	${MKDIR} ${WRKSRC}/tests/data/common_wheels
-	# the tests check for these wheel files, so fetch them and copy them in
-	${CP} ${DISTDIR}/${DIST_SUBDIR}/setuptools-67.6.0-py3-none-any.whl ${WRKSRC}/tests/data/common_wheels
-	${CP} ${DISTDIR}/${DIST_SUBDIR}/wheel-0.40.0-py3-none-any.whl ${WRKSRC}/tests/data/common_wheels
+	${MKDIR} ${_TEST_DATA_COMMON_WHLS}
+# The tests check for these wheel files, so fetch them and copy them in
+	${CP} ${DISTDIR}/${DIST_SUBDIR}/${_TEST_WHEEL_COVERAGE} ${_TEST_DATA_COMMON_WHLS}
+	${CP} ${DISTDIR}/${DIST_SUBDIR}/${_TEST_WHEEL_FLIT_CORE} ${_TEST_DATA_COMMON_WHLS}
+	${CP} ${DISTDIR}/${DIST_SUBDIR}/${_TEST_WHEEL_KEYRING} ${_TEST_DATA_COMMON_WHLS}
+	${CP} ${DISTDIR}/${DIST_SUBDIR}/${_TEST_WHEEL_PYTEST_SUBKET} \
+		${_TEST_DATA_COMMON_WHLS}
+	${CP} ${DISTDIR}/${DIST_SUBDIR}/${_TEST_WHEEL_SETUPTOOLS} ${_TEST_DATA_COMMON_WHLS}
 	${LN} -sf ${LOCALBASE}/bin/pip ${LOCALBASE}/bin/pip3
 
+do-test:
+	(cd ${WRKSRC} && \
+		${SETENV} ${LOCALBASE}/bin/nox -s test-${_PYTHON_VERSION} \
+		-- -n auto)
+
 .include <bsd.port.mk>
diff --git a/devel/py-pip/distinfo b/devel/py-pip/distinfo
index f673b0aeeb2a..b0b127e6c99f 100644
--- a/devel/py-pip/distinfo
+++ b/devel/py-pip/distinfo
@@ -1,7 +1,13 @@
-TIMESTAMP = 1703228100
-SHA256 (pip/setuptools-67.6.0-py3-none-any.whl) = b78aaa36f6b90a074c1fa651168723acbf45d14cb1196b6f02c0fd07f17623b2
-SIZE (pip/setuptools-67.6.0-py3-none-any.whl) = 1089190
-SHA256 (pip/wheel-0.40.0-py3-none-any.whl) = d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247
-SIZE (pip/wheel-0.40.0-py3-none-any.whl) = 64545
-SHA256 (pip/pypa-pip-23.3.2_GH0.tar.gz) = 0e534d5c6dba159f0a4e64d55ef4d130222bcb4ac25f62275017eacbfa10a1d5
-SIZE (pip/pypa-pip-23.3.2_GH0.tar.gz) = 9397451
+TIMESTAMP = 1776401928
+SHA256 (pip/coverage-7.13.5-py3-none-any.whl) = 34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61
+SIZE (pip/coverage-7.13.5-py3-none-any.whl) = 211346
+SHA256 (pip/flit_core-3.12.0-py3-none-any.whl) = e7a0304069ea895172e3c7bb703292e992c5d1555dd1233ab7b5621b5b69e62c
+SIZE (pip/flit_core-3.12.0-py3-none-any.whl) = 45594
+SHA256 (pip/keyring-25.7.0-py3-none-any.whl) = be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f
+SIZE (pip/keyring-25.7.0-py3-none-any.whl) = 39160
+SHA256 (pip/pytest_subket-0.8.1-py3-none-any.whl) = 7dc90dcc5fd422bc04a58ecebda94e71ef524629ab17ec2d7517a38e29230e92
+SIZE (pip/pytest_subket-0.8.1-py3-none-any.whl) = 8825
+SHA256 (pip/setuptools-70.1.0-py3-none-any.whl) = d9b8b771455a97c8a9f3ab3448ebe0b29b5e105f1228bba41028be116985a267
+SIZE (pip/setuptools-70.1.0-py3-none-any.whl) = 882588
+SHA256 (pip/pypa-pip-26.0.1_GH0.tar.gz) = b70256771f5ea127dae3e4bd6a9c9ab4928d1833519e17b132e76bdeec5a373d
+SIZE (pip/pypa-pip-26.0.1_GH0.tar.gz) = 9227871
diff --git a/devel/py-pip/files/patch-setup.py b/devel/py-pip/files/patch-setup.py
deleted file mode 100644
index 297dd8d7578a..000000000000
--- a/devel/py-pip/files/patch-setup.py
+++ /dev/null
@@ -1,11 +0,0 @@
---- setup.py.orig	2022-05-11 19:03:44 UTC
-+++ setup.py
-@@ -75,8 +75,6 @@ setup(
-     entry_points={
-         "console_scripts": [
-             "pip=pip._internal.cli.main:main",
--            "pip{}=pip._internal.cli.main:main".format(sys.version_info[0]),
--            "pip{}.{}=pip._internal.cli.main:main".format(*sys.version_info[:2]),
-         ],
-     },
-     zip_safe=False,
diff --git a/devel/py-virtualenvwrapper/Makefile b/devel/py-virtualenvwrapper/Makefile
index 2fc8cc8cb27b..6610e72d7b89 100644
--- a/devel/py-virtualenvwrapper/Makefile
+++ b/devel/py-virtualenvwrapper/Makefile
@@ -1,6 +1,5 @@
 PORTNAME=	virtualenvwrapper
-PORTVERSION=	4.8.4
-PORTREVISION=	2
+PORTVERSION=	6.1.1
 CATEGORIES=	devel python
 MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -12,45 +11,57 @@ WWW=		https://virtualenvwrapper.readthedocs.io/
 LICENSE=	MIT
 LICENSE_FILE=	${WRKSRC}/LICENSE
 
-BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}pbr>0:devel/py-pbr@${PY_FLAVOR}
+BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}setuptools>0:devel/py-setuptools@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}setuptools-scm>=6.2:devel/py-setuptools-scm@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx>=0,1:textproc/py-sphinx@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}wheel>0:devel/py-wheel@${PY_FLAVOR}
 RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}stevedore>0:devel/py-stevedore@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}virtualenv>0:devel/py-virtualenv@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}virtualenv-clone>0:devel/py-virtualenv-clone@${PY_FLAVOR}
 
-# Actually 2.6-2.7,3.3-3.6
+# Actually 3.8-3.12
 USES=		python
-USE_PYTHON=	autoplist concurrent distutils
+USE_PYTHON=	autoplist concurrent pep517
 
 OPTIONS_DEFINE=	DOCS
 
-DOCS_BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}sphinx>=0,1:textproc/py-sphinx@${PY_FLAVOR} \
-			${PYTHON_PKGNAMEPREFIX}sphinxcontrib-bitbucket>=1.0:textproc/py-sphinxcontrib-bitbucket@${PY_FLAVOR}
-DOCS_VARS=		PYDISTUTILS_BUILD_TARGET+=build_sphinx \
-			PYDISTUTILS_BUILDARGS="-a -E"
 
+DOCS_MAKE_ENV=	PYTHONPATH=${WRKSRC}
+PLIST_FILES=	share/man/man1/virtualenvwrapper.1.gz
 PORTDOCS=	*
 
 NO_ARCH=	yes
 
 post-patch:
-	${REINPLACE_CMD} \
-		-e 's|$$(command \\which python)|${PYTHON_CMD}|1' \
+	${REINPLACE_CMD} -E \
+		-e 's|which virtualenvwrapper.sh|which ${PORTNAME}.sh${UNIQUE_SUFFIX}|' \
+		-e 's|(_virtualenvwrapper_python_executable)=".*"|\1=${PYTHON_CMD}|1' \
 		-e 's|="virtualenv"|="virtualenv${UNIQUE_SUFFIX}"|1' \
 		-e 's|="virtualenv-clone"|="virtualenv-clone${UNIQUE_SUFFIX}"|1' \
-		${WRKSRC}/${PORTNAME}.sh
-	${REINPLACE_CMD} \
-		-e 's|which virtualenvwrapper.sh|which ${PORTNAME}.sh${UNIQUE_SUFFIX}|' \
+		-e 's|\$$\{\.sh\.file\}|$$0|1' \
+		-e 's|function (.*) \{|\1 ( ) {|' \
+		-e 's/(COMPREPLY|reply|in_args|out_args|args)=\((.*)\)/\1=\2/' \
+		-e 's|typeset ([^=]*)|\1=|' \
+		-e 's|typeset ||' \
+		-e 's|source |. |' \
+		${WRKSRC}/${PORTNAME}.sh \
 		${WRKSRC}/${PORTNAME}_lazy.sh
 
-post-patch-DOCS-on:
-	@${REINPLACE_CMD} -e 's|python setup.py|${PYTHON_CMD} setup.py|' \
-		${WRKSRC}/docs/source/conf.py
+post-build:
+	cd ${WRKSRC}/docs && ${SETENVI} ${MAKE_ENV} \
+		${BSDMAKE} SPHINX_BUILD=${LOCALBASE}/bin/sphinx-build${UNIQUE_SUFFIX} man
 
 post-build-DOCS-on:
-	@${RM} ${WRKSRC}/docs/build/html/.buildinfo
+	cd ${WRKSRC}/docs && ${SETENVI} ${MAKE_ENV} \
+		${BSDMAKE} SPHINX_BUILD=${LOCALBASE}/bin/sphinx-build${UNIQUE_SUFFIX} html
+
+post-install:
+	${INSTALL_MAN} ${WRKSRC}/docs/build/man/virtualenvwrapper.1 \
+		${STAGEDIR}${PREFIX}/share/man/man1
 
 post-install-DOCS-on:
 	${MKDIR} ${STAGEDIR}${DOCSDIR}
-	@cd ${WRKSRC}/docs/build/html && ${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR}
+	@cd ${WRKSRC}/docs/build/html && \
+		${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR} "-not ( -name .buildinfo )"
 
 .include <bsd.port.mk>
diff --git a/devel/py-virtualenvwrapper/distinfo b/devel/py-virtualenvwrapper/distinfo
index cd0c95445563..5e92d401262d 100644
--- a/devel/py-virtualenvwrapper/distinfo
+++ b/devel/py-virtualenvwrapper/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1584492404
-SHA256 (virtualenvwrapper-4.8.4.tar.gz) = 51a1a934e7ed0ff221bdd91bf9d3b604d875afbb3aa2367133503fee168f5bfa
-SIZE (virtualenvwrapper-4.8.4.tar.gz) = 334920
+TIMESTAMP = 1777103810
+SHA256 (virtualenvwrapper-6.1.1.tar.gz) = 112e7ea34a9a3ce90aaea54182f0d3afef4d1a913eeb75e98a263b4978cd73c6
+SIZE (virtualenvwrapper-6.1.1.tar.gz) = 95964
diff --git a/devel/py-virtualenvwrapper/files/patch-virtualenvwrapper_user__scripts.py b/devel/py-virtualenvwrapper/files/patch-virtualenvwrapper_user__scripts.py
new file mode 100644
index 000000000000..c5e3dc1b031e
--- /dev/null
+++ b/devel/py-virtualenvwrapper/files/patch-virtualenvwrapper_user__scripts.py
@@ -0,0 +1,65 @@
+--- virtualenvwrapper/user_scripts.py.orig	2026-04-25 10:17:06 UTC
++++ virtualenvwrapper/user_scripts.py
+@@ -202,7 +202,7 @@ def initialize_source(args):
+ # Run user-provided scripts
+ #
+ [ -f "$VIRTUALENVWRAPPER_HOOK_DIR/initialize" ] && \
+-    source "$VIRTUALENVWRAPPER_HOOK_DIR/initialize"
++    . "$VIRTUALENVWRAPPER_HOOK_DIR/initialize"
+ """
+ 
+ 
+@@ -223,7 +223,7 @@ def post_mkvirtualenv_source(args):
+ # Run user-provided scripts
+ #
+ [ -f "$VIRTUALENVWRAPPER_HOOK_DIR/postmkvirtualenv" ] && \
+-    source "$VIRTUALENVWRAPPER_HOOK_DIR/postmkvirtualenv"
++    . "$VIRTUALENVWRAPPER_HOOK_DIR/postmkvirtualenv"
+ """
+ 
+ 
+@@ -244,7 +244,7 @@ def post_cpvirtualenv_source(args):
+ # Run user-provided scripts
+ #
+ [ -f "$VIRTUALENVWRAPPER_HOOK_DIR/postcpvirtualenv" ] && \
+-    source "$VIRTUALENVWRAPPER_HOOK_DIR/postcpvirtualenv"
++    . "$VIRTUALENVWRAPPER_HOOK_DIR/postcpvirtualenv"
+ """
+ 
+ 
+@@ -276,9 +276,9 @@ def post_activate_source(args):
+ # Run user-provided scripts
+ #
+ [ -f "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate" ] && \
+-    source "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate"
++    . "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate"
+ [ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate" ] && \
+-    source "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate"
++    . "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate"
+ """
+ 
+ 
+@@ -289,9 +289,9 @@ def pre_deactivate_source(args):
+ # Run user-provided scripts
+ #
+ [ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/predeactivate" ] && \
+-    source "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/predeactivate"
++    . "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/predeactivate"
+ [ -f "$VIRTUALENVWRAPPER_HOOK_DIR/predeactivate" ] && \
+-    source "$VIRTUALENVWRAPPER_HOOK_DIR/predeactivate"
++    . "$VIRTUALENVWRAPPER_HOOK_DIR/predeactivate"
+ """
+ 
+ 
+@@ -303,9 +303,9 @@ VIRTUALENVWRAPPER_LAST_VIRTUAL_ENV="$WORKON_HOME/%(env
+ #
+ VIRTUALENVWRAPPER_LAST_VIRTUAL_ENV="$WORKON_HOME/%(env_name)s"
+ [ -f "$WORKON_HOME/%(env_name)s/bin/postdeactivate" ] && \
+-    source "$WORKON_HOME/%(env_name)s/bin/postdeactivate"
++    . "$WORKON_HOME/%(env_name)s/bin/postdeactivate"
+ [ -f "$VIRTUALENVWRAPPER_HOOK_DIR/postdeactivate" ] && \
+-    source "$VIRTUALENVWRAPPER_HOOK_DIR/postdeactivate"
++    . "$VIRTUALENVWRAPPER_HOOK_DIR/postdeactivate"
+ unset VIRTUALENVWRAPPER_LAST_VIRTUAL_ENV
+ """ % {'env_name': args[0]}
+ 
diff --git a/games/angband/Makefile b/games/angband/Makefile
index a30207c8b287..8e521300ec3a 100644
--- a/games/angband/Makefile
+++ b/games/angband/Makefile
@@ -43,6 +43,9 @@ post-patch:
 		's|.SILENT:||' ${WRKSRC}/mk/buildsys.mk.in
 	@${REINPLACE_CMD} -e \
 		's|-O0||' ${WRKSRC}/src/Makefile
+	cd ${WRKSRC}/docs && \
+		iconv -f MACCENTRALEUROPE -t UTF-8 version.rst > version-utf-8.rst
+	cd ${WRKSRC}/docs && ${MV} version-utf-8.rst version.rst
 
 post-build-DOCS-on:
 	# Needs gmake, although we could run sphinx directly
diff --git a/lang/ghc/files/patch-docs_users__guide_rtd-theme_layout.html b/lang/ghc/files/patch-docs_users__guide_rtd-theme_layout.html
new file mode 100644
index 000000000000..011e818e8361
--- /dev/null
+++ b/lang/ghc/files/patch-docs_users__guide_rtd-theme_layout.html
@@ -0,0 +1,25 @@
+--- docs/users_guide/rtd-theme/layout.html.orig	2026-04-18 08:43:54 UTC
++++ docs/users_guide/rtd-theme/layout.html
+@@ -29,15 +29,19 @@
+     <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
+   {%- endif %}
+   {%- for css in css_files %}
+-    {%- if css|attr("rel") %}
+-      <link rel="{{ css.rel }}" href="{{ pathto(css.filename, 1) }}" type="text/css"{% if css.title is not none %} title="{{ css.title }}"{% endif %} />
++    {%- if css|attr("filename") %}
++      {{css_tag(css) }}
+     {%- else %}
+       <link rel="stylesheet" href="{{ pathto(css, 1) }}" type="text/css" />
+     {%- endif %}
+   {%- endfor %}
+ 
+   {%- for cssfile in extra_css_files %}
+-    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
++    {%- if cssfile|attr("filename") %}
++      {{css_tag(css) }}
++    {%- else %}
++      <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
++    {%- endif %}
+   {%- endfor -%}
+ 
+   {#- FAVICON
diff --git a/mail/py-afew/Makefile b/mail/py-afew/Makefile
index 857733835497..120b7dd484eb 100644
--- a/mail/py-afew/Makefile
+++ b/mail/py-afew/Makefile
@@ -1,6 +1,6 @@
 PORTNAME=	afew
 DISTVERSION=	3.0.1
-PORTREVISION=	4
+PORTREVISION=	5
 CATEGORIES=	mail python
 MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -32,16 +32,19 @@ MANPAGES_PLIST_FILES=	share/man/man1/afew.1.gz
 PORTDOCS=	*
 
 post-build-MANPAGES-on:
-	cd ${WRKSRC} && ${PYTHON_CMD} setup.py build_sphinx -b man
+	cd ${WRKSRC}/docs && ${SETENVI} ${MAKE_ENV} PYTHONPATH=${WRKSRC} \
+		${LOCALBASE}/bin/sphinx-build${UNIQUE_SUFFIX} -b man . build/man
 
 post-install-MANPAGES-on:
-	${INSTALL_MAN} ${WRKSRC}/build/sphinx/man/afew.1 ${STAGEDIR}${PREFIX}/share/man/man1
+	${INSTALL_MAN} ${WRKSRC}/docs/build/man/afew.1 ${STAGEDIR}${PREFIX}/share/man/man1
 
 post-build-DOCS-on:
-	cd ${WRKSRC} && ${PYTHON_CMD} setup.py build_sphinx -b html
+	cd ${WRKSRC}/docs && ${SETENVI} ${MAKE_ENV} PYTHONPATH=${WRKSRC} \
+		${LOCALBASE}/bin/sphinx-build${UNIQUE_SUFFIX} -b html \
+		-d build/doctrees . build/html
 
 post-install-DOCS-on:
-	cd ${WRKSRC}/build/sphinx/html && ${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR}
-	@${RM} ${STAGEDIR}${DOCSDIR}/.buildinfo
+	cd ${WRKSRC}/docs/build/html && ${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR} \
+		"-not ( -name .buildinfo )"
 
 .include <bsd.port.mk>
diff --git a/textproc/py-pallets-sphinx-themes/Makefile b/textproc/py-pallets-sphinx-themes/Makefile
index 464dfb383123..69eb89344ed3 100644
--- a/textproc/py-pallets-sphinx-themes/Makefile
+++ b/textproc/py-pallets-sphinx-themes/Makefile
@@ -1,6 +1,5 @@
 PORTNAME=	Pallets-Sphinx-Themes
-DISTVERSION=	2.3.0
-PORTREVISION=	1
+DISTVERSION=	2.5.0
 CATEGORIES=	textproc python
 MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -13,10 +12,10 @@ WWW=		https://pypi.org/project/Pallets-Sphinx-Themes/
 LICENSE=	BSD3CLAUSE
 LICENSE_FILE=	${WRKSRC}/LICENSE.txt
 
-BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}flit-core>=3.9.0:devel/py-flit-core@${PY_FLAVOR}
+BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}flit-core>=3.11:devel/py-flit-core@${PY_FLAVOR}
 RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}packaging>=23.1:devel/py-packaging@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}sphinx-notfound-page>=1.0.4:textproc/py-sphinx-notfound-page@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinx>=5.3.0:textproc/py-sphinx@${PY_FLAVOR}
+		${PYTHON_PKGNAMEPREFIX}sphinx>=7.3,1:textproc/py-sphinx@${PY_FLAVOR}
 
 USES=		python
 USE_PYTHON=	autoplist concurrent pep517
diff --git a/textproc/py-pallets-sphinx-themes/distinfo b/textproc/py-pallets-sphinx-themes/distinfo
index a8c8d66dbf6c..c9432b164377 100644
--- a/textproc/py-pallets-sphinx-themes/distinfo
+++ b/textproc/py-pallets-sphinx-themes/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1729845817
-SHA256 (pallets_sphinx_themes-2.3.0.tar.gz) = 6293ced11a1d5d3de7268af1acd60428732b5a9e6051a47a596c6d9a083e60d9
-SIZE (pallets_sphinx_themes-2.3.0.tar.gz) = 21029
+TIMESTAMP = 1776030844
+SHA256 (pallets_sphinx_themes-2.5.0.tar.gz) = ef8609704b80e8a5d508a88adeb0559234311a1cf3362427aca9d283b22c80ef
+SIZE (pallets_sphinx_themes-2.5.0.tar.gz) = 216582
diff --git a/textproc/py-sphinx-autoapi/Makefile b/textproc/py-sphinx-autoapi/Makefile
index 88bcf815c0f9..ce682f9d116c 100644
--- a/textproc/py-sphinx-autoapi/Makefile
+++ b/textproc/py-sphinx-autoapi/Makefile
@@ -1,9 +1,9 @@
 PORTNAME=	sphinx-autoapi
-DISTVERSION=	2.1.1
-PORTREVISION=	2
+DISTVERSION=	3.8.0
 CATEGORIES=	textproc python
 MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
+DISTNAME=	sphinx_autoapi-${DISTVERSION}
 
 MAINTAINER=	andreas@bilke.org
 COMMENT=	Sphinx API documentation generator
@@ -12,12 +12,10 @@ WWW=		https://sphinx-autoapi.readthedocs.io/
 LICENSE=	MIT
 LICENSE_FILE=	${WRKSRC}/LICENSE.rst
 
-BUILD_DEPENDS=	${PY_SETUPTOOLS} \
-		${PYTHON_PKGNAMEPREFIX}wheel>0:devel/py-wheel@${PY_FLAVOR}
-RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}anyascii>0:textproc/py-anyascii@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}astroid2>=2.7:devel/py-astroid2@${PY_FLAVOR} \
+BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}flit-core>=3.2<4:devel/py-flit-core@${PY_FLAVOR}
+RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}astroid>=3.0:devel/py-astroid@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}Jinja2>0:devel/py-Jinja2@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinx>=5.2.0:textproc/py-sphinx@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx>=7.4.0:textproc/py-sphinx@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}pyyaml>=0:devel/py-pyyaml@${PY_FLAVOR}
 
 USES=		python
diff --git a/textproc/py-sphinx-autoapi/distinfo b/textproc/py-sphinx-autoapi/distinfo
index 90ce1cf38ff1..f9683c641ddb 100644
--- a/textproc/py-sphinx-autoapi/distinfo
+++ b/textproc/py-sphinx-autoapi/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1686650321
-SHA256 (sphinx-autoapi-2.1.1.tar.gz) = fbadb96e79020d6b0ec45d888517bf816d6b587a2d340fbe1ec31135e300a6c8
-SIZE (sphinx-autoapi-2.1.1.tar.gz) = 42160540
+TIMESTAMP = 1776838617
+SHA256 (sphinx_autoapi-3.8.0.tar.gz) = 9f8ac7d43baf28a0831ac0e392fab6a095b875af07e52d135a5f716cc3cf1142
+SIZE (sphinx_autoapi-3.8.0.tar.gz) = 58418
diff --git a/textproc/py-sphinx-design/Makefile b/textproc/py-sphinx-design/Makefile
index a43b1f10c272..d35e27b4f16f 100644
--- a/textproc/py-sphinx-design/Makefile
+++ b/textproc/py-sphinx-design/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=	sphinx-design
 PORTVERSION=	0.7.0
+PORTREVISION=	1
 CATEGORIES=	textproc python
 MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -14,7 +15,7 @@ LICENSE=	MIT
 LICENSE_FILE=	${WRKSRC}/LICENSE
 
 BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}flit-core>=3.4<4:devel/py-flit-core@${PY_FLAVOR}
-RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}sphinx>=5,1<10,1:textproc/py-sphinx@${PY_FLAVOR}
+RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}sphinx>=7,1<10,1:textproc/py-sphinx@${PY_FLAVOR}
 
 USES=		python:3.11+
 USE_PYTHON=	autoplist concurrent pep517
diff --git a/textproc/py-sphinx-design/files/patch-pyproject.toml b/textproc/py-sphinx-design/files/patch-pyproject.toml
deleted file mode 100644
index 0990f1e6d5be..000000000000
--- a/textproc/py-sphinx-design/files/patch-pyproject.toml
+++ /dev/null
@@ -1,11 +0,0 @@
---- pyproject.toml.orig	2026-01-19 13:12:43 UTC
-+++ pyproject.toml
-@@ -27,7 +27,7 @@ requires-python = ">=3.11"
- ]
- keywords = ["sphinx", "extension", "material design", "web components"]
- requires-python = ">=3.11"
--dependencies = ["sphinx>=7,<10"]
-+dependencies = ["sphinx>=5,<10"]
- 
- [project.urls]
- Homepage = "https://github.com/executablebooks/sphinx-design"
diff --git a/textproc/py-sphinx/Makefile b/textproc/py-sphinx/Makefile
index c7307cfd5db8..1f3240a5ce60 100644
--- a/textproc/py-sphinx/Makefile
+++ b/textproc/py-sphinx/Makefile
@@ -1,5 +1,5 @@
 PORTNAME=	sphinx
-PORTVERSION=	9.0.4
+DISTVERSION=	9.0.4
 PORTEPOCH=	1
 CATEGORIES=	textproc python
 MASTER_SITES=	PYPI
@@ -16,46 +16,35 @@ WWW=		https://www.sphinx-doc.org/
 LICENSE=	BSD2CLAUSE
 LICENSE_FILE=	${WRKSRC}/LICENSE.rst
 
-BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}flit-core>=3.7:devel/py-flit-core@${PY_FLAVOR}
-RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}sphinxcontrib-applehelp>=1.0.7:textproc/py-sphinxcontrib-applehelp@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-devhelp>=1.0.6:textproc/py-sphinxcontrib-devhelp@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-jsmath>=1.0.1:textproc/py-sphinxcontrib-jsmath@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-htmlhelp>=2.0.6:textproc/py-sphinxcontrib-htmlhelp@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-serializinghtml>=1.1.9:textproc/py-sphinxcontrib-serializinghtml@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-qthelp>=1.0.6:textproc/py-sphinxcontrib-qthelp@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}Jinja2>=3.1:devel/py-Jinja2@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}pygments>=2.17:textproc/py-pygments@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}docutils>=0.21,1<0.23,1:textproc/py-docutils@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}snowballstemmer>=2.2:textproc/py-snowballstemmer@${PY_FLAVOR} \
+BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}flit-core>=3.12:devel/py-flit-core@${PY_FLAVOR}
+RUN_DEPENDS=	${LOCALBASE}/share/certs/ca-root-nss.crt:security/ca_root_nss \
+		${PYTHON_PKGNAMEPREFIX}alabaster>=0.7.14:textproc/py-alabaster@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}Babel>=2.13:devel/py-babel@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}alabaster>=0.7.14<0.8:textproc/py-alabaster@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}colorama>=0.4.6:devel/py-colorama@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}docutils>=0.20:textproc/py-docutils@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}imagesize>=1.3:graphics/py-imagesize@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}Jinja2>=3.1:devel/py-Jinja2@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}packaging>=23.0:devel/py-packaging@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}pygments>=2.17:textproc/py-pygments@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}requests>=2.30.0:www/py-requests@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}roman-numerals>=1.0.0:textproc/py-roman-numerals@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}packaging>=23.0:devel/py-packaging@${PY_FLAVOR} \
-		${LOCALBASE}/share/certs/ca-root-nss.crt:security/ca_root_nss \
-		${PYTHON_PKGNAMEPREFIX}typing-extensions>0:devel/py-typing-extensions@${PY_FLAVOR}
-TEST_DEPENDS=	${PYTHON_PKGNAMEPREFIX}defusedxml>=0:devel/py-defusedxml@${PY_FLAVOR}
+		${PYTHON_PKGNAMEPREFIX}snowballstemmer>=2.2:textproc/py-snowballstemmer@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-applehelp>=1.0.7:textproc/py-sphinxcontrib-applehelp@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-devhelp>=1.0.6:textproc/py-sphinxcontrib-devhelp@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-htmlhelp>=2.0.6:textproc/py-sphinxcontrib-htmlhelp@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-jsmath>=1.0.1:textproc/py-sphinxcontrib-jsmath@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-qthelp>=1.0.6:textproc/py-sphinxcontrib-qthelp@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-serializinghtml>=1.1.9:textproc/py-sphinxcontrib-serializinghtml@${PY_FLAVOR}
+TEST_DEPENDS=	${PYTHON_PKGNAMEPREFIX}defusedxml>=0.7.1:devel/py-defusedxml@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}pytest-xdist>=3.4:devel/py-pytest-xdist@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}setuptools>=70.0:devel/py-setuptools@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}typing-extensions>=4.9:devel/py-typing-extensions@${PY_FLAVOR}
 
-USES=		python:3.11+
-USE_PYTHON=	autoplist concurrent pep517 pytest
+USES=		python
+USE_PYTHON=	autoplist concurrent cython_test pep517 pytest
 
-PYTEST_BROKEN_TESTS=	test_anchors_ignored \
-			test_defaults \
-			test_defaults_json \
-			test_ext_imgconverter \
-			test_latex_images
+PYTEST_BROKEN_TESTS=	test_copy_images
 
-# Upstream archive contains files with UTF-8 names (#246618)
-# https://github.com/sphinx-doc/sphinx/issues/2395
-EXTRACT_CMD=	${SETENV} LC_ALL=en_US.UTF-8 ${TAR}
 NO_ARCH=	yes
 
-.include <bsd.port.pre.mk>
-
-# imghdr was removed from the standard library in Python 3.13
-.if ${PYTHON_REL} >= 31300
-RUN_DEPENDS+=	${PYTHON_PKGNAMEPREFIX}standard-imghdr>=3.13.0:devel/py-standard-imghdr@${PY_FLAVOR}
-.endif
-
-.include <bsd.port.post.mk>
+.include <bsd.port.mk>
diff --git a/textproc/py-sphinx/distinfo b/textproc/py-sphinx/distinfo
index 1cd0c4d7c516..92658bfce514 100644
--- a/textproc/py-sphinx/distinfo
+++ b/textproc/py-sphinx/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1775943327
+TIMESTAMP = 1776307903
 SHA256 (python/sphinx-9.0.4.tar.gz) = 594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3
 SIZE (python/sphinx-9.0.4.tar.gz) = 8710502
diff --git a/textproc/py-sphinx_rtd_theme/Makefile b/textproc/py-sphinx_rtd_theme/Makefile
index 8d3cdb9aa8c2..351fe9f8b3ef 100644
--- a/textproc/py-sphinx_rtd_theme/Makefile
+++ b/textproc/py-sphinx_rtd_theme/Makefile
@@ -1,7 +1,6 @@
 PORTNAME=	sphinx_rtd_theme
-PORTVERSION=	3.1.0
+DISTVERSION=	3.1.0
 CATEGORIES=	textproc python
-MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
 
 MAINTAINER=	robak@FreeBSD.org
@@ -11,13 +10,49 @@ WWW=		https://github.com/readthedocs/sphinx_rtd_theme
 LICENSE=	MIT
 LICENSE_FILE=	${WRKSRC}/LICENSE
 
-USES=		python
-USE_PYTHON=	autoplist distutils pytest
+BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}setuptools>0:devel/py-setuptools@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx>=9,1:textproc/py-sphinx@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-jquery>=4,<5:textproc/py-sphinxcontrib-jquery@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}wheel>0:devel/py-wheel@${PY_FLAVOR}
+RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}docutils>=0.18:textproc/py-docutils@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinx>=9,1:textproc/py-sphinx@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-jquery>=4,<5:textproc/py-sphinxcontrib-jquery@${PY_FLAVOR}
 
-RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}sphinx>=6,1<10,1:textproc/py-sphinx@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}docutils>=0.18,1<0.23,1:textproc/py-docutils@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}sphinxcontrib-jquery>=4.0<5.0:textproc/py-sphinxcontrib-jquery@${PY_FLAVOR}
+USES=		python
+USE_GITHUB=	yes
+GH_ACCOUNT=	readthedocs
+USE_PYTHON=	autoplist concurrent pep517 pytest
 
 NO_ARCH=	yes
 
+PORTDOCS=	*
+
+OPTIONS_DEFINE=	DOCS
+
+_DOCS_INSTALL_EXCLUDES=	"-not -name .buildinfo -not -regex ^./_sources.*"
+_DOCS_MAN_PAGES=	-type f | ${SORT} | ${SED} -e 's|${STAGEDIR}||'
+
+post-build:
+	(cd ${WRKSRC}/docs && \
+		${LOCALBASE}/bin/sphinx-build-${PYTHON_VER} -b man -d \
+		./build/doctrees . ./build/man)
+
+post-build-DOCS-on:
+	(cd ${WRKSRC}/docs && \
+		${LOCALBASE}/bin/sphinx-build-${PYTHON_VER} -b html -d \
+		./build/doctrees . ./build/html)
+
+post-install:
+	${INSTALL_MAN} ${WRKSRC}/docs/build/man/*.1 \
+		${STAGEDIR}${PREFIX}/share/man/man1/
+
+post-install-DOCS-on:
+	${MKDIR} ${STAGEDIR}${DOCSDIR}
+	(cd ${WRKSRC}/docs/build/html && \
+		${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR}/ ${_DOCS_INSTALL_EXCLUDES})
+
+post-stage:
+	(${FIND} ${STAGEDIR}${PREFIX}/share/man/man1/ ${_DOCS_MAN_PAGES} \
+		>> ${_PYTHONPKGLIST})
+
 .include <bsd.port.mk>
diff --git a/textproc/py-sphinx_rtd_theme/distinfo b/textproc/py-sphinx_rtd_theme/distinfo
index 8fde60556f0d..50007bf4dc66 100644
--- a/textproc/py-sphinx_rtd_theme/distinfo
+++ b/textproc/py-sphinx_rtd_theme/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1775762416
-SHA256 (sphinx_rtd_theme-3.1.0.tar.gz) = b44276f2c276e909239a4f6c955aa667aaafeb78597923b1c60babc76db78e4c
-SIZE (sphinx_rtd_theme-3.1.0.tar.gz) = 7620915
+TIMESTAMP = 1776141882
+SHA256 (readthedocs-sphinx_rtd_theme-3.1.0_GH0.tar.gz) = f1755f1069616adacf1e00c0814e6b16192b7930ba4a3522993c3e096001b9b5
+SIZE (readthedocs-sphinx_rtd_theme-3.1.0_GH0.tar.gz) = 3162074
diff --git a/textproc/py-wtforms/Makefile b/textproc/py-wtforms/Makefile
index b1708942bb8d..472053712ab9 100644
--- a/textproc/py-wtforms/Makefile
+++ b/textproc/py-wtforms/Makefile
@@ -1,6 +1,5 @@
 PORTNAME=	wtforms
-DISTVERSION=	3.1.2
-PORTREVISION=	1
+DISTVERSION=	3.2.1
 CATEGORIES=	textproc python
 MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -13,7 +12,7 @@ LICENSE=	BSD3CLAUSE
 LICENSE_FILE=	${WRKSRC}/LICENSE.rst
 
 BUILD_DEPENDS=	${PY_SETUPTOOLS} \
-		${PYTHON_PKGNAMEPREFIX}Babel>0:devel/py-babel@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}Babel>2.6.0:devel/py-babel@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}python-dateutil>0:devel/py-python-dateutil@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}hatchling>0:devel/py-hatchling@${PY_FLAVOR} \
 		${PYTHON_PKGNAMEPREFIX}markupsafe>0:textproc/py-markupsafe@${PY_FLAVOR} \
diff --git a/textproc/py-wtforms/distinfo b/textproc/py-wtforms/distinfo
index 463f4fc734c8..a742453fc746 100644
--- a/textproc/py-wtforms/distinfo
+++ b/textproc/py-wtforms/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1704978549
-SHA256 (wtforms-3.1.2.tar.gz) = f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9
-SIZE (wtforms-3.1.2.tar.gz) = 134705
+TIMESTAMP = 1775720663
+SHA256 (wtforms-3.2.1.tar.gz) = df3e6b70f3192e92623128123ec8dca3067df9cfadd43d59681e210cfb8d4682
+SIZE (wtforms-3.2.1.tar.gz) = 137801
diff --git a/x11/kitty/Makefile b/x11/kitty/Makefile
index 936bf4fb4351..db38048afed3 100644
--- a/x11/kitty/Makefile
+++ b/x11/kitty/Makefile
@@ -1,7 +1,7 @@
 PORTNAME=	kitty
 DISTVERSIONPREFIX=	v
 DISTVERSION=	0.46.2
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	x11 wayland
 
 MAINTAINER=	nivit@FreeBSD.org
@@ -91,21 +91,8 @@ USES+=		ncurses:port
 USES+=		ncurses
 .endif
 
-# PR291485
-# Temporarily disable build/installation of docs and man pages on FreeBSD >= 15.0
-# See:
-# https://pkg-status.freebsd.org/beefy23/data/150amd64-default/e05e2042985b/logs/kitty-0.44.0_1.log
-# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291485
-.if ${OPSYS} == FreeBSD && ${OSVERSION} < 1500000
-MAKE_ENV+=	BUILD_MANPAGES=yes
+MAKE_ENV+=	BUILD_MANPAGES=yes TZ=UTC
 PLIST_SUB+=	PORTMANPAGES=""
-.else
-DOCS_MAKE_ENV=	BUILD_DOCS=no
-MAKE_ENV+=	BUILD_MANPAGES=no
-PLIST_SUB:=	${PLIST_SUB:S/PORTDOCS=""//1}
-PLIST_SUB+=	PORTDOCS="@comment " \
-		PORTMANPAGES="@comment "
-.endif
 
 post-patch:
 	${REINPLACE_CMD} -E \
@@ -137,20 +124,12 @@ do-install:
 	${INSTALL_DATA} ${WRKSRC}/terminfo/kitty.terminfo \
 		${STAGEDIR}${PREFIX}/share/misc/
 	${STRIP_CMD} ${_STRIP_TARGETS:S|^|${STAGEDIR}${DATADIR}/|}
-# PR291485: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291485
-.if ${OPSYS} == FreeBSD && ${OSVERSION} < 1500000
 	${INSTALL_MAN} ${BUILD_DIR}/share/man/man1/kitty.1 ${STAGEDIR}${PREFIX}/share/man/man1
 	${INSTALL_MAN} ${BUILD_DIR}/share/man/man5/kitty.conf.5 ${STAGEDIR}${PREFIX}/share/man/man5
-.endif
 
 do-install-DOCS-on:
-# PR291485: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291485
-.if ${OPSYS} == FreeBSD && ${OSVERSION} < 1500000
 	cd ${BUILD_DIR}/share/doc/kitty/html && \
 		${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR} \
 			"-not ( -name .buildinfo -or -name .nojekyll )"
-.else
-	@${DO_NADA}
-.endif
 
 .include <bsd.port.mk>
diff --git a/x11/kitty/pkg-plist b/x11/kitty/pkg-plist
index d1ee4a53143b..713f73c8dae0 100644
--- a/x11/kitty/pkg-plist
+++ b/x11/kitty/pkg-plist
@@ -158,7 +158,7 @@ share/applications/kitty.desktop
 %%PORTDOCS%%%%DOCSDIR%%/_sources/underlines.rst.txt
 %%PORTDOCS%%%%DOCSDIR%%/_sources/unscroll.rst.txt
 %%PORTDOCS%%%%DOCSDIR%%/_sources/wide-gamut-colors.rst.txt
-%%PORTDOCS%%%%DOCSDIR%%/_static/_sphinx_javascript_frameworks_compat.js
+%%PORTDOCS%%%%DOCSDIR%%/_static/base-stemmer.js
 %%PORTDOCS%%%%DOCSDIR%%/_static/basic.css
 %%PORTDOCS%%%%DOCSDIR%%/_static/check-solid.svg
 %%PORTDOCS%%%%DOCSDIR%%/_static/clipboard.min.js
@@ -171,9 +171,8 @@ share/applications/kitty.desktop
 %%PORTDOCS%%%%DOCSDIR%%/_static/debug.css
 %%PORTDOCS%%%%DOCSDIR%%/_static/doctools.js
 %%PORTDOCS%%%%DOCSDIR%%/_static/documentation_options.js
+%%PORTDOCS%%%%DOCSDIR%%/_static/english-stemmer.js
 %%PORTDOCS%%%%DOCSDIR%%/_static/file.png
-%%PORTDOCS%%%%DOCSDIR%%/_static/jquery-3.6.0.js
-%%PORTDOCS%%%%DOCSDIR%%/_static/jquery.js
 %%PORTDOCS%%%%DOCSDIR%%/_static/kitty.svg
 %%PORTDOCS%%%%DOCSDIR%%/_static/language_data.js
 %%PORTDOCS%%%%DOCSDIR%%/_static/minus.png
@@ -195,8 +194,6 @@ share/applications/kitty.desktop
 %%PORTDOCS%%%%DOCSDIR%%/_static/tabs.js
 %%PORTDOCS%%%%DOCSDIR%%/_static/timestamps.css
 %%PORTDOCS%%%%DOCSDIR%%/_static/timestamps.js
-%%PORTDOCS%%%%DOCSDIR%%/_static/underscore-1.13.1.js
-%%PORTDOCS%%%%DOCSDIR%%/_static/underscore.js
 %%PORTDOCS%%%%DOCSDIR%%/actions.html
 %%PORTDOCS%%%%DOCSDIR%%/binary.html
 %%PORTDOCS%%%%DOCSDIR%%/build.html
