ci: update GraalPy from 24.2 to 25.0 (Python 3.12 based) (#6083)

* ci: update GraalPy from 24.2 to 25.0 (Python 3.12 based)

- Replace graalpy-24.2 with graalpy-25.0 in CI matrix
- Replace graalpy-24.1 with graalpy-24.2 (shift older version up)
- Remove dead GRAALPY_VERSION < (24, 2) xfail guards from tests
- Remove unused GRAALPY_VERSION from tests/env.py
- Update internals.h comment to reference v25.0

Assisted-by: OpenCode:glm-5

* fix: use numpy 2.2.x for GraalPy 3.12 (graalpy312 wheels)

numpy 1.26.x only has graalpy311 wheels; GraalPy 25.0 (Python 3.12)
requires numpy 2.2.x which has graalpy312 wheels on the GraalVM index.

Assisted-by: OpenCode:glm-5

* fix: simplify numpy requirement for GraalPy (drop 3.11 branch)

We no longer test GraalPy 3.11, so the version split is unnecessary.

Assisted-by: OpenCode:glm-5
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 64b6804..4e49a55 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -51,7 +51,7 @@
             python-version: 'pypy-3.11-v7.3.23'
             cmake-args: -DCMAKE_CXX_STANDARD=17
           - runs-on: ubuntu-latest
-            python-version: 'graalpy-24.2'
+            python-version: 'graalpy-25.0'
             cmake-args: -DCMAKE_CXX_STANDARD=20
           - runs-on: macos-latest
             python-version: '3.14'
@@ -96,7 +96,7 @@
             python-version: 'pypy-3.11-v7.3.23'
             cmake-args: -DCMAKE_CXX_STANDARD=14
           - runs-on: ubuntu-latest
-            python-version: 'graalpy-24.1'
+            python-version: 'graalpy-25.0'
 
           # No SciPy for macOS ARM
           - runs-on: macos-15-intel
@@ -117,7 +117,7 @@
           - runs-on: macos-latest
             python-version: 'pypy-3.11-v7.3.23'
           - runs-on: macos-latest
-            python-version: 'graalpy-24.2'
+            python-version: 'graalpy-25.0'
 
           - runs-on: windows-latest
             python-version: '3.9'
diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h
index 4175d20..7107b70 100644
--- a/include/pybind11/detail/internals.h
+++ b/include/pybind11/detail/internals.h
@@ -98,7 +98,7 @@
         // Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*
         // that the `key` be allocated with the CPython allocator (as it is by
         // PyThread_tss_create).
-        // However, in GraalPy (as of v24.2 or older), TSS is implemented by Java and this call
+        // However, in GraalPy (as of v25.0 or older), TSS is implemented by Java and this call
         // requires a living Python interpreter.
 #ifdef GRAALVM_PYTHON
         if (Py_IsInitialized() == 0 || _Py_IsFinalizing() != 0) {
diff --git a/tests/env.py b/tests/env.py
index 23995c2..d205d7e 100644
--- a/tests/env.py
+++ b/tests/env.py
@@ -29,10 +29,6 @@
 PYPY = platform.python_implementation() == "PyPy"
 PYPY_PRE_7_3_23 = PYPY and sys.pypy_version_info < (7, 3, 23)
 GRAALPY = sys.implementation.name == "graalpy"
-_graalpy_version = (
-    sys.modules["__graalpython__"].get_graalvm_version() if GRAALPY else "0.0.0"
-)
-GRAALPY_VERSION = tuple(int(t) for t in _graalpy_version.split("-")[0].split(".")[:3])
 
 # Compile-time config (what the binary was built for)
 PY_GIL_DISABLED = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))
diff --git a/tests/requirements.txt b/tests/requirements.txt
index 39bf867..53f05b6 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -4,7 +4,7 @@
 numpy~=1.23.0; python_version=="3.8" and platform_python_implementation=="PyPy"
 numpy~=1.25.0; python_version=="3.9" and platform_python_implementation=="PyPy"
 numpy~=2.2.0; python_version=="3.10" and platform_python_implementation=="PyPy"
-numpy~=1.26.0; platform_python_implementation=="GraalVM" and sys_platform=="linux"
+numpy~=2.2.0; platform_python_implementation=="GraalVM" and sys_platform=="linux"
 numpy~=1.21.5; platform_python_implementation=="CPython" and python_version>="3.8" and python_version<"3.10"
 numpy~=1.22.2; platform_python_implementation=="CPython" and python_version=="3.10"
 numpy~=1.26.0; platform_python_implementation=="CPython" and python_version>="3.11" and python_version<"3.13" and platform_machine!="ARM64"
diff --git a/tests/test_enum.py b/tests/test_enum.py
index 969c30b..53dcc09 100644
--- a/tests/test_enum.py
+++ b/tests/test_enum.py
@@ -5,13 +5,9 @@
 
 import pytest
 
-import env
 from pybind11_tests import enums as m
 
 
-@pytest.mark.xfail(
-    env.GRAALPY and env.GRAALPY_VERSION < (24, 2), reason="Fixed in GraalPy 24.2"
-)
 def test_unscoped_enum():
     assert str(m.UnscopedEnum.EOne) == "UnscopedEnum.EOne"
     assert str(m.UnscopedEnum.ETwo) == "UnscopedEnum.ETwo"
@@ -197,9 +193,6 @@
     assert repr(x) == "{<EMode.EFirstMode: 1>: 3, <EMode.ESecondMode: 2>: 4}"
 
 
-@pytest.mark.xfail(
-    env.GRAALPY and env.GRAALPY_VERSION < (24, 2), reason="Fixed in GraalPy 24.2"
-)
 def test_binary_operators():
     assert int(m.Flags.Read) == 4
     assert int(m.Flags.Write) == 2
diff --git a/tests/test_operator_overloading.py b/tests/test_operator_overloading.py
index 19c4bbb..04dfb2f 100644
--- a/tests/test_operator_overloading.py
+++ b/tests/test_operator_overloading.py
@@ -88,9 +88,6 @@
     assert cstats.move_assignments == 0
 
 
-@pytest.mark.xfail(
-    env.GRAALPY and env.GRAALPY_VERSION < (24, 2), reason="Fixed in GraalPy 24.2"
-)
 def test_operators_notimplemented():
     """#393: need to return NotSupported to ensure correct arithmetic operator behavior"""