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

Set precedence of individual types #140

Open
sylvorg opened this issue Apr 13, 2024 · 6 comments
Open

Set precedence of individual types #140

sylvorg opened this issue Apr 13, 2024 · 6 comments

Comments

@sylvorg
Copy link

sylvorg commented Apr 13, 2024

Hello, and sorry for bothering you so many times! 😅

As in the title; is there any way to set the precedence of individual types? For example, using beartype.vale.Is, I have cobbled together an annotation ExactOrigin which should be tested before Callable, for example. But when I use those two annotations in a plum function, I get an AmbiguousLookupError. Is there any way to set the precedence of ExactOrigin over Callable?

Thank you kindly for the help!

@wesselb
Copy link
Member

wesselb commented Apr 21, 2024

Hey @sylvorg, absolutely not a problem! I massively appreciate your issues. Please feel free to keep opening them!! I'll do my best to respond as quickly as possible, though sometimes I won't have the capacity to get back to you quickly.

Currently, there is no way to set the precedence of individual types. Ideally, you would create this precedence by making the one type a subtype of another. In your case, I think your problem would be solved by making ExactOrigin a subtype of Callable. Would that be possible?

@sylvorg
Copy link
Author

sylvorg commented Apr 27, 2024

No worries, take all the time you need! Greatness can't be rushed, after all!

The problem with making ExactOrigin a subtype is that ExactOrigin, and a host of other checks I've created, can't use beartype.vale.Is, which seems to only work with the Annotated hint; is there any way to implement that in a way that'll keep the signature of ExactOrigin, such as when using get_origin on something like ExactOrigin[type] and getting back ExactOrigin? ... Sorry, I may have gotten a little confused at the end there, so if you have any questions, please let me know! 😅

@sylvorg
Copy link
Author

sylvorg commented Apr 27, 2024

Also, I'd like Literal or Union to be checked before Callable, for example! 😅 Basically, anything with a smaller subset of possible types!

@wesselb
Copy link
Member

wesselb commented Apr 27, 2024

@sylvorg would you be able to give a full MWE of what you'd like to achieve, the one with beartype.vale.Is and ExactOrigin?

@sylvorg
Copy link
Author

sylvorg commented Apr 27, 2024

Basically, Origin and ExactOrigin would check the origin of an annotation, such as tuple[...] being tuple, and if the origin is None, such as for just tuple, the annotation itself is used, i.e., again, tuple. I recently raised an issue in the beartype repo to address some issues with beartype.door.is_subhint, so hopefully I won't need those anymore, but I have other Annotation types as well, such as Not (which checks that something is not in the subscripted arguments), Exclude (which takes an annotation and returns false for subtypes, such as checking if something is an integer but not a boolean), etc.

Would you happen to know how I can turn these into full-fledged classes that I can subscript as well? Because I don't know how to use __args__ of a types.GenericAlias object, for example.

@wesselb
Copy link
Member

wesselb commented May 18, 2024

Hey @sylvorg! Apologies for the delay. It's a busy and hectic time.

Plum relies on a so-called partial order between types (basically, a <= relationship). That this is a partial order is very important, because it ensures correctness of dispatch. Currently, Plum uses beartype.door.TypeHint to give this partial order.

What you seem to want to achieve is to slightly modify the partial order currently defined by beartype.door.TypeHint. I'm a little reluctant to build this into Plum, since correctness of the partial order is crucial to the correctness of dispatch.

However, what has come up before, and what would be feasible, is to make the "type system" configurable for every dispatcher.

You would be able to do something like this:

def partial_order(type1, type2):
    return TypeHint(type1) <= TypeHint(type2)

dispatch = Dispatcher(type_system=partial_order)

You could then base your partial_order off of @beartype's TypeHint and insert your optimisations.

How would something like that sound?

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

No branches or pull requests

2 participants