discopy icon indicating copy to clipboard operation
discopy copied to clipboard

Fix generic type handling in assert_isinstance

Open colltoaction opened this issue 1 week ago • 1 comments

Hello! I was running into a very cursed error but finally found a test case and fix.

    def test_list_generic_in_function():
        func = Function(sum, List[int], int)
>       assert func([1, 2, 3]) == 6
               ^^^^^^^^^^^^^^^

test/semantics/python.py:82: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
discopy/python/multiplicative.py:83: in __call__
    callable(x) or assert_isinstance(x, t)
                   ^^^^^^^^^^^^^^^^^^^^^^^
discopy/utils.py:380: in assert_isinstance
    if not any(isinstance(object_, cls) for cls in classes):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
discopy/utils.py:380: in <genexpr>
    if not any(isinstance(object_, cls) for cls in classes):
               ^^^^^^^^^^^^^^^^^^^^^^^^
../../miniconda3/lib/python3.13/typing.py:1375: in __instancecheck__
    return self.__subclasscheck__(type(obj))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = typing.List[int], cls = <class 'list'>

    def __subclasscheck__(self, cls):
>       raise TypeError("Subscripted generics cannot be used with"
                        " class and instance checks")
E       TypeError: Subscripted generics cannot be used with class and instance checks

../../miniconda3/lib/python3.13/typing.py:1378: TypeError

colltoaction avatar Dec 13 '25 16:12 colltoaction

Maybe CI errors are related to https://github.com/discopy/discopy/pull/298?

colltoaction avatar Dec 13 '25 16:12 colltoaction

Mmh this looks more like a typing problem than a DisCoPy problem:

>>> from typing import List
>>> isinstance([1, 2, 3], List[int])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/atoumix/.pyenv/versions/3.12.0/lib/python3.12/typing.py", line 1169, in __instancecheck__
    return self.__subclasscheck__(type(obj))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/atoumix/.pyenv/versions/3.12.0/lib/python3.12/typing.py", line 1172, in __subclasscheck__
    raise TypeError("Subscripted generics cannot be used with"
TypeError: Subscripted generics cannot be used with class and instance checks

toumix avatar Dec 15 '25 10:12 toumix

Not sure what the problem is with the tests, looks like some JAX update broke the code, maybe you can freeze the requirement?

toumix avatar Dec 15 '25 10:12 toumix

Mmh this looks more like a typing problem than a DisCoPy problem:

That's why it is needed to wrap cls with get_origin in this call: isinstance(object_, get_origin(cls)). The original stack trace I shared shows the same __subclasscheck__.

freeze requirements

First try gives me errors with autoray. I notice there might be more changes necessary to make these work properly as seen here.

colltoaction avatar Dec 15 '25 14:12 colltoaction

I'm doing a deeper debugging session to help with the dependencies issue, but it doesn't seem related with this change.

I will undo the pyproject.toml change here in case you want to merge the fix.

colltoaction avatar Dec 15 '25 19:12 colltoaction

Thanks @toumix! If this can be released, you will make my life so much better! :)

colltoaction avatar Dec 18 '25 14:12 colltoaction

Sure thing!

toumix avatar Dec 19 '25 08:12 toumix