Skip to content

Conversation

@hippo91
Copy link
Contributor

@hippo91 hippo91 commented Dec 15, 2018

Description

This PR fixes the pylint-dev/pylint#2588. The problem was that a call to a function that has been
previously called via functools.partial was wrongly inferred.

The bug comes from the _filter_stmts method of the LookupMixin class. The deletion of the current statement should not be made in the case where the node is an instance of the PartialFunction class
(brain_functools) and if the node's name is the same as the statement's name.

I tried to use isinstance function to test if the node is an instance of the PartialFunction. The problem is that this class is locally declared inside the _functools_partial_inference function of brain_functools module. Of course i was thinking of extracting this class in its own module but as it inherits from FunctionDef this module should include scoped_nodes which itself includes node_classes. And i need to include this new module into node_classes. I'am facing a circular import problem. Thus i preferred to make as less changes as possible and created a class attribute is_partial_function and test the presence of this attribute via hasattr to determine if the class is an instance of PartialFunction.

I added a test in the test_inferred_partial_function_calls of the TestFunctoolsPartial class.
Apparently this class was not tested during the CI because it doesn't inherit from unittest.TestCase!
I changed this but i think it will be needed also for other classes of the unittest_brain module.
@PCManticore am i wrong?

Type of Changes

Type
🐛 Bug fix

Related Issue

Closes pylint-dev/pylint#2588

…ing deleting statement in _filter_statements method if the node's name is the same as the current statement's name
…er_stmts method of the LookupMixin class in the case where the node is a PartialFunction and its name if the same as tue current statement's name
…test that ensures that after using partial on a function, a subsequent call of this function is still well inferred.
@hippo91
Copy link
Contributor Author

hippo91 commented Dec 15, 2018

@PCManticore it seems that Travis is failing due to formatting standard.
I can't use black on my desktop because i'm still using python3.5.
Is there any workaround?



class TestFunctoolsPartial:
class TestFunctoolsPartial(unittest.TestCase):
Copy link
Contributor

Choose a reason for hiding this comment

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

@hippo91 It's not required to add unittest.TestCase here because we use pytest and it is able to find these tests accordingly.

@PCManticore
Copy link
Contributor

@hippo91 I think it could work locally with Python 3.6 if you use pyenv to manage your Python installations. It should be a matter of pyenv install python3.6 , followed by creating a Python 3.6 virtualenv that you can use for pylint & astroid's development. I think this should be documented in our contributing guide.

Regarding the thing with unittest.TestCase, we don't need to add that as a base class, because we use pytest and it's capable of finding these tests.

if not (optional_assign or are_exclusive(_stmts[pindex], node)):
del _stmt_parents[pindex]
del _stmts[pindex]
if not hasattr(node, 'is_partial_function') or node.name != _stmts[pindex].name:
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the reason for the second check, can you add a comment for that?


filled_positionals = len(call.positional_arguments[1:])
filled_keywords = list(call.keyword_arguments)
is_partial_function = True
Copy link
Contributor

Choose a reason for hiding this comment

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

@hippo91 I wonder if we can extract PartialFunction somehow from this module. We can use astroid.objects for it, and if we need to figure out if a function is partial or not, we can implement the name property and qname function, just like we do for Super, FrozenSet and friends. And instead of checking if is_partial_function is given, we only look for .name against a predefined list of elements for which to apply the condition in the mixin. Do you think that's worth it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@PCManticore it looks interesting.
I work on it.

Copy link
Contributor

@PCManticore PCManticore left a comment

Choose a reason for hiding this comment

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

Looks good, but left a comment regarding refactoring.

@hippo91
Copy link
Contributor Author

hippo91 commented Dec 22, 2018

@PCManticore thank you for the hint concerning pyenv. It's perfect. Now i can use black.
I updated this pull request according to your remarks.
Is it what you was thinking of?

I still can't have CI ok, because of pylint complaining about chained-comparison in a piece of code i didn't change:
astroid/node_classes.py:4175:12: R1716: Simplify chained comparison between the operands (chained-comparison)
Moreover CI is also complaining about formatting whereas i ran black on the modified files. Is there a special configuration file that i missed?

Copy link
Contributor

@PCManticore PCManticore 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! Regarding black, are you using black==18.6b4 or tox -e formatting? That should be enough to make black happy here. Also feel free to ignore the new linting errors, they usually occur when we update pylint with a new check, since we use the master version in `tox.

@hippo91
Copy link
Contributor Author

hippo91 commented Jan 3, 2019

@PCManticore I succeeded in correcting the formatting error by using the same version of black. Thank you.
However i don't feel comfortable with the fact i can't pass the Travis CI even if its a matter of pylint version.
The crash in pylint test prevent the other tests to occur. Is there a way to execute them whatever the result of the pylint test is?

@PCManticore
Copy link
Contributor

Oh gotcha, I see what you mean now. The CI jobs are now grouped into stages, so first we run anything linting / formatting related, then followed by the actual tests. In this case, I think it's best to fix the linting errors in a separate PR, merge it and then rebase this one to include those fixes. also I'll be away for two weeks so won't have time to fix those myself. :)

@hippo91 hippo91 mentioned this pull request Jan 12, 2019
1 task
@PCManticore
Copy link
Contributor

Hey @hippo91 I merged this manually and pushed it to master. Thanks for the 💯 work here!

@hippo91 hippo91 deleted the bug_pylint_2588_bis branch June 20, 2020 09:06
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.

Using functools partial on a function gives a too-many-function-args when using the function

2 participants