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

Call get_method_hook when methods are used in decorators #10675

Merged

Conversation

pranavrajpal
Copy link
Contributor

Currently, when methods are used in decorators, instead of correctly calling get_method_hook with '{module_name}.{class_name}.{method_name}' (with module_name, class_name, and method_name filled in with their correct values), get_function_hook is called instead with '{method_name} of {class_name}'. This PR fixes this bug by calling get_method_hook correctly.

Technically, this may break some plugins if they relied on the fact that get_function_hook would be called on methods used in decorators, because with this PR those calls get moved to get_method_hook. I'm guessing that this is rare, but I don't know for sure if any plugins rely on that.

Currently, this only works when you access the method in the decorator itself, instead of assigning the method to a local variable. So, for example (assuming obj is an object that has a method meth), this works:

@obj.meth
def f() -> None:
    pass

but this doesn't:

method = obj.meth
@method
def f() -> None:
    pass

Currently, the second case causes mypy to pass __main__.method to get_function_hook instead of passing the same thing as the first case. I added a test that's currently marked as xfail for the second case, but I'm not really sure how to fix it.

Test Plan

I added a test to check-custom-plugin.test to make sure that the correct method name is getting passed to plugins and that it is getting passed to the correct plugin hook.

When a method is used in a decorator, pass the full name to plugins
through the get_method_hook function, just like we would normally do for
other places that methods got called. Previously, in these situations,
we would call get_function_hook instead with '{method_name} of
{class_name}', which loses information about which module the class is
located in, and gives information about a method to the hook meant for
functions.

Currently this is limited to situations where the method is accessed in
the decorator itself, so

    @obj.meth
    def f() -> None: ...

would work but

    method = obj.meth
    @method
    def f() -> None: ...

probably wouldn't work.
Add a test case that makes sure that methods used as decorators are
passed to the get_method_hook with the correct name. This was fixed in
the previous commit, so this test is currently passing.
Add a test that checks if plugins are correctly called with
'{class_name}.{method_name}' when a method is assigned to a local
variable and then used as a decorator, instead of the current behavior,
which is calling the plugin with '{module_name}.{local_variable_name}'
where local_variable_name is the variable that the method was assigned
to.

This is currently marked as xfail because this doesn't work right now.
The `fullname is None` check is redundant because of the outer if
statement, and self.type_map stores Type, not Optional[Type], so the
`object_type is not None` check is unnecessary.
Reproducing the bug that causes a method name like 'a of Foo' to get
passed to get_function_hook happens any time a method is used in a
decorator, meaning the overloading is unnecessary for the test.
Copy link
Collaborator

@msullivan msullivan left a comment

Choose a reason for hiding this comment

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

Looks great, thanks! Drop the xfailed test, and then I can merge it

test-data/unit/check-custom-plugin.test Outdated Show resolved Hide resolved
Remove test marked with xfail because getting it to work probably would
require a lot of other changes.
@msullivan msullivan merged commit e4c2668 into python:master Jun 22, 2021
@pranavrajpal pranavrajpal deleted the call-plugins-for-methods-in-decorators branch June 22, 2021 02:32
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 this pull request may close these issues.

None yet

2 participants