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

Fix #5876 : To check if class arguments comes in the function then it should come first. #5919

Merged
merged 36 commits into from
Dec 22, 2018

Conversation

anubhavsinha98
Copy link
Contributor

@anubhavsinha98 anubhavsinha98 commented Nov 28, 2018

Explanation

Fixes #5876 : To check if class arguments comes in function then it should come first.

Checklist

  • The PR title starts with "Fix #bugnum: ", followed by a short, clear summary of the changes. (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
  • The PR explanation includes the words "Fixes #bugnum: ..." (or "Fixes part of #bugnum" if the PR only partially fixes an issue).
  • The linter/Karma presubmit checks have passed.
    • These should run automatically, but if not, you can manually trigger them locally using python scripts/pre_commit_linter.py and bash scripts/run_frontend_tests.sh.
  • The PR is made from a branch that's not called "develop".
  • The PR follows the style guide.
  • The PR is assigned to an appropriate reviewer.
    • If you're a new contributor, please ask on Gitter for someone to assign a reviewer.
    • If you're not sure who the appropriate reviewer is, please assign to the issue's "owner" -- see the "talk-to" label on the issue.

@codecov-io
Copy link

codecov-io commented Nov 28, 2018

Codecov Report

Merging #5919 into develop will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           develop   #5919   +/-   ##
=======================================
  Coverage     45.3%   45.3%           
=======================================
  Files          520     520           
  Lines        30667   30667           
  Branches      4597    4597           
=======================================
  Hits         13893   13893           
  Misses       16774   16774
Impacted Files Coverage Δ
...xploration_player/ExplorationPlayerStateService.js 1.53% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 05ed54f...747280c. Read the comment docs.

failed = False
for filename in files_to_check:
with open(filename, 'r') as f:
file_content = f.readlines()
Copy link
Contributor

Choose a reason for hiding this comment

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

The ast library can make this file reading and function identification much simpler. Here's a code snippet you could consider using to iterate over all of the functions in a file and access their args:

for filename in files_to_check:
    with open(filename, 'r') as f:
        ast_file = ast.walk(ast.parse(f.read()))
        func_defs = [n for n in ast_file if isinstance(n, ast.FunctionDef)]
        for func in func_defs:
            print func.name
            print function_node.args.args

@lokijuhy
Copy link
Contributor

As we discussed on gitter, I think this code should include tests. Some example tests you would want to write to make sure this code works are:

  • does a function with a first argument of self pass the check?
  • does a function with a argument of self that is in the second position fail the check?
  • does a function with no self or cls arguments pass the check?

Right now you have one function that both reads the file and performs the check. This is challenging to test, because you can't easily pass your function an example to test with. To make this code easier to test, I recommend separating the logic that reads the file from the logic that performs the argument ordering check into two separate functions. That way, you have a standalone function that performs the check, which takes a string or list as input, and therefore you can easily construct example inputs in your tests.

@aks681
Copy link
Contributor

aks681 commented Nov 29, 2018

@anubhavsinha98 Was this PR or #5916 created by accident? As both seem to fix the same issue.

@lilithxxx
Copy link
Contributor

@lokijuhy I think many checks on pre_commit_linter can use the AST approach so why not shift all of them to use that? @seanlip Whats your thought on this?

@seanlip
Copy link
Member

seanlip commented Dec 1, 2018

I think that would be a good idea, insofar as the checks relate to the actual semantic structure of the code.

@anubhavsinha98
Copy link
Contributor Author

@lilithxxx, @seanlip and @lokijuhy, I will convert this logic for the AST approach and soon update the PR.

@anubhavsinha98
Copy link
Contributor Author

And yes it's a nice idea to convert checks in pre_commit_linter, into AST approach.

@oppiabot
Copy link

oppiabot bot commented Dec 14, 2018

Hi @anubhavsinha98, I'm going to mark this PR as stale because it hasn't had any updates for 10 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue.
If you are still working on this PR, please make a follow-up commit within 7 days (and submit it for review, if applicable). Please also let us know if you are stuck so we can help you!

@oppiabot oppiabot bot added the stale label Dec 14, 2018
@oppiabot
Copy link

oppiabot bot commented Dec 19, 2018

Hi @anubhavsinha98. Due to recent changes in the "develop" branch, this PR now has a merge conflict. Please follow this link if you need help resolving the conflict, so that the PR can be merged. Thanks!

@anubhavsinha98
Copy link
Contributor Author

@apb7 , done with the custom checker. PTAL ! Thanks !

@lokijuhy
Copy link
Contributor

Looks good to me! Great job @anubhavsinha98

Copy link
Contributor

@apb7 apb7 left a comment

Choose a reason for hiding this comment

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

Hi @anubhavsinha98, took an initial pass. Also, how did you test the checker? Can you please post some logs/screenshots? Thanks!

newline_messages + docstring_messages + comment_messages +
html_tag_and_attribute_messages + html_linter_messages +
linter_messages + pattern_messages + copyright_notice_messages)
newline_messages + docstring_messages +
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will remove that.

@@ -757,6 +757,33 @@ def process_module(self, node):
'backslash-continuation', line=line_num + 1)


