From 67b7523a7b1f4a313ae1607a9c15a6f7c785a15f Mon Sep 17 00:00:00 2001 From: David Liu Date: Fri, 22 Sep 2023 16:14:07 -0400 Subject: [PATCH 01/13] Release v2.6.2! (#957) --- CHANGELOG.md | 2 ++ python_ta/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2e123dee..61177e0e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased +## [2.6.2] - 2023-09-22 + ### Bug fixes - Fix `naming-convention-violation` bug where `_` was considered an invalid variable name. diff --git a/python_ta/__init__.py b/python_ta/__init__.py index 3a907d928..37cbeae58 100644 --- a/python_ta/__init__.py +++ b/python_ta/__init__.py @@ -14,7 +14,7 @@ import python_ta python_ta.check_all() """ -__version__ = "2.6.2.dev" # Version number +__version__ = "2.6.3.dev" # Version number # First, remove underscore from builtins if it has been bound in the REPL. import builtins From 516d40fd1b78d9de1824c22718ebe5f4457cabe3 Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Thu, 12 Oct 2023 20:58:58 -0400 Subject: [PATCH 02/13] changes so far --- docs/usage/configuration.md | 11 ++++++++++ python_ta/__init__.py | 41 +++++++++++++++++++++++-------------- python_ta/config/.pylintrc | 3 +++ 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/docs/usage/configuration.md b/docs/usage/configuration.md index 3ccc23cb5..b3568516a 100644 --- a/docs/usage/configuration.md +++ b/docs/usage/configuration.md @@ -52,6 +52,17 @@ import python_ta python_ta.check_all(..., load_default_config=False) ``` +## Allowing 'pylint:' Comments + +PythonTA allows you to choose whether you want to locally disable checks using 'pylint:' or not, i.e. it +lets you choose whether or not you want to allow comments that begin with 'pylint:'. + +```python +import python_ta + +python_ta.check_all(..., config = {"allow-pylint-comments" : True}) +``` + ## Custom Error Messages PythonTA allows for pylint error messages to be overridden with more user friendly messages. diff --git a/python_ta/__init__.py b/python_ta/__init__.py index 37cbeae58..0ee20ee98 100644 --- a/python_ta/__init__.py +++ b/python_ta/__init__.py @@ -136,7 +136,7 @@ def _check( errs = [] # Errors caught in files for data submission config = {} # Configuration settings for data submission for file_py in get_file_paths(locations): - if not _verify_pre_check(file_py): + if not _verify_pre_check(file_py, local_config, load_default_config): continue # Check the other files # Load config file in user location. Construct new linter each # time, so config options don't bleed to unintended files. @@ -363,6 +363,13 @@ def reset_linter( "help": "Path to patch config toml file.", }, ), + "allow-pylint-comments", + { + "default": False, + "type": "yn", + "metavar": "", + "help": "allows or disallows pylint: comments", + }, ) parent_dir_path = os.path.dirname(__file__) @@ -423,24 +430,28 @@ def get_file_paths(rel_path: AnyStr) -> Generator[AnyStr, None, None]: yield os.path.join(root, filename) # Format path, from root. -def _verify_pre_check(filepath: AnyStr) -> bool: +def _verify_pre_check( + filepath: AnyStr, local_config: Union[dict, str] = "", load_default_config: bool = True +) -> bool: """Check student code for certain issues.""" # Make sure the program doesn't crash for students. # Could use some improvement for better logging and error reporting. try: - # Check for inline "pylint:" comment, which may indicate a student - # trying to disable a check. - with tokenize.open(os.path.expanduser(filepath)) as f: - for tok_type, content, _, _, _ in tokenize.generate_tokens(f.readline): - if tok_type != tokenize.COMMENT: - continue - match = OPTION_PO.search(content) - if match is not None: - print( - '[ERROR] String "pylint:" found in comment. ' - + "No check run on file `{}.`\n".format(filepath) - ) - return False + linter = reset_linter(config=local_config, load_default_config=load_default_config) + if not linter.config.allow_pylint_comments: + # Check for inline "pylint:" comment, which may indicate a student + # trying to disable a check. + with tokenize.open(os.path.expanduser(filepath)) as f: + for tok_type, content, _, _, _ in tokenize.generate_tokens(f.readline): + if tok_type != tokenize.COMMENT: + continue + match = OPTION_PO.search(content) + if match is not None: + print( + '[ERROR] String "pylint:" found in comment. ' + + "No check run on file `{}.`\n".format(filepath) + ) + return False except IndentationError as e: print( "[ERROR] python_ta could not check your code due to an " diff --git a/python_ta/config/.pylintrc b/python_ta/config/.pylintrc index 1750bbf74..a48d2b327 100644 --- a/python_ta/config/.pylintrc +++ b/python_ta/config/.pylintrc @@ -23,6 +23,9 @@ pyta-server-address = http://127.0.0.1:5000 # Path to messages_config toml file # messages-config-path = messages.toml +# Allowing pylint: comments +allow-pylint-comments = no + [REPORTS] # The type of reporter to use to display results. Available PyTA classes are # PlainReporter, ColorReporter, HTMLReporter, JSONReporter. From 16cac582e230e879e70dc2841a9acbdc70eb4a1e Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Fri, 13 Oct 2023 15:20:00 -0400 Subject: [PATCH 03/13] Trying something --- python_ta/__init__.py | 34 +++++++++++++++------------------- python_ta/testcase.py | 0 2 files changed, 15 insertions(+), 19 deletions(-) create mode 100644 python_ta/testcase.py diff --git a/python_ta/__init__.py b/python_ta/__init__.py index 0ee20ee98..09b9e552b 100644 --- a/python_ta/__init__.py +++ b/python_ta/__init__.py @@ -136,7 +136,7 @@ def _check( errs = [] # Errors caught in files for data submission config = {} # Configuration settings for data submission for file_py in get_file_paths(locations): - if not _verify_pre_check(file_py, local_config, load_default_config): + if not _verify_pre_check(file_py): continue # Check the other files # Load config file in user location. Construct new linter each # time, so config options don't bleed to unintended files. @@ -430,28 +430,24 @@ def get_file_paths(rel_path: AnyStr) -> Generator[AnyStr, None, None]: yield os.path.join(root, filename) # Format path, from root. -def _verify_pre_check( - filepath: AnyStr, local_config: Union[dict, str] = "", load_default_config: bool = True -) -> bool: +def _verify_pre_check(filepath: AnyStr) -> bool: """Check student code for certain issues.""" # Make sure the program doesn't crash for students. # Could use some improvement for better logging and error reporting. try: - linter = reset_linter(config=local_config, load_default_config=load_default_config) - if not linter.config.allow_pylint_comments: - # Check for inline "pylint:" comment, which may indicate a student - # trying to disable a check. - with tokenize.open(os.path.expanduser(filepath)) as f: - for tok_type, content, _, _, _ in tokenize.generate_tokens(f.readline): - if tok_type != tokenize.COMMENT: - continue - match = OPTION_PO.search(content) - if match is not None: - print( - '[ERROR] String "pylint:" found in comment. ' - + "No check run on file `{}.`\n".format(filepath) - ) - return False + # Check for inline "pylint:" comment, which may indicate a student + # trying to disable a check. + with tokenize.open(os.path.expanduser(filepath)) as f: + for tok_type, content, _, _, _ in tokenize.generate_tokens(f.readline): + if tok_type != tokenize.COMMENT: + continue + match = OPTION_PO.search(content) + if match is not None: + print( + '[ERROR] String "pylint:" found in comment. ' + + "No check run on file `{}.`\n".format(filepath) + ) + return False except IndentationError as e: print( "[ERROR] python_ta could not check your code due to an " diff --git a/python_ta/testcase.py b/python_ta/testcase.py new file mode 100644 index 000000000..e69de29bb From a6d76e47081239761b1bad4ebd6b24ad8113ffba Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Fri, 13 Oct 2023 15:49:39 -0400 Subject: [PATCH 04/13] Middle --- python_ta/__init__.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/python_ta/__init__.py b/python_ta/__init__.py index 09b9e552b..c2b99fd10 100644 --- a/python_ta/__init__.py +++ b/python_ta/__init__.py @@ -136,7 +136,7 @@ def _check( errs = [] # Errors caught in files for data submission config = {} # Configuration settings for data submission for file_py in get_file_paths(locations): - if not _verify_pre_check(file_py): + if not _verify_pre_check(file_py, linter): continue # Check the other files # Load config file in user location. Construct new linter each # time, so config options don't bleed to unintended files. @@ -430,24 +430,25 @@ def get_file_paths(rel_path: AnyStr) -> Generator[AnyStr, None, None]: yield os.path.join(root, filename) # Format path, from root. -def _verify_pre_check(filepath: AnyStr) -> bool: +def _verify_pre_check(filepath: AnyStr, linter: PyLinter) -> bool: """Check student code for certain issues.""" # Make sure the program doesn't crash for students. # Could use some improvement for better logging and error reporting. try: - # Check for inline "pylint:" comment, which may indicate a student - # trying to disable a check. - with tokenize.open(os.path.expanduser(filepath)) as f: - for tok_type, content, _, _, _ in tokenize.generate_tokens(f.readline): - if tok_type != tokenize.COMMENT: - continue - match = OPTION_PO.search(content) - if match is not None: - print( - '[ERROR] String "pylint:" found in comment. ' - + "No check run on file `{}.`\n".format(filepath) - ) - return False + if not linter.config.allow_pylint_comments: + # Check for inline "pylint:" comment, which may indicate a student + # trying to disable a check. + with tokenize.open(os.path.expanduser(filepath)) as f: + for tok_type, content, _, _, _ in tokenize.generate_tokens(f.readline): + if tok_type != tokenize.COMMENT: + continue + match = OPTION_PO.search(content) + if match is not None: + print( + '[ERROR] String "pylint:" found in comment. ' + + "No check run on file `{}.`\n".format(filepath) + ) + return False except IndentationError as e: print( "[ERROR] python_ta could not check your code due to an " From 59678fee222d575038cf6bb3b88641b8a112965c Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Fri, 13 Oct 2023 16:11:12 -0400 Subject: [PATCH 05/13] Please work --- python_ta/__init__.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/python_ta/__init__.py b/python_ta/__init__.py index 34962eaa2..3c5f9c585 100644 --- a/python_ta/__init__.py +++ b/python_ta/__init__.py @@ -286,13 +286,15 @@ def reset_linter( "help": "Path to patch config toml file.", }, ), - "allow-pylint-comments", - { - "default": False, - "type": "yn", - "metavar": "", - "help": "allows or disallows pylint: comments", - }, + ( + "allow-pylint-comments", + { + "default": False, + "type": "yn", + "metavar": "", + "help": "allows or disallows pylint: comments", + }, + ), ) parent_dir_path = os.path.dirname(__file__) From cdc79645f1b2c4d00a70505613c92443839efbd7 Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Fri, 13 Oct 2023 16:27:50 -0400 Subject: [PATCH 06/13] Testcase --- python_ta/testcase.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/python_ta/testcase.py b/python_ta/testcase.py index e69de29bb..24a0479ef 100644 --- a/python_ta/testcase.py +++ b/python_ta/testcase.py @@ -0,0 +1,14 @@ +def some_function(): + x = 5 # pylint: + y = 0 + result = x / y + return result + + +a = 10 +b = 20 +if __name__ == "__main__": + import python_ta + + options = {"allow-pylint-comments": False} + python_ta.check_all() From 3ba60913708b92c4bb6f9329f47f694ef20f58da Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Wed, 18 Oct 2023 14:25:49 -0400 Subject: [PATCH 07/13] testcase draft --- python_ta/testcase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python_ta/testcase.py b/python_ta/testcase.py index 24a0479ef..06cdc560a 100644 --- a/python_ta/testcase.py +++ b/python_ta/testcase.py @@ -1,5 +1,5 @@ def some_function(): - x = 5 # pylint: + x = 5 # pylint: disable something y = 0 result = x / y return result @@ -11,4 +11,4 @@ def some_function(): import python_ta options = {"allow-pylint-comments": False} - python_ta.check_all() + python_ta.check_all(config=options) From 7b7093406a6a3ccb4dc1000180ac12649253ae4a Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Wed, 18 Oct 2023 15:27:08 -0400 Subject: [PATCH 08/13] tests --- ....py => allow_pylint_comments_false_testcase.py} | 0 python_ta/allow_pylint_comments_true_testcase.py | 14 ++++++++++++++ 2 files changed, 14 insertions(+) rename python_ta/{testcase.py => allow_pylint_comments_false_testcase.py} (100%) create mode 100644 python_ta/allow_pylint_comments_true_testcase.py diff --git a/python_ta/testcase.py b/python_ta/allow_pylint_comments_false_testcase.py similarity index 100% rename from python_ta/testcase.py rename to python_ta/allow_pylint_comments_false_testcase.py diff --git a/python_ta/allow_pylint_comments_true_testcase.py b/python_ta/allow_pylint_comments_true_testcase.py new file mode 100644 index 000000000..4a2f6a6b2 --- /dev/null +++ b/python_ta/allow_pylint_comments_true_testcase.py @@ -0,0 +1,14 @@ +def some_function(): + x = 5 # pylint: disable something + y = 0 + result = x / y + return result + + +a = 10 +b = 20 +if __name__ == "__main__": + import python_ta + + options = {"allow-pylint-comments": True} + python_ta.check_all(config=options) From 865ee7a235c91e663ef76389cb8d9caaf97ecd5e Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Thu, 19 Oct 2023 12:06:02 -0400 Subject: [PATCH 09/13] Modification to docs --- docs/usage/configuration.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/usage/configuration.md b/docs/usage/configuration.md index 8f9713340..de4292ae4 100644 --- a/docs/usage/configuration.md +++ b/docs/usage/configuration.md @@ -55,8 +55,7 @@ python_ta.check_all(..., load_default_config=False) ## Allowing 'pylint:' Comments PythonTA allows you to choose whether you want to locally disable checks by using 'pylint:' in a comment, i.e. it -lets you choose whether or not you want to allow comments that begin with 'pylint:'. The default value for this option -is False, i.e. PythonTA by default would not allow you to use 'pylint:' in a comment. +lets you choose whether or not you want to allow comments that begin with 'pylint:'. The default value for this option is False, i.e. PythonTA by default would not allow you to use 'pylint:' in a comment. ```python import python_ta From 872a2b6ca2e56bafc6685c2d747ecb974cb8f322 Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Fri, 3 Nov 2023 12:06:29 -0400 Subject: [PATCH 10/13] Revised based on review (except test cases) --- CHANGELOG.md | 1 + docs/usage/configuration.md | 2 +- python_ta/__init__.py | 12 +++++++----- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b62da4dd2..eda56579d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Added new configuration option `use-pyta-error-messages` to let users choose whether PythonTA should overwrite pylint's error messages. - Both PlainReporter and ColorReporter emphasize specific code chunks by using overline characters under any part that is highlighted as ERROR. +- Added new configuration option `allow-pylint-comments` to let users choose whether PythonTA should allow comments beginning with pylint: or not. ## [2.6.3] - 2023-10-09 diff --git a/docs/usage/configuration.md b/docs/usage/configuration.md index de4292ae4..79e6af169 100644 --- a/docs/usage/configuration.md +++ b/docs/usage/configuration.md @@ -60,7 +60,7 @@ lets you choose whether or not you want to allow comments that begin with 'pylin ```python import python_ta -python_ta.check_all(..., config = {"allow-pylint-comments" : True}) +python_ta.check_all(..., config={"allow-pylint-comments": True}) ``` ## Custom Error Messages diff --git a/python_ta/__init__.py b/python_ta/__init__.py index 7049e48b7..bad65dbb3 100644 --- a/python_ta/__init__.py +++ b/python_ta/__init__.py @@ -368,15 +368,17 @@ def get_file_paths(rel_path: AnyStr) -> Generator[AnyStr, None, None]: yield os.path.join(root, filename) # Format path, from root. -def _verify_pre_check(filepath: AnyStr, allowed_pylint: bool) -> bool: - """Check student code for certain issues.""" +def _verify_pre_check(filepath: AnyStr, allow_pylint_comments: bool) -> bool: + """Check student code for certain issues. + The additional allow_pylint_comments parameter indicates whether we want the user to be able to add comments + beginning with pylint which can be used to locally disable checks.""" # Make sure the program doesn't crash for students. # Could use some improvement for better logging and error reporting. try: - if allowed_pylint: + # Check for inline "pylint:" comment, which may indicate a student + # trying to disable a check. + if allow_pylint_comments: return True - # Check for inline "pylint:" comment, which may indicate a student - # trying to disable a check. with tokenize.open(os.path.expanduser(filepath)) as f: for tok_type, content, _, _, _ in tokenize.generate_tokens(f.readline): if tok_type != tokenize.COMMENT: From 955f467f94d73823ac941ecef3335e567972379b Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Thu, 16 Nov 2023 12:00:19 -0500 Subject: [PATCH 11/13] added tests --- tests/test_config/test_config.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/test_config/test_config.py b/tests/test_config/test_config.py index 178a72dea..7fefe95f2 100644 --- a/tests/test_config/test_config.py +++ b/tests/test_config/test_config.py @@ -3,6 +3,7 @@ """ import json import os +from unittest.mock import mock_open, patch import pytest @@ -226,3 +227,23 @@ def test_config_parse_error_has_no_snippet() -> None: snippet = reporter.messages[config][0].snippet assert snippet == "" + + +def test_allow_pylint_comments() -> None: + """Test that checks whether the allow-pylint-comments configuration option works as expected when it is + set to True""" + + with patch("python_ta.tokenize.open", mock_open(read_data="# pylint: disable")): + result = python_ta._verify_pre_check("", allow_pylint_comments=True) + + assert result is True + + +def test_disallows_pylint_comments() -> None: + """Test that checks whether the allow-pylint-comments configuration option works as expected when it is + is set to False""" + + with patch("python_ta.tokenize.open", mock_open(read_data="# pylint: disable")): + result = python_ta._verify_pre_check("", allow_pylint_comments=False) + + assert result is False From 6d8e235e2db0225823a6a4bd7a5353fbbe02ce17 Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Sat, 18 Nov 2023 14:20:11 -0500 Subject: [PATCH 12/13] final changes --- python_ta/__init__.py | 3 ++- tests/test_config/test_config.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/python_ta/__init__.py b/python_ta/__init__.py index 7bc73fbef..8b0355c1e 100644 --- a/python_ta/__init__.py +++ b/python_ta/__init__.py @@ -371,7 +371,8 @@ def get_file_paths(rel_path: AnyStr) -> Generator[AnyStr, None, None]: def _verify_pre_check(filepath: AnyStr, allow_pylint_comments: bool) -> bool: """Check student code for certain issues. The additional allow_pylint_comments parameter indicates whether we want the user to be able to add comments - beginning with pylint which can be used to locally disable checks.""" + beginning with pylint which can be used to locally disable checks. + """ # Make sure the program doesn't crash for students. # Could use some improvement for better logging and error reporting. try: diff --git a/tests/test_config/test_config.py b/tests/test_config/test_config.py index 7fefe95f2..13ce9f202 100644 --- a/tests/test_config/test_config.py +++ b/tests/test_config/test_config.py @@ -231,7 +231,8 @@ def test_config_parse_error_has_no_snippet() -> None: def test_allow_pylint_comments() -> None: """Test that checks whether the allow-pylint-comments configuration option works as expected when it is - set to True""" + set to True + """ with patch("python_ta.tokenize.open", mock_open(read_data="# pylint: disable")): result = python_ta._verify_pre_check("", allow_pylint_comments=True) @@ -241,7 +242,8 @@ def test_allow_pylint_comments() -> None: def test_disallows_pylint_comments() -> None: """Test that checks whether the allow-pylint-comments configuration option works as expected when it is - is set to False""" + is set to False + """ with patch("python_ta.tokenize.open", mock_open(read_data="# pylint: disable")): result = python_ta._verify_pre_check("", allow_pylint_comments=False) From fbc8f1bb5673ec142318b44dd7428fcc839b257f Mon Sep 17 00:00:00 2001 From: Aina Merchant Date: Sat, 18 Nov 2023 14:21:24 -0500 Subject: [PATCH 13/13] deleted files --- python_ta/allow_pylint_comments_false_testcase.py | 14 -------------- python_ta/allow_pylint_comments_true_testcase.py | 14 -------------- 2 files changed, 28 deletions(-) delete mode 100644 python_ta/allow_pylint_comments_false_testcase.py delete mode 100644 python_ta/allow_pylint_comments_true_testcase.py diff --git a/python_ta/allow_pylint_comments_false_testcase.py b/python_ta/allow_pylint_comments_false_testcase.py deleted file mode 100644 index 06cdc560a..000000000 --- a/python_ta/allow_pylint_comments_false_testcase.py +++ /dev/null @@ -1,14 +0,0 @@ -def some_function(): - x = 5 # pylint: disable something - y = 0 - result = x / y - return result - - -a = 10 -b = 20 -if __name__ == "__main__": - import python_ta - - options = {"allow-pylint-comments": False} - python_ta.check_all(config=options) diff --git a/python_ta/allow_pylint_comments_true_testcase.py b/python_ta/allow_pylint_comments_true_testcase.py deleted file mode 100644 index 4a2f6a6b2..000000000 --- a/python_ta/allow_pylint_comments_true_testcase.py +++ /dev/null @@ -1,14 +0,0 @@ -def some_function(): - x = 5 # pylint: disable something - y = 0 - result = x / y - return result - - -a = 10 -b = 20 -if __name__ == "__main__": - import python_ta - - options = {"allow-pylint-comments": True} - python_ta.check_all(config=options)