From b997b9093d8f8aa685a46b246242403d9e32f0ef Mon Sep 17 00:00:00 2001 From: zowoq <59103226+zowoq@users.noreply.github.com> Date: Wed, 8 Oct 2025 09:52:47 +1000 Subject: [PATCH 1/6] go_1_25: 1.25.1 -> 1.25.2 Changelog: https://go.dev/doc/devel/release#go1.25 (cherry picked from commit c27d4b0b745774e5ee1d7f23201b430726c18d6a) --- pkgs/development/compilers/go/1.25.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/development/compilers/go/1.25.nix b/pkgs/development/compilers/go/1.25.nix index b25f60b3d5ae..0908ef39dec9 100644 --- a/pkgs/development/compilers/go/1.25.nix +++ b/pkgs/development/compilers/go/1.25.nix @@ -28,11 +28,11 @@ let in stdenv.mkDerivation (finalAttrs: { pname = "go"; - version = "1.25.1"; + version = "1.25.2"; src = fetchurl { url = "https://go.dev/dl/go${finalAttrs.version}.src.tar.gz"; - hash = "sha256-0BDBCc7pTYDv5oHqtGvepJGskGv0ZYPDLp8NuwvRpZQ="; + hash = "sha256-NxEUDPuH/Oj3oT982GDfBB5sEvdhD0DKxuxvorZeluQ="; }; strictDeps = true; From cb8b359b5fadbb54dd9186001c3e9c4f32b49ff7 Mon Sep 17 00:00:00 2001 From: K900 Date: Wed, 8 Oct 2025 13:14:21 +0300 Subject: [PATCH 2/6] python313Packages.pip-tools: 7.4.1 -> 7.5.1 - switch to github source (pypi artifacts are named weird now) - update test skips --- .../python-modules/pip-tools/default.nix | 37 ++++++------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/pkgs/development/python-modules/pip-tools/default.nix b/pkgs/development/python-modules/pip-tools/default.nix index a5a04a886480..f73dbc454550 100644 --- a/pkgs/development/python-modules/pip-tools/default.nix +++ b/pkgs/development/python-modules/pip-tools/default.nix @@ -4,7 +4,7 @@ buildPythonPackage, build, click, - fetchPypi, + fetchFromGitHub, pep517, pip, pytest-xdist, @@ -19,14 +19,16 @@ buildPythonPackage rec { pname = "pip-tools"; - version = "7.4.1"; + version = "7.5.1"; pyproject = true; disabled = pythonOlder "3.8"; - src = fetchPypi { - inherit pname version; - hash = "sha256-hkgm9Qc4ZEUOJNvuuFzjkgzfsJhIo9aev1N7Uh8UvMk="; + src = fetchFromGitHub { + owner = "jazzband"; + repo = "pip-tools"; + tag = "v${version}"; + hash = "sha256-o2qpaiy+oL3QzfVaGaaRa+2drCjzc6YwNsJlK8NBICY="; }; patches = [ ./fix-setup-py-bad-syntax-detection.patch ]; @@ -59,29 +61,12 @@ buildPythonPackage rec { disabledTests = [ # Tests require network access "network" - "test_direct_reference_with_extras" - "test_local_duplicate_subdependency_combined" "test_bad_setup_file" - # Assertion error - "test_compile_recursive_extras" - "test_combine_different_extras_of_the_same_package" - "test_diff_should_not_uninstall" - "test_cli_compile_all_extras_with_multiple_packages" - # Deprecations + "test_compile_build_targets_setuptools_no_wheel_dep" + "test_compile_recursive_extras_build_targets" + "test_direct_reference_with_extras" "test_error_in_pyproject_toml" - - # pip 25.0 compat issues - # https://github.com/jazzband/pip-tools/issues/2112 - # requirement doesn't end with semicolon - "test_resolver" - "test_resolver__custom_unsafe_deps" - # constraints.txt is now in a tmpdir - "test_preserve_via_requirements_constrained_dependencies_when_run_twice" - "test_annotate_option" - # TypeError("'<' not supported between instances of 'InstallationCandidate' and 'InstallationCandidate'")>.exit_code - "test_no_candidates" - "test_no_candidates_pre" - "test_failure_of_legacy_resolver_prompts_for_backtracking" + "test_local_duplicate_subdependency_combined" ]; pythonImportsCheck = [ "piptools" ]; From 697c16364fee72d3ccd81db2a6efe53e6b284c11 Mon Sep 17 00:00:00 2001 From: K900 Date: Wed, 8 Oct 2025 13:25:47 +0300 Subject: [PATCH 3/6] python313Packages.pyopenssl: skip test broken by openssl 3.6.0 --- pkgs/development/python-modules/pyopenssl/default.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/development/python-modules/pyopenssl/default.nix b/pkgs/development/python-modules/pyopenssl/default.nix index ebbfcaff6c1f..aab03cea1990 100644 --- a/pkgs/development/python-modules/pyopenssl/default.nix +++ b/pkgs/development/python-modules/pyopenssl/default.nix @@ -64,6 +64,8 @@ buildPythonPackage rec { "test_wantWriteError" # https://github.com/pyca/pyopenssl/issues/1043 "test_alpn_call_failure" + # https://github.com/pyca/pyopenssl/issues/1455 + "test_client_receives_servers_data" ] ++ lib.optionals (lib.hasPrefix "libressl" openssl.meta.name) [ # https://github.com/pyca/pyopenssl/issues/791 From 19d426681272b83a9c8c6215b6a80b7351d7cf6c Mon Sep 17 00:00:00 2001 From: K900 Date: Wed, 8 Oct 2025 13:54:34 +0300 Subject: [PATCH 4/6] python313Packages.py-vapid: pick patch to fix tests with latest cryptography --- .../py-vapid/cryptography.patch | 270 ++++++++++++++++++ .../python-modules/py-vapid/default.nix | 6 + 2 files changed, 276 insertions(+) create mode 100644 pkgs/development/python-modules/py-vapid/cryptography.patch diff --git a/pkgs/development/python-modules/py-vapid/cryptography.patch b/pkgs/development/python-modules/py-vapid/cryptography.patch new file mode 100644 index 000000000000..d38088931b44 --- /dev/null +++ b/pkgs/development/python-modules/py-vapid/cryptography.patch @@ -0,0 +1,270 @@ +--- a/py_vapid/__init__.py ++++ b/py_vapid/__init__.py +@@ -25,6 +25,7 @@ + + class VapidException(Exception): + """An exception wrapper for Vapid.""" ++ + pass + + +@@ -34,6 +35,7 @@ class Vapid01(object): + https://tools.ietf.org/html/draft-ietf-webpush-vapid-01 + + """ ++ + _private_key = None + _public_key = None + _schema = "WebPush" +@@ -65,14 +67,14 @@ def from_raw(cls, private_raw): + key = ec.derive_private_key( + int(binascii.hexlify(b64urldecode(private_raw)), 16), + curve=ec.SECP256R1(), +- backend=default_backend()) ++ backend=default_backend(), ++ ) + return cls(key) + + @classmethod + def from_raw_public(cls, public_raw): + key = ec.EllipticCurvePublicKey.from_encoded_point( +- curve=ec.SECP256R1(), +- data=b64urldecode(public_raw) ++ curve=ec.SECP256R1(), data=b64urldecode(public_raw) + ) + ss = cls() + ss._public_key = key +@@ -87,8 +89,7 @@ def from_pem(cls, private_key): + + """ + # not sure why, but load_pem_private_key fails to deserialize +- return cls.from_der( +- b''.join(private_key.splitlines()[1:-1])) ++ return cls.from_der(b"".join(private_key.splitlines()[1:-1])) + + @classmethod + def from_der(cls, private_key): +@@ -98,9 +99,9 @@ def from_der(cls, private_key): + :type private_key: bytes + + """ +- key = serialization.load_der_private_key(b64urldecode(private_key), +- password=None, +- backend=default_backend()) ++ key = serialization.load_der_private_key( ++ b64urldecode(private_key), password=None, backend=default_backend() ++ ) + return cls(key) + + @classmethod +@@ -118,13 +119,13 @@ def from_file(cls, private_key_file=None): + vapid.generate_keys() + vapid.save_key(private_key_file) + return vapid +- with open(private_key_file, 'r') as file: ++ with open(private_key_file, "r") as file: + private_key = file.read() + try: + if "-----BEGIN" in private_key: +- vapid = cls.from_pem(private_key.encode('utf8')) ++ vapid = cls.from_pem(private_key.encode("utf8")) + else: +- vapid = cls.from_der(private_key.encode('utf8')) ++ vapid = cls.from_der(private_key.encode("utf8")) + return vapid + except Exception as exc: + logging.error("Could not open private key file: %s", repr(exc)) +@@ -156,11 +157,10 @@ def verify(cls, key, auth): + type key: str + + """ +- tokens = auth.rsplit(' ', 1)[1].rsplit('.', 1) ++ tokens = auth.rsplit(" ", 1)[1].rsplit(".", 1) + kp = cls().from_raw_public(key.encode()) + return kp.verify_token( +- validation_token=tokens[0].encode(), +- verification_token=tokens[1] ++ validation_token=tokens[0].encode(), verification_token=tokens[1] + ) + + @property +@@ -197,20 +197,19 @@ def public_key(self): + + def generate_keys(self): + """Generate a valid ECDSA Key Pair.""" +- self.private_key = ec.generate_private_key(ec.SECP256R1, +- default_backend()) ++ self.private_key = ec.generate_private_key(curve=ec.SECP256R1(), backend=default_backend()) + + def private_pem(self): + return self.private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, +- encryption_algorithm=serialization.NoEncryption() ++ encryption_algorithm=serialization.NoEncryption(), + ) + + def public_pem(self): + return self.public_key.public_bytes( + encoding=serialization.Encoding.PEM, +- format=serialization.PublicFormat.SubjectPublicKeyInfo ++ format=serialization.PublicFormat.SubjectPublicKeyInfo, + ) + + def save_key(self, key_file): +@@ -245,14 +244,14 @@ def verify_token(self, validation_token, verification_token): + :rtype: boolean + + """ +- hsig = b64urldecode(verification_token.encode('utf8')) ++ hsig = b64urldecode(verification_token.encode("utf8")) + r = int(binascii.hexlify(hsig[:32]), 16) + s = int(binascii.hexlify(hsig[32:]), 16) + try: + self.public_key.verify( + ecutils.encode_dss_signature(r, s), + validation_token, +- signature_algorithm=ec.ECDSA(hashes.SHA256()) ++ signature_algorithm=ec.ECDSA(hashes.SHA256()), + ) + return True + except InvalidSignature: +@@ -260,23 +259,25 @@ def verify_token(self, validation_token, verification_token): + + def _base_sign(self, claims): + cclaims = copy.deepcopy(claims) +- if not cclaims.get('exp'): +- cclaims['exp'] = int(time.time()) + 86400 +- if not self.conf.get('no-strict', False): +- valid = _check_sub(cclaims.get('sub', '')) ++ if not cclaims.get("exp"): ++ cclaims["exp"] = int(time.time()) + 86400 ++ if not self.conf.get("no-strict", False): ++ valid = _check_sub(cclaims.get("sub", "")) + else: +- valid = cclaims.get('sub') is not None ++ valid = cclaims.get("sub") is not None + if not valid: + raise VapidException( + "Missing 'sub' from claims. " +- "'sub' is your admin email as a mailto: link.") +- if not re.match(r"^https?://[^/:]+(:\d+)?$", +- cclaims.get("aud", ""), +- re.IGNORECASE): ++ "'sub' is your admin email as a mailto: link." ++ ) ++ if not re.match( ++ r"^https?://[^/:]+(:\d+)?$", cclaims.get("aud", ""), re.IGNORECASE ++ ): + raise VapidException( + "Missing 'aud' from claims. " + "'aud' is the scheme, host and optional port for this " +- "transaction e.g. https://example.com:8080") ++ "transaction e.g. https://example.com:8080" ++ ) + return cclaims + + def sign(self, claims, crypto_key=None): +@@ -292,19 +293,22 @@ def sign(self, claims, crypto_key=None): + + """ + sig = sign(self._base_sign(claims), self.private_key) +- pkey = 'p256ecdsa=' ++ pkey = "p256ecdsa=" + pkey += b64urlencode( + self.public_key.public_bytes( + serialization.Encoding.X962, +- serialization.PublicFormat.UncompressedPoint +- )) ++ serialization.PublicFormat.UncompressedPoint, ++ ) ++ ) + if crypto_key: +- crypto_key = crypto_key + ';' + pkey ++ crypto_key = crypto_key + ";" + pkey + else: + crypto_key = pkey + +- return {"Authorization": "{} {}".format(self._schema, sig.strip('=')), +- "Crypto-Key": crypto_key} ++ return { ++ "Authorization": "{} {}".format(self._schema, sig.strip("=")), ++ "Crypto-Key": crypto_key, ++ } + + + class Vapid02(Vapid01): +@@ -313,6 +317,7 @@ class Vapid02(Vapid01): + https://tools.ietf.org/html/rfc8292 + + """ ++ + _schema = "vapid" + + def sign(self, claims, crypto_key=None): +@@ -329,14 +334,11 @@ def sign(self, claims, crypto_key=None): + """ + sig = sign(self._base_sign(claims), self.private_key) + pkey = self.public_key.public_bytes( +- serialization.Encoding.X962, +- serialization.PublicFormat.UncompressedPoint +- ) +- return{ ++ serialization.Encoding.X962, serialization.PublicFormat.UncompressedPoint ++ ) ++ return { + "Authorization": "{schema} t={t},k={k}".format( +- schema=self._schema, +- t=sig, +- k=b64urlencode(pkey) ++ schema=self._schema, t=sig, k=b64urlencode(pkey) + ) + } + +@@ -349,27 +351,23 @@ def verify(cls, auth): + :rtype: bool + + """ +- pref_tok = auth.rsplit(' ', 1) +- assert pref_tok[0].lower() == cls._schema, ( +- "Incorrect schema specified") ++ pref_tok = auth.rsplit(" ", 1) ++ assert pref_tok[0].lower() == cls._schema, "Incorrect schema specified" + parts = {} +- for tok in pref_tok[1].split(','): +- kv = tok.split('=', 1) ++ for tok in pref_tok[1].split(","): ++ kv = tok.split("=", 1) + parts[kv[0]] = kv[1] +- assert 'k' in parts.keys(), ( +- "Auth missing public key 'k' value") +- assert 't' in parts.keys(), ( +- "Auth missing token set 't' value") +- kp = cls().from_raw_public(parts['k'].encode()) +- tokens = parts['t'].rsplit('.', 1) ++ assert "k" in parts.keys(), "Auth missing public key 'k' value" ++ assert "t" in parts.keys(), "Auth missing token set 't' value" ++ kp = cls().from_raw_public(parts["k"].encode()) ++ tokens = parts["t"].rsplit(".", 1) + return kp.verify_token( +- validation_token=tokens[0].encode(), +- verification_token=tokens[1] ++ validation_token=tokens[0].encode(), verification_token=tokens[1] + ) + + + def _check_sub(sub): +- """ Check to see if the `sub` is a properly formatted `mailto:` ++ """Check to see if the `sub` is a properly formatted `mailto:` + + a `mailto:` should be a SMTP mail address. Mind you, since I run + YouFailAtEmail.com, you have every right to yell about how terrible +@@ -382,9 +380,7 @@ def _check_sub(sub): + :rtype: bool + + """ +- pattern = ( +- r"^(mailto:.+@((localhost|[%\w-]+(\.[%\w-]+)+|([0-9a-f]{1,4}):+([0-9a-f]{1,4})?)))|https:\/\/(localhost|[\w-]+\.[\w\.-]+|([0-9a-f]{1,4}:+)+([0-9a-f]{1,4})?)$" # noqa +- ) ++ pattern = r"^(mailto:.+@((localhost|[%\w-]+(\.[%\w-]+)+|([0-9a-f]{1,4}):+([0-9a-f]{1,4})?)))|https:\/\/(localhost|[\w-]+\.[\w\.-]+|([0-9a-f]{1,4}:+)+([0-9a-f]{1,4})?)$" # noqa + return re.match(pattern, sub, re.IGNORECASE) is not None diff --git a/pkgs/development/python-modules/py-vapid/default.nix b/pkgs/development/python-modules/py-vapid/default.nix index 494afb7008d3..83042bf54525 100644 --- a/pkgs/development/python-modules/py-vapid/default.nix +++ b/pkgs/development/python-modules/py-vapid/default.nix @@ -22,6 +22,12 @@ buildPythonPackage rec { hash = "sha256-PIlzts+DhK0MmuZNYnDMxIDguSxwLY9eoswD5rUSR/k="; }; + patches = [ + # Fix tests with latest cryptography + # Upstream PR: https://github.com/web-push-libs/vapid/pull/110 + ./cryptography.patch + ]; + build-system = [ setuptools ]; dependencies = [ cryptography ]; From 84b586af72066183d3be71aa04043e8ac7acda3d Mon Sep 17 00:00:00 2001 From: K900 Date: Wed, 8 Oct 2025 13:57:32 +0300 Subject: [PATCH 5/6] python313Packages.parsel: skip test broken by error message format change --- pkgs/development/python-modules/parsel/default.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkgs/development/python-modules/parsel/default.nix b/pkgs/development/python-modules/parsel/default.nix index 750b61b13d48..e78c495f90c5 100644 --- a/pkgs/development/python-modules/parsel/default.nix +++ b/pkgs/development/python-modules/parsel/default.nix @@ -42,6 +42,11 @@ buildPythonPackage rec { pythonImportsCheck = [ "parsel" ]; + disabledTests = [ + # asserts on the exact output format of an error message + "test_set_xpathfunc" + ]; + meta = with lib; { description = "Python library to extract data from HTML and XML using XPath and CSS selectors"; homepage = "https://github.com/scrapy/parsel"; From f49ca9070b8cf209d6b1c6f35b0c31a5e5ad7672 Mon Sep 17 00:00:00 2001 From: K900 Date: Wed, 8 Oct 2025 14:17:04 +0300 Subject: [PATCH 6/6] python313Packages.uvloop: skip test broken by error message wording change --- pkgs/development/python-modules/uvloop/default.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/development/python-modules/uvloop/default.nix b/pkgs/development/python-modules/uvloop/default.nix index bde90d49d258..9c4be78c1c72 100644 --- a/pkgs/development/python-modules/uvloop/default.nix +++ b/pkgs/development/python-modules/uvloop/default.nix @@ -80,6 +80,8 @@ buildPythonPackage rec { "tests/test_base.py::TestBaseUV.test_call_at" # Pointless and flaky (at least on darwin, depending on the sandbox perhaps) "tests/test_dns.py" + # Asserts on exact wording of error message + "tests/test_tcp.py::Test_AIO_TCP::test_create_connection_open_con_addr" ] ++ lib.optionals (pythonOlder "3.11") [ "tests/test_tcp.py::Test_UV_TCPSSL::test_create_connection_ssl_failed_certificat"