1+ """Linter module for evaluating and cleaning Python code using pylint."""
2+
13import re
2- import os
4+ import os # noqa: F401
35import subprocess
46
57
68class Lint :
9+ """Class for evaluating and cleaning Python code using pylint."""
10+
711 def clean_pylint_output (self , result , warnings = False ):
12+ """
13+ Clean the output from pylint.
14+
15+ By removing unwanted messages and formatting errors.
16+
17+ Args:
18+ result (str): The output string from pylint.
19+ warnings (bool): Whether to include warnings in the output.
20+
21+ Returns:
22+ str: The cleaned and formatted output.
23+ """
824
925 # result = result.replace(os.path.basename(code_file_name), 'user_code')
1026 # Define the patterns to remove
@@ -14,13 +30,15 @@ def clean_pylint_output(self, result, warnings=False):
1430 r":[0-9]+:[0-9]+: R[0-9]{4}:.*" , # Refactor messages
1531 r":[0-9]+:[0-9]+: error.*EOF.*" , # Unexpected EOF error
1632 r":[0-9]+:[0-9]+: E1101:.*Module 'ompl.*" , # ompl E1101 error
17- r":[0-9]+:[0-9]+:.*value.*argument.*unbound.*method.*" , # No value for argument 'self' error
33+ (
34+ r":[0-9]+:[0-9]+:.*value.*argument.*unbound.*method.*"
35+ ), # No value for argument 'self' error
1836 r":[0-9]+:[0-9]+: E1111:.*" , # Assignment from no return error
1937 r":[0-9]+:[0-9]+: E1136:.*" , # E1136 until issue is resolved
2038 ]
2139
2240 if not warnings :
23- # Remove convention, refactor, and warning messages if warnings are not desired
41+ # Remove convention, refactor, and warning msgs if warnings are not desired
2442 for pattern in patterns [:3 ]:
2543 result = re .sub (r"^[^:]*" + pattern , "" , result , flags = re .MULTILINE )
2644
@@ -41,6 +59,15 @@ def clean_pylint_output(self, result, warnings=False):
4159 return result
4260
4361 def append_rating_if_missing (self , result ):
62+ """
63+ Append a default rating message to the result if it is missing.
64+
65+ Args:
66+ result (str): The output string from pylint.
67+
68+ Returns:
69+ str: The result string with the rating message appended if necessary.
70+ """
4471 rating_message = (
4572 "-----------------------------------\n Your code has been rated at 0.00/10"
4673 )
@@ -56,13 +83,28 @@ def append_rating_if_missing(self, result):
5683 def evaluate_code (
5784 self , code , ros_version , warnings = False , py_lint_source = "pylint_checker.py"
5885 ):
86+ """
87+ Evaluate the provided Python code using pylint and return the cleaned output.
88+
89+ Args:
90+ code (str): The Python code to evaluate.
91+ ros_version (str): The ROS version to determine environment settings.
92+ warnings (bool, optional): Whether to include warnings in the output.
93+ Defaults to False.
94+ py_lint_source (str, optional): The pylint checker source file.
95+ Defaults to "pylint_checker.py".
96+
97+ Returns:
98+ str: The cleaned and formatted pylint output.
99+ """
59100 try :
60101 code = re .sub (r"from HAL import HAL" , "from hal import HAL" , code )
61102 code = re .sub (r"from GUI import GUI" , "from gui import GUI" , code )
62103 code = re .sub (r"from MAP import MAP" , "from map import MAP" , code )
63104 code = re .sub (r"\nimport cv2\n" , "\n from cv2 import cv2\n " , code )
64105
65- # Avoids EOF error when iterative code is empty (which prevents other errors from showing)
106+ # Avoids EOF error when iterative code is empty
107+ # (which prevents other errors from showing)
66108 while_position = re .search (
67109 r"[^ ]while\s*\(\s*True\s*\)\s*:|[^ ]while\s*True\s*:|[^ ]while\s*1\s*:|[^ ]while\s*\(\s*1\s*\)\s*:" ,
68110 code ,
@@ -87,9 +129,17 @@ def evaluate_code(
87129
88130 command = ""
89131 if "humble" in str (ros_version ):
90- command = f"export PYTHONPATH=$PYTHONPATH:/workspace/code; python3 /RoboticsApplicationManager/manager/manager/lint/{ py_lint_source } "
132+ command = (
133+ f"export PYTHONPATH=$PYTHONPATH:/workspace/code; "
134+ f"python3 /RoboticsApplicationManager/manager/manager/lint/"
135+ f"{ py_lint_source } "
136+ )
91137 else :
92- command = f"export PYTHONPATH=$PYTHONPATH:/workspace/code; python3 /RoboticsApplicationManager/manager/manager/lint/{ py_lint_source } "
138+ command = (
139+ f"export PYTHONPATH=$PYTHONPATH:/workspace/code; "
140+ f"python3 /RoboticsApplicationManager/manager/manager/lint/"
141+ f"{ py_lint_source } "
142+ )
93143
94144 ret = subprocess .run (command , capture_output = True , text = True , shell = True )
95145
0 commit comments