Package: src:python-hypothesis
Version: 6.155.7-1
User: [email protected]
Usertags: python3.15
Tags: patch, ftbfs, forky, sid

Hi!

While rebuilding the python related packages against the Python 3.15rc1
version we found that python-hypothesis fails to build from source [1].
The problem has already been fixed upstream with [2], included in
v6.165.7.

I applied the upstream fix in the sandbox [3] to be able to build the
packages that depend on python-hypothesis, please consider applying the
patch to support the upcoming 3.15 version.

As a side note, the patch also applies to the version in salsa's
repository, but using that package also required us to finishing the
repackaging for the rust + maturin version (arch:all to arch:any, docs
need to be build explicitly, fix installation paths avoid installing in
usr/lib/python3.XX).

Happy hacking,

[1]: https://debusine.debian.net/debian/r-python-python3.15/artifact/4436475/
[2]: 
https://github.com/HypothesisWorks/hypothesis/commit/37999eb97e416a19881c3cc463f9f7a73623d0e7
[3]: https://debusine.debian.net/debian/r-python-python3.15/
--
"Can you imagine what I would do if I could do all I can?" -- Sun Tzu
Saludos /\/\ /\ >< `/
Description: claude: support Python 3.15
 Backport upstream commit 37999eb97e416a19881c3cc463f9f7a73623d0e7:
Origin: backport, https://github.com/HypothesisWorks/hypothesis/commit/37999eb97e416a19881c3cc463f9f7a73623d0e7
Author: Liam DeVoe <[email protected]>

Index: python-hypothesis-6.155.7/hypothesis/src/hypothesis/internal/lambda_sources.py
===================================================================
--- python-hypothesis-6.155.7.orig/hypothesis/src/hypothesis/internal/lambda_sources.py
+++ python-hypothesis-6.155.7/hypothesis/src/hypothesis/internal/lambda_sources.py
@@ -9,6 +9,7 @@
 # obtain one at https://mozilla.org/MPL/2.0/.
 
 import ast
+import dis
 import hashlib
 import inspect
 import linecache
@@ -101,12 +102,21 @@ def _function_key(f, *, bounded_size=Fal
 
 
 class _op:
-    # Opcodes, from dis.opmap. These may change between major versions.
-    NOP = 9
-    LOAD_FAST = 85
-    LOAD_FAST_LOAD_FAST = 88
-    LOAD_FAST_BORROW = 86
-    LOAD_FAST_BORROW_LOAD_FAST_BORROW = 87
+    # Look up the opcode values dynamically, since they can change between versions. If
+    # the opcode does not exist on a version, we set it to None.
+    NOP = dis.opmap["NOP"]
+    LOAD_FAST = dis.opmap["LOAD_FAST"]
+    LOAD_FAST_LOAD_FAST = (
+        dis.opmap["LOAD_FAST_LOAD_FAST"] if sys.version_info[:2] >= (3, 13) else None
+    )
+    LOAD_FAST_BORROW = (
+        dis.opmap["LOAD_FAST_BORROW"] if sys.version_info[:2] >= (3, 14) else None
+    )
+    LOAD_FAST_BORROW_LOAD_FAST_BORROW = (
+        dis.opmap["LOAD_FAST_BORROW_LOAD_FAST_BORROW"]
+        if sys.version_info[:2] >= (3, 14)
+        else None
+    )
 
 
 def _normalize_code(f, l):
@@ -129,6 +139,8 @@ def _normalize_code(f, l):
             lambda a, b: a == [b[0] >> 4, b[0] & 15],
         ),
     ]
+    # Avoid applying any transform with an opcode that doesn't exist on this python version.
+    transforms = [t for t in transforms if None not in t[0] + t[1]]
     # augment with converse
     transforms += [
         (
Index: python-hypothesis-6.155.7/hypothesis/src/hypothesis/internal/reflection.py
===================================================================
--- python-hypothesis-6.155.7.orig/hypothesis/src/hypothesis/internal/reflection.py
+++ python-hypothesis-6.155.7/hypothesis/src/hypothesis/internal/reflection.py
@@ -346,6 +346,13 @@ def source_exec_as_module(source: str) -
 
     hexdigest = hashlib.sha384(source.encode()).hexdigest()
     result = ModuleType("hypothesis_temporary_module_" + hexdigest)
+    # ModuleType() sets __spec__ = None. Later, we call @impersonate on functions defined
+    # in the module, which gives it a real co_filename. Python traceback formatting then
+    # calls internal linecache code which warns on the combination of "real on-disk file"
+    # + "null __spec__".
+    #
+    # Sidestep this by deleting __spec__; we don't need it.
+    del result.__spec__
     assert isinstance(source, str)
     exec(source, result.__dict__)
     eval_cache[source] = result
Index: python-hypothesis-6.155.7/hypothesis/src/hypothesis/strategies/_internal/types.py
===================================================================
--- python-hypothesis-6.155.7.orig/hypothesis/src/hypothesis/strategies/_internal/types.py
+++ python-hypothesis-6.155.7/hypothesis/src/hypothesis/strategies/_internal/types.py
@@ -917,6 +917,12 @@ if sys.version_info[:2] < (3, 14):
 
     _global_type_lookup[memoryview] = st.binary().map(memoryview)
 
+if sys.version_info[:2] >= (3, 15):
+    _global_type_lookup[builtins.sentinel] = st.builds(  # type: ignore
+        builtins.sentinel,  # type: ignore
+        st.text(),
+    )
+
 
 _global_type_lookup.update(
     {
Index: python-hypothesis-6.155.7/hypothesis/tests/cover/test_interactive_example.py
===================================================================
--- python-hypothesis-6.155.7.orig/hypothesis/tests/cover/test_interactive_example.py
+++ python-hypothesis-6.155.7/hypothesis/tests/cover/test_interactive_example.py
@@ -141,6 +141,9 @@ def test_script_example_does_not_emit_wa
 
 @skipif_emscripten
 @pytest.mark.skipif(WINDOWS, reason="pexpect.spawn not supported on Windows")
+# pexpect forks, and 3.15 warns about forking from a process with threads in it,
+# which we are under xdist.
[email protected]("ignore:.*is multi-threaded.*:DeprecationWarning")
 def test_interactive_example_does_not_emit_warning():
     import pexpect
 
Index: python-hypothesis-6.155.7/hypothesis/tests/cover/test_lookup.py
===================================================================
--- python-hypothesis-6.155.7.orig/hypothesis/tests/cover/test_lookup.py
+++ python-hypothesis-6.155.7/hypothesis/tests/cover/test_lookup.py
@@ -74,12 +74,9 @@ generics = sorted(
         t
         for t in types._global_type_lookup
         # We ignore TypeVar, because it is not a Generic type:
-        if isinstance(t, types.typing_root_type)
-        and t != typing.TypeVar
-        and (
-            sys.version_info[:2] <= (3, 11)
-            or t != getattr(typing, "ByteString", object())
-        )
+        if isinstance(t, types.typing_root_type) and t != typing.TypeVar
+        # accessing ByteString warns on 3.15
+        and (not ((3, 12) <= sys.version_info[:2] < (3, 14)) or t != typing.ByteString)
     ),
     key=str,
 )
@@ -139,7 +136,8 @@ def test_typing_Type_Union(ex):
     "typ",
     [
         pytest.param(
-            getattr(collections.abc, "ByteString", ...),
+            # accessing ByteString warns on 3.15
+            collections.abc.ByteString if sys.version_info[:2] < (3, 14) else ...,
             marks=pytest.mark.skipif(sys.version_info[:2] >= (3, 14), reason="removed"),
         ),
         typing.Match,

Reply via email to