Hi,

The issue is caused by the latest version of mypy, which has changed how it handles type checking.

I've created a patch for this issue and sent it upstream as a PR:
https://github.com/pyapp-kit/psygnal/pull/442

Unfortunately it seems that if it works for mypy 2.4+ it fails for whichever version upstream is using in their CI, so it might need some more work to get it applied upstream. In the meantime, I plan to apply the patch in Debian to get it back to a buildable state.

--
Regards,
Marga
Description: Fix types for the latest Mypy version
 With Mypy 2.4 types now need to follow PEP 747, or the build fails.
 This patch fixes the necessary types to et Mypyc checks to succeed.
Author: Margarita Manterola <[email protected]>
Origin: debian
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1150627
Forwarded: https://github.com/pyapp-kit/psygnal/pull/442
Last-Update: 2026-10-23 
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/src/psygnal/_dataclass_utils.py
+++ b/src/psygnal/_dataclass_utils.py
@@ -9,6 +9,7 @@
 if TYPE_CHECKING:
     from collections.abc import Iterator
     from typing import TypeGuard
+    from typing_extensions import TypeForm
 
     import attrs
     import msgspec
@@ -137,7 +138,7 @@
 
 def iter_fields(
     cls: type, exclude_frozen: bool = True
-) -> Iterator[tuple[str, type | None]]:
+) -> Iterator[tuple[str, TypeForm | None]]:
     """Iterate over all fields in the class, including inherited fields.
 
     This function recognizes dataclasses, attrs classes, msgspec Structs, and pydantic
--- a/src/psygnal/_group_descriptor.py
+++ b/src/psygnal/_group_descriptor.py
@@ -25,6 +25,7 @@
     from _weakref import ref as ref
     from collections.abc import Iterable, Mapping
     from typing import TypeAlias
+    from typing_extensions import TypeForm
 
     from psygnal._group import EmissionInfo
     from psygnal._weak_callback import RefErrorChoice, WeakCallback
@@ -118,7 +119,7 @@
             return _check_field_equality(cls, name, before, after, _fail=True)
 
 
-def _pick_equality_operator(type_: type | None) -> EqOperator:
+def _pick_equality_operator(type_: TypeForm | None) -> EqOperator:
     """Get the default equality operator for a given type."""
     np = sys.modules.get("numpy", None)
     if getattr(type_, "__module__", "").startswith("dask"):
--- a/src/psygnal/_signal.py
+++ b/src/psygnal/_signal.py
@@ -167,6 +167,7 @@
 if TYPE_CHECKING:
     from collections.abc import Container, Iterable, Iterator
     from typing import TypeAlias
+    from typing_extensions import TypeForm
 
     from ._group import EmissionInfo
     from ._weak_callback import RefErrorChoice
@@ -296,7 +297,7 @@
 
     def __init__(
         self,
-        *types: type[Any] | Signature,
+        *types: TypeForm[Any] | Signature,
         description: str = "",
         name: str | None = None,
         check_nargs_on_connect: bool = True,

Reply via email to