diff --git a/CHANGELOG.md b/CHANGELOG.md index 3437bc298..94dbaa464 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. - `AccumulationTable` can now track variables initialized within the `for` loop. Prior, only variables initialized before the `for` loop could be tracked. ## [2.6.4] - 2024-11-10 diff --git a/docs/usage/configuration.md b/docs/usage/configuration.md index 655da8e30..79e6af169 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 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. + +```python +import python_ta + +python_ta.check_all(..., config={"allow-pylint-comments": True}) +``` + ## Custom Error Messages By default, PythonTA overwrites some of pylint's error messages with its own to make them more beginner-friendly. diff --git a/python_ta/__init__.py b/python_ta/__init__.py index 2fd8e7d1e..8b0355c1e 100644 --- a/python_ta/__init__.py +++ b/python_ta/__init__.py @@ -140,7 +140,8 @@ 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): + allowed_pylint = linter.config.allow_pylint_comments + if not _verify_pre_check(file_py, allowed_pylint): 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. @@ -289,6 +290,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", + }, + ), ( "use-pyta-error-messages", { @@ -358,13 +368,18 @@ 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: - """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: # Check for inline "pylint:" comment, which may indicate a student # trying to disable a check. + if allow_pylint_comments: + return True with tokenize.open(os.path.expanduser(filepath)) as f: for tok_type, content, _, _, _ in tokenize.generate_tokens(f.readline): if tok_type != tokenize.COMMENT: diff --git a/python_ta/config/.pylintrc b/python_ta/config/.pylintrc index 991b1c135..ed3e813e0 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 + # Set whether the default error messages by pylint should be overwritten by PythonTA's custom messages use-pyta-error-messages = yes diff --git a/tests/test_config/test_config.py b/tests/test_config/test_config.py index 178a72dea..13ce9f202 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,25 @@ 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