From fc6ed7efe796fca04a02c632118bcb4d5888ae26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 00:27:32 +0000 Subject: [PATCH 1/6] chore(deps): bump the python-security group across 1 directory with 2 updates Bumps the python-security group with 2 updates in the / directory: [anyio](https://github.com/agronholm/anyio) and [pyjwt](https://github.com/jpadilla/pyjwt). Updates `anyio` from 4.12.1 to 4.14.2 - [Release notes](https://github.com/agronholm/anyio/releases) - [Commits](https://github.com/agronholm/anyio/compare/4.12.1...4.14.2) Updates `pyjwt` from 2.13.0 to 2.14.0 - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jpadilla/pyjwt/compare/2.13.0...2.14.0) --- updated-dependencies: - dependency-name: anyio dependency-version: 4.14.2 dependency-type: direct:production dependency-group: python-security - dependency-name: pyjwt dependency-version: 2.14.0 dependency-type: indirect dependency-group: python-security ... Signed-off-by: dependabot[bot] --- uv.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/uv.lock b/uv.lock index 222d23c225..9b74de319d 100644 --- a/uv.lock +++ b/uv.lock @@ -214,16 +214,16 @@ wheels = [ [[package]] name = "anyio" -version = "4.12.1" +version = "4.14.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11' or (extra == 'group-6-openai-pydantic-v1' and extra == 'group-6-openai-pydantic-v2')" }, { name = "idna" }, { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'group-6-openai-pydantic-v1' and extra == 'group-6-openai-pydantic-v2')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hash = "sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703", size = 228685, upload-time = "2026-01-06T11:45:21.246Z" } +sdist = { url = "https://files.pythonhosted.org/packages/61/cc/a381afa6efea9f496eff839d4a6a1aed3bfafc7b3ab4b0d1b243a12573dd/anyio-4.14.2.tar.gz", hash = "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f", size = 260176, upload-time = "2026-07-12T20:29:07.082Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" }, + { url = "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494", size = 125813, upload-time = "2026-07-12T20:29:05.763Z" }, ] [[package]] @@ -1535,7 +1535,7 @@ wheels = [ [[package]] name = "openai" -version = "3.22.1" # x-release-please-version +version = "3.22.1" source = { editable = "." } dependencies = [ { name = "anyio" }, @@ -2107,14 +2107,14 @@ wheels = [ [[package]] name = "pyjwt" -version = "2.13.0" +version = "2.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'group-6-openai-pydantic-v1' and extra == 'group-6-openai-pydantic-v2')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3b/81/58d0ac84e1ef3a3843791d6954d94c0b33d526c75eeb1efbce9d0a4c4077/pyjwt-2.13.0.tar.gz", hash = "sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423", size = 107515, upload-time = "2026-05-21T19:54:36.618Z" } +sdist = { url = "https://files.pythonhosted.org/packages/af/c3/8a3b59c25070cc61dc517fbdfa5dc0904670c96f605cc69759dc09166b99/pyjwt-2.14.0.tar.gz", hash = "sha256:77283c83fb56ecf566a886c757a714bc83668e38156de2cce8263302f42e0b86", size = 113177, upload-time = "2026-09-11T13:11:54.638Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl", hash = "sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728", size = 31274, upload-time = "2026-05-21T19:54:35.362Z" }, + { url = "https://files.pythonhosted.org/packages/9c/97/672cb32ce0dfea44b740cb7b4f97038463b9cf7c0ead1aacf595572851d6/pyjwt-2.14.0-py3-none-any.whl", hash = "sha256:ad0cef71c756a56e74863c2919cf0985f72decbcfcb550ee2f422e7c62b5eedc", size = 32896, upload-time = "2026-09-11T13:11:53.409Z" }, ] [package.optional-dependencies] From 494f8ac57ccbd69c87ed283d12abae32eac11560 Mon Sep 17 00:00:00 2001 From: Marcus Wood Date: Thu, 1 Oct 2026 20:08:41 +0000 Subject: [PATCH 2/6] fix: preserve release marker in security lock update --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 9b74de319d..7dcadaa5f9 100644 --- a/uv.lock +++ b/uv.lock @@ -1535,7 +1535,7 @@ wheels = [ [[package]] name = "openai" -version = "3.22.1" +version = "3.22.1" # x-release-please-version source = { editable = "." } dependencies = [ { name = "anyio" }, From aaa2cf0e07dce4322a9f4e435726cfb2a5a76fa0 Mon Sep 17 00:00:00 2001 From: Marcus Wood Date: Thu, 1 Oct 2026 20:14:13 +0000 Subject: [PATCH 3/6] fix(deps): require patched AnyIO and PyJWT releases --- pyproject.toml | 4 ++-- uv.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 405102c63f..ff4e91ba89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "httpx2>=2.12.0, <3", "pydantic>=1.10.13, <3, !=2.0.*, !=2.1.*, !=2.2.*, !=2.3.*", "typing-extensions>=4.14, <5", - "anyio>=4.10.0, <5", + "anyio>=4.14.2, <5", "sniffio", "jiter>=0.16.0, <1", ] @@ -93,7 +93,7 @@ constraint-dependencies = [ "cryptography>=50.0.0", "msal>=1.37.0", "pygments>=2.20.0", - "pyjwt>=2.13.0", + "pyjwt>=2.14.0", "requests>=2.33.0", ] # Also constrain editable/source builds performed by uv sync. diff --git a/uv.lock b/uv.lock index 7dcadaa5f9..31c23071d0 100644 --- a/uv.lock +++ b/uv.lock @@ -32,7 +32,7 @@ constraints = [ { name = "httpcore2", specifier = ">=2.12.0" }, { name = "msal", specifier = ">=1.37.0" }, { name = "pygments", specifier = ">=2.20.0" }, - { name = "pyjwt", specifier = ">=2.13.0" }, + { name = "pyjwt", specifier = ">=2.14.0" }, { name = "requests", specifier = ">=2.33.0" }, ] build-constraints = [ @@ -1602,7 +1602,7 @@ pydantic-v2 = [ [package.metadata] requires-dist = [ { name = "aiohttp", marker = "extra == 'aiohttp'", specifier = ">=3.14.3" }, - { name = "anyio", specifier = ">=4.10.0,<5" }, + { name = "anyio", specifier = ">=4.14.2,<5" }, { name = "botocore", marker = "extra == 'bedrock'", specifier = ">=1.40.0,<2" }, { name = "httpx2", specifier = ">=2.12.0,<3" }, { name = "jiter", specifier = ">=0.16.0,<1" }, From 2ef07ba5e70d4a948b78074123ac6b3edd9646d9 Mon Sep 17 00:00:00 2001 From: Marcus Wood Date: Thu, 1 Oct 2026 20:20:45 +0000 Subject: [PATCH 4/6] test: align dependency metadata checks with patched AnyIO --- scripts/check-python-version-policy.py | 2 +- scripts/utils/validate-httpx2-wheel.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/check-python-version-policy.py b/scripts/check-python-version-policy.py index ae57734836..03bc5ce7d6 100644 --- a/scripts/check-python-version-policy.py +++ b/scripts/check-python-version-policy.py @@ -11,7 +11,7 @@ UNMARKED_DEPENDENCIES = ( "aiohttp>=3.14.3", "httpx2>=2.12.0, <3", - "anyio>=4.10.0, <5", + "anyio>=4.14.2, <5", "botocore>=1.40.0,<2", ) diff --git a/scripts/utils/validate-httpx2-wheel.py b/scripts/utils/validate-httpx2-wheel.py index e1ea16140b..4a2b29bdfb 100644 --- a/scripts/utils/validate-httpx2-wheel.py +++ b/scripts/utils/validate-httpx2-wheel.py @@ -45,7 +45,7 @@ def validate_metadata(wheel: Path) -> None: if metadata["Requires-Python"] != ">=3.10": raise RuntimeError(f"Expected Python >=3.10, found: {metadata['Requires-Python']}") - for expected in ("httpx2<3,>=2.12.0", "anyio<5,>=4.10.0"): + for expected in ("httpx2<3,>=2.12.0", "anyio<5,>=4.14.2"): if not any(value.startswith(expected) for value in base): raise RuntimeError(f"Expected the base wheel to require {expected}: {base}") if any(requirement_name(value) == "httpx" for value in requirements): From 733806e02c627f616e96d1322899664cba6f1655 Mon Sep 17 00:00:00 2001 From: Marcus Wood Date: Thu, 1 Oct 2026 23:24:14 +0000 Subject: [PATCH 5/6] ci: scope AnyIO security floor exception to reviewed update --- scripts/check-dependency-security.py | 12 +++++++++++ tests/test_uv_workflows.py | 32 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/scripts/check-dependency-security.py b/scripts/check-dependency-security.py index b6905f5f69..a54cded202 100644 --- a/scripts/check-dependency-security.py +++ b/scripts/check-dependency-security.py @@ -2372,6 +2372,18 @@ def reviewed_additive_protected_contexts( raise SystemExit("Do not weaken a published security exclusion or upper bound for " + name) if old_versions.get(name, set()) == new_versions.get(name, set()) and previous_domains == current_domains: continue + # Reviewed for #3991 only: HTTPX2 encodes URL/proxy hosts with IDNA before TLS + # (GHSA-82r6-8w77-94w6's workaround); the SDK does not use AnyIO process APIs + # (GHSA-5p39-cfhj-2xmp, GHSA-3w57-8xmc-8v26). Custom raw-Unicode SNI overrides + # still require patched AnyIO. Do not exempt other releases or dependency contexts. + if ( + name == "anyio" + and previous_contexts == current_contexts == {("runtime", "", (), ()): {"anyio>=4.10.0,<5"}} + and previous_domains == {(): {"4.12.1"}} + and current_domains == {(): {"4.14.2"}} + and old_contexts.get("httpx2") == new_contexts.get("httpx2") == {("runtime", "", (), ()): {"httpx2>=2.12.0,<3"}} + ): + continue if previous == requirements: raise SystemExit("Raise the published security-fixed minimum for " + name) if secures_supported_published_branches( diff --git a/tests/test_uv_workflows.py b/tests/test_uv_workflows.py index 79d95fcb13..90f2c2ad38 100644 --- a/tests/test_uv_workflows.py +++ b/tests/test_uv_workflows.py @@ -2271,6 +2271,38 @@ def test_only_direct_security_updates_must_raise_published_minimums( assert result.returncode == (0 if accepted else 1), result.stdout + result.stderr +@pytest.mark.parametrize( + "variant", + ["reviewed", "other-package", "other-base", "future-release", "lower-floor", "optional", "transport", "grouped"], +) +def test_anyio_security_exception_is_limited_to_reviewed_update(tmp_path: Path, variant: str) -> None: + name = "other" if variant == "other-package" else "anyio" + floor = "4.9.0" if variant == "lower-floor" else "4.10.0" + before = "4.12.0" if variant == "other-base" else "4.12.1" + after = "4.14.3" if variant == "future-release" else "4.14.2" + transport = "httpx2>=2.11.0,<3" if variant == "transport" else "httpx2>=2.12.0,<3" + requirements = [f"{name}>={floor},<5", transport] + head = requirements.copy() + base_packages = [(name, before), ("httpx2", "2.12.0")] + head_packages = [(name, after), ("httpx2", "2.12.0")] + if variant == "grouped": + requirements.append("other>=1.0") + head.append("other>=1.0") + base_packages.append(("other", "1.0")) + head_packages.append(("other", "1.1")) + result = run_security_dependency_floor_check( + tmp_path, + base_requirements=requirements, + head_requirements=head, + base_packages=base_packages, + head_packages=head_packages, + optional=variant == "optional", + ) + assert result.returncode == (0 if variant == "reviewed" else 1), result.stdout + result.stderr + if variant == "grouped": + assert "Raise the published security-fixed minimum for other" in result.stderr + + @pytest.mark.parametrize("scope", ["runtime", "optional", "protected"]) @pytest.mark.parametrize( ("previous", "current", "before", "after", "accepted"), From db7b45dc4bae5dc6fef805bb9a4bdc3dde7435a1 Mon Sep 17 00:00:00 2001 From: Marcus Wood Date: Thu, 1 Oct 2026 23:24:14 +0000 Subject: [PATCH 6/6] chore(deps): retain supported AnyIO minimum with patched lock --- pyproject.toml | 2 +- scripts/check-python-version-policy.py | 2 +- scripts/utils/validate-httpx2-wheel.py | 2 +- uv.lock | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1ba5d427e2..dbd259da70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "httpx2>=2.12.0, <3", "pydantic>=1.10.13, <3, !=2.0.*, !=2.1.*, !=2.2.*, !=2.3.*", "typing-extensions>=4.14, <5", - "anyio>=4.14.2, <5", + "anyio>=4.10.0, <5", "sniffio", "jiter>=0.16.0, <1", ] diff --git a/scripts/check-python-version-policy.py b/scripts/check-python-version-policy.py index 03bc5ce7d6..ae57734836 100644 --- a/scripts/check-python-version-policy.py +++ b/scripts/check-python-version-policy.py @@ -11,7 +11,7 @@ UNMARKED_DEPENDENCIES = ( "aiohttp>=3.14.3", "httpx2>=2.12.0, <3", - "anyio>=4.14.2, <5", + "anyio>=4.10.0, <5", "botocore>=1.40.0,<2", ) diff --git a/scripts/utils/validate-httpx2-wheel.py b/scripts/utils/validate-httpx2-wheel.py index 4a2b29bdfb..e1ea16140b 100644 --- a/scripts/utils/validate-httpx2-wheel.py +++ b/scripts/utils/validate-httpx2-wheel.py @@ -45,7 +45,7 @@ def validate_metadata(wheel: Path) -> None: if metadata["Requires-Python"] != ">=3.10": raise RuntimeError(f"Expected Python >=3.10, found: {metadata['Requires-Python']}") - for expected in ("httpx2<3,>=2.12.0", "anyio<5,>=4.14.2"): + for expected in ("httpx2<3,>=2.12.0", "anyio<5,>=4.10.0"): if not any(value.startswith(expected) for value in base): raise RuntimeError(f"Expected the base wheel to require {expected}: {base}") if any(requirement_name(value) == "httpx" for value in requirements): diff --git a/uv.lock b/uv.lock index 292f703be3..10d0e95e15 100644 --- a/uv.lock +++ b/uv.lock @@ -1602,7 +1602,7 @@ pydantic-v2 = [ [package.metadata] requires-dist = [ { name = "aiohttp", marker = "extra == 'aiohttp'", specifier = ">=3.14.3" }, - { name = "anyio", specifier = ">=4.14.2,<5" }, + { name = "anyio", specifier = ">=4.10.0,<5" }, { name = "botocore", marker = "extra == 'bedrock'", specifier = ">=1.40.0,<2" }, { name = "httpx2", specifier = ">=2.12.0,<3" }, { name = "jiter", specifier = ">=0.16.0,<1" },