Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with parametric types and promotion #169

Closed
nstarman opened this issue Jun 25, 2024 · 2 comments · Fixed by #170
Closed

Problems with parametric types and promotion #169

nstarman opened this issue Jun 25, 2024 · 2 comments · Fixed by #170

Comments

@nstarman
Copy link
Contributor

Consider

from dataclasses import dataclass
from plum import promote, parametric, add_promotion_rule
from typing import Any

@parametric
@dataclass
class Class:
    a: int | float
    b: int | float

    @classmethod
    def __init_type_parameter__(self, a: type, b: type) -> tuple[type, type]:
        """Check whether the type parameters are valid."""
        return a, b

    @classmethod
    def __infer_type_parameter__(self, a: Any, b: Any) -> tuple[type, type]:
        """Inter the type parameter from the arguments."""
        print(a, b)
        return type(a), type(b)

x = Class(1, 2)  # Class[int, int]
y = Class(1.0, 2.0)  # Class[float, float]

plum appears to auto-register a self-promotion pathway, but parametric types produce subclasses, so the promotion doesn't cover the types.

promote(x, y)
# TypeError: No promotion rule for `__main__.Class[int, int]` and `__main__.Class[float, float]`.

If I register a generic promotion for Class to cover its subclasses then I hit the the MethodRedefinitionWarning

add_promotion_rule(Class, Class, Class)
promote(x, y)
# MethodRedefinitionWarning: `Method(function_name='_promotion_rule', ...
# (Class[int, int](a=1, b=2), Class[float, float](a=1.0, b=2.0))

There does not appear to be a way to register a generic dispatch for parametric types without incurring MethodRedefinitionWarning!

@wesselb
Copy link
Member

wesselb commented Jun 25, 2024

@nstarman I believe this is due to this bit of the promotion mechanism, which, in this case, indeed defines a method that overwrites another.

I'm strongly considering whether we should make the redefinition warnings opt in, so e.g. one would write dispatch = Dispatcher(warn_redefinition=True).

@nstarman
Copy link
Contributor Author

I think dispatch = Dispatcher(warn_redefinition=True) is a good idea!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants