coady / multimethod

Multiple argument dispatching.
https://coady.github.io/multimethod
Other
284 stars 23 forks source link

TypeError in new version 1.11.1 #113

Closed vnmabus closed 8 months ago

vnmabus commented 8 months ago

I am having problems in my project with the new version 1.11.1.

In particular it seems that the following multimethod:

https://github.com/GAA-UAM/scikit-fda/blob/b43718a92bd7189e3c821913c6de447aaa25b291/skfda/misc/metrics/_utils.py#L140

is causing some kind of error due to generics:

File .../skfda/misc/metrics/_utils.py:183, in PairwiseMetric.__call__(self, elem1, elem2)
    177 def __call__(
    178     self,
    179     elem1: _MapAcceptableT,
    180     elem2: Optional[_MapAcceptableT] = None,
    181 ) -> NDArrayFloat:
    182     """Evaluate the pairwise metric."""
--> 183     optimized = pairwise_metric_optimization(self.metric, elem1, elem2)
    185     return (
    186         _pairwise_symmetric(
    187             self.metric,  # type: ignore[arg-type]
   (...)
    192         else optimized
    193     )

File .../site-packages/multimethod/__init__.py:421, in multidispatch.__call__(self, *args, **kwargs)
    419 """Resolve and dispatch to best method."""
    420 params = self.signature.bind(*args, **kwargs).args if (kwargs and self.signature) else args
--> 421 func = self.dispatch(*params)
    422 return func(*args, **kwargs)

File .../site-packages/multimethod/__init__.py:354, in multimethod.dispatch(self, *args)
    352 def dispatch(self, *args) -> Callable:
    353     types = tuple(map(type, args))
--> 354     if not any(map(issubclass, types, self.generics)):
    355         return self[types]
    356     matches = {key for key in list(self) if isinstance(key, signature) and key.instances(*args)}

File .../typing.py:1308, in _BaseGenericAlias.__subclasscheck__(self, cls)
   1307 def __subclasscheck__(self, cls):
-> 1308     raise TypeError("Subscripted generics cannot be used with"
   1309                     " class and instance checks")

TypeError: Subscripted generics cannot be used with class and instance checks

I tried unsuccessfully to create a minimum example showing the error, but as the changes in the last version are few, maybe you do not need it to locate the error.

coady commented 8 months ago

4e22af5 might be related. In addition to that, you could try logging:

ccaballeroh commented 8 months ago

I also had this same error a few days ago indirectly through Pandera. It got solved pinning the version of multimethod to 1.11. This is mentioned over here https://github.com/unionai-oss/pandera/issues/1500.

Maybe https://github.com/coady/multimethod/commit/8346c7629644248f3a73b49d2f9023e862225afb is related? I have spent a fair amount of time checking the code, but I'm over my head here.

vnmabus commented 8 months ago

4e22af5 might be related. In addition to that, you could try logging:

* the types at runtimes

* the registered types in `.generics` at import time - one of them must be a generic

It seems that self.generics is [(skfda.typing._metric.Metric[~Original], skfda.misc.metrics._utils.NormInducedMetric[typing.Union[numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], skfda.representation._functional_data.FData]], typing.Generic[~Original, ~Transformed])].

The error appears in _BaseGenericAlias.__subclasscheck__ with parameters self=skfda.typing._metric.Metric[~Original], cls=<class 'skfda.misc.metrics._lp_distances.LpDistance'>.

coady commented 8 months ago

The error appears in _BaseGenericAlias.__subclasscheck__ with parameters self=skfda.typing._metric.Metric[~Original], cls=<class 'skfda.misc.metrics._lp_distances.LpDistance'>.

Thanks, I'm confident this is fixed in main (4e22af5 and later). I'll add a regression test that's as close to Metric as possible.

If anyone on this thread can test theirs against main, that would be appreciated.

coady commented 8 months ago

Released v1.11.2.

coady commented 8 months ago

Fixed in v1.11.2.