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

Let the multiple inheritance checks consider callable objects as possible subtypes of usual functions (Fixes #14852). #14855

Merged

Conversation

tyralla
Copy link
Contributor

@tyralla tyralla commented Mar 8, 2023

Let the multiple inheritance checks consider callable objects as possible subtypes of usual functions (Fixes #14852).

The solution is inspired by the visit_instance method of SubtypeVisitor. The testMultipleInheritanceOverridingOfFunctionsWithCallableInstances tests the new functionality for decorated and non-decorated functions and callable objects.

…ible subtypes of usual functions (Fixes python#14852).

The solution is inspired by the `visit_instance` method of `SubtypeVisitor`.  The `testMultipleInheritanceOverridingOfFunctionsWithCallableInstances` tests the new functionality for decorated and non-decorated functions and callable objects.
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2023

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

class F:
def __call__(self, x: int) -> None: ...

def dec2(f: Callable[[Any, int], None]) -> F: ...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe give it a more descriptive name, e.g. make_callable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean make_callable1 and make_callable2 for dec1 and dec2? Or different names, like make_callable and modify_function or so?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, no strong opinion TBH. After I looked at this test for a few minutes, I got acquainted with "dec1", "dec2", "A", "B" etc. It's just that on first glance dec1 and dec2 seemed less than descriptive, but they'd be perfect names in Go :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never worked with Go. Maybe I should try it...

Copy link
Contributor

@ikonst ikonst Mar 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(https://go.dev/talks/2014/names.slide does a good job at describing what's considered good style there)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i instead of index. If I remember correctly, pylint complains if I don't write at least idx.

Comment on lines +2489 to +2493
if isinstance(first_type, Instance):
call = find_member("__call__", first_type, first_type, is_operator=True)
if call and isinstance(second_type, FunctionLike):
second_sig = self.bind_and_map_method(second, second_type, ctx, base2)
ok = is_subtype(call, second_sig, ignore_pos_arg_names=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 I keep wondering if this could be somehow generalized, e.g. check compatibility between any callables the same way, with simple functions being "upgraded" to a synthetic Instance with a __call__ member. I didn't check the feasibility of this too much, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there are possibly more places where similar checks are performed (or should be performed).

A quick search for find_member("__call__",: five hits that seem to serve the same or similar purposes besides my own one.

However, there seem to be many small differences. So, refactoring it might not be simple.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a second look, just searching for "__call__". 51 hits. Many special cases. I have no idea how far a generalisation like the one you suggested would be helpful. And it would be too much effort for me, currently.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, totally understood. BTW I'm just trying to help with reviews, I'm not a maintainer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Do you know how to proceed? Besides this pull request (which I really would like to land in Mypy 1.2), I have two older ones open (#14440 and #14390). I'm not sure who to ping when and how...

@tyralla
Copy link
Contributor Author

tyralla commented Mar 17, 2023

@hauntsaninja: seems like we need a maintainer's review. Would you like to? Or who else to ask?

Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thank you!

@hauntsaninja hauntsaninja merged commit 1dd26a3 into python:master Mar 25, 2023
JukkaL pushed a commit that referenced this pull request Apr 5, 2023
…ons (#14855)

Let the multiple inheritance checks consider callable objects as
possible subtypes of usual functions (Fixes #14852).

The solution is inspired by the `visit_instance` method of
`SubtypeVisitor`. The
`testMultipleInheritanceOverridingOfFunctionsWithCallableInstances`
tests the new functionality for decorated and non-decorated functions
and callable objects.
@JukkaL JukkaL mentioned this pull request Apr 5, 2023
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multiple inheritance checks do not consider callable objects as possible subtypes of usual functions
3 participants