class FunctionArgsOrderChecker(checkers.BaseChecker):
"""Checker for order of arguments. It checks
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can have more characters in this line.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, this docstring is wrongly phrased. Change it to:
Custom pylint checker which checks the order of arguments in function definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay will change it .

scripts/pylint_extensions.py Outdated Show resolved Hide resolved
msgs = {
'C0005': ('Wrong order of arguments '
'self should come first',
'wrong-ord-args-self',
Copy link
Contributor

Choose a reason for hiding this comment

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

The name should be same everywhere. Therefore, change this to function-args-order.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

name can't be same as there are two messages so for each message name should be different so that we can differentiate between them.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is the name of the checker. There is no checker of the name wrong-order-args-self. Did you try running this checker once?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's keep a common name and differentiate on the basis of the message.

Copy link
Contributor Author

@anubhavsinha98 anubhavsinha98 Dec 20, 2018

Choose a reason for hiding this comment

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

Actually wrong-ord-args-self is the message-id, which should be unique.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, it is unique for a particular checker. We can distinguish on the basis of the message in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually the message_symbol i.e message_id needs to be unique for every message. Otherwise it throws the InvalidMessageError: Message symbol 'function-args-order' is already defined

'self should come first',),
'C0006': ('Wrong order of arguments '
'cls should come first',
'wrong-ord-args-cls',
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto.

def visit_functiondef(self, node):
args_list = [args.name for args in node.args.args]
if 'self' in args_list and args_list[0] != 'self':
self.add_message('wrong-ord-args-self', node=node)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto.

if 'self' in args_list and args_list[0] != 'self':
self.add_message('wrong-ord-args-self', node=node)
elif 'cls' in args_list and args_list[0] != 'cls':
self.add_message('wrong-ord-args-cls', node=node)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto.

name = 'function-args-order'
priority = -1
msgs = {
'C0005': ('Wrong order of arguments '
Copy link
Contributor

Choose a reason for hiding this comment

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

Break after ( and change this to Wrong order of arguments in function definition. 'self' should come first.

'self should come first',
'wrong-ord-args-self',
'self should come first',),
'C0006': ('Wrong order of arguments '
Copy link
Contributor

Choose a reason for hiding this comment

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

Break after ( and change this to Wrong order of arguments in function definition. 'cls' should come first.

@anubhavsinha98
Copy link
Contributor Author

Tested the checker by making a test.py file !
screenshot from 2018-12-20 20-32-14

Copy link
Contributor

@apb7 apb7 left a comment

Choose a reason for hiding this comment

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

Just a couple of comments!

priority = -1
msgs = {
'C0005': (
'Wrong order of arguments in function definition '
Copy link
Contributor

Choose a reason for hiding this comment

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

Fullstop at the end of this line?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do 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.

Sir is that message_id thing ok?

'function-args-order-self',
'\'self\' should come first',),
'C0006': (
'Wrong order of arguments in function definition '
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay.

@anubhavsinha98
Copy link
Contributor Author

@apb7 Made the changes, PTAL !

Copy link
Contributor

@apb7 apb7 left a comment

Choose a reason for hiding this comment

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

@@ -757,6 +757,44 @@ def process_module(self, node):
'backslash-continuation', line=line_num + 1)


class FunctionArgsOrderChecker(checkers.BaseChecker):
"""Custom pylint checker which checks the order
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you not accommodate more characters in this line? I feel this has been cut-off too soon..

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, will correct it.

}

def visit_functiondef(self, node):
"""Visits every function definition in the
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto

Copy link
Contributor

Choose a reason for hiding this comment

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

(Also, for the following lines.)


class FunctionArgsOrderCheckerTest(unittest.TestCase):

def test_find_function_def(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

find --> finds

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will change that .

@@ -26,25 +26,27 @@
class ObjectNormalizationUnitTests(test_utils.GenericTestBase):
"""Tests normalization of typed objects."""

def check_normalization(self, cls, mappings, invalid_items):
def check_normalization(self, object_class, mappings, invalid_items):
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm..I am not sure about making changes here. Shouldn't we incorporate such cases where self and cls both are present as arguments, that self should come first and then cls?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually @seanlip suggested these changes, in the #5844(comment) . As there were only two cases present . Well we can add such case also where self and cls both are present and self should come first and then cls. What you suggest?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, then it's fine here. Thanks for the link to the comment!

@@ -26,25 +26,27 @@
class ObjectNormalizationUnitTests(test_utils.GenericTestBase):
"""Tests normalization of typed objects."""

def check_normalization(self, cls, mappings, invalid_items):
def check_normalization(self, object_class, mappings, invalid_items):
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, then it's fine here. Thanks for the link to the comment!



class FunctionArgsOrderCheckerTest(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.

Hi @vibhor98, do we need docstrings here too, that is, for this test files? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @apb7, yes we need to add docstrings to the methods in test files but only selected ones. Those ending with *Test (like this class name) or test_* don't need docstrings. We're handling this via regex.

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool, thanks a bunch!

Copy link
Contributor

@apb7 apb7 left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@apb7
Copy link
Contributor

apb7 commented Dec 21, 2018

@anubhavsinha98, can you please confirm that you're using the same email for GitHub as the one with which you've signed the CLA? There seems to be some mismatch in GitHub names for commits:
screenshot-github com-2018 12 21-23-28-45

Copy link
Contributor

@apb7 apb7 left a comment

Choose a reason for hiding this comment

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

Un-approving till this query is resolved. Thanks!

@anubhavsinha98
Copy link
Contributor Author

@apb7 , I am using same email in Github and the one through which I have signed the CLA .

@anubhavsinha98
Copy link
Contributor Author

anubhavsinha98 commented Dec 21, 2018

Actually that is my system name !

Copy link
Contributor

@apb7 apb7 left a comment

Choose a reason for hiding this comment

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

Checked with @anubhavsinha98: He has used the same email for signing the CLA as the one used by GitHub. Thanks!

@apb7 apb7 merged commit cd180b2 into oppia:develop Dec 22, 2018
@anubhavsinha98 anubhavsinha98 deleted the mybranch branch December 23, 2018 11:25
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.

Add to python linting to ensure that class arguments are the first element of the arglist
8 participants