-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor annotation checking to expose errors to pylint
Instead of just storing the error messages as part of `check_results()`, we also store the type of error. This allows us to expose these errors to pylint in edx-lint, with the help of a new checker. (to be created)
- Loading branch information
Showing
5 changed files
with
142 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,4 @@ | |
Extensible tools for parsing annotations in codebases. | ||
""" | ||
|
||
__version__ = '1.0.2' | ||
__version__ = '1.1.0' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
""" | ||
List possible annotation error types. | ||
""" | ||
from collections import namedtuple | ||
|
||
AnnotationErrorType = namedtuple( | ||
"AnnotationError", ["message", "symbol", "description"] | ||
) | ||
|
||
# The TYPES list should contain all AnnotationErrorType instances. This list can then be parsed by others, for instance | ||
# to expose errors to pylint. | ||
TYPES = [] | ||
|
||
|
||
def add_error_type(message, symbol, description): | ||
""" | ||
Create an AnnotationErrorType instance and add it to TYPES. | ||
""" | ||
error_type = AnnotationErrorType( | ||
message, | ||
symbol, | ||
description, | ||
) | ||
TYPES.append(error_type) | ||
if len(TYPES) > 10: | ||
# if more than 10 items are created here, numerical IDs generated by edx-lint will overlap with other warning | ||
# IDs. | ||
raise ValueError("TYPES may not contain more than 10 items") | ||
return error_type | ||
|
||
|
||
# It is important to preserve the insertion order of these error types in the TYPES list, as edx-lint uses the error | ||
# type indices to generate numerical pylint IDs. If the insertion order is changed, the pylint IDs will change too, | ||
# which might cause incompatibilities down the road. Thus, new items should be added at the end. | ||
InvalidChoice = add_error_type( | ||
'"%s" is not a valid choice for "%s". Expected one of %s.', | ||
"annotation-invalid-choice", | ||
"Emitted when the value of a choice field is not one of the valid choices", | ||
) | ||
DuplicateChoiceValue = add_error_type( | ||
'"%s" is already present in this annotation.', | ||
"annotation-duplicate-choice-value", | ||
"Emitted when duplicate values are found in a choice field", | ||
) | ||
MissingChoiceValue = add_error_type( | ||
'no value found for "%s". Expected one of %s.', | ||
"annotation-missing-choice-value", | ||
"Emitted when a choice field does not have any value", | ||
) | ||
InvalidToken = add_error_type( | ||
"'%s' token does not belong to group '%s'. Expected one of: %s", | ||
"annotation-invalid-token", | ||
"Emitted when a token is found in a group for which it is not valid", | ||
) | ||
DuplicateToken = add_error_type( | ||
"found duplicate token '%s'", | ||
"annotation-duplicate-token", | ||
"Emitted when a token is found twice in a group", | ||
) | ||
MissingToken = add_error_type( | ||
"missing non-optional annotation: '%s'", | ||
"annotation-missing-token", | ||
"Emitted when a required token is missing from a group", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
""" | ||
Tests for the StaticSearch/DjangoSearch API. | ||
""" | ||
|
||
from code_annotations import annotation_errors | ||
from code_annotations.base import AnnotationConfig | ||
from code_annotations.find_static import StaticSearch | ||
|
||
|
||
def test_annotation_errors(): | ||
config = AnnotationConfig( | ||
"tests/test_configurations/.annotations_test", | ||
verbosity=-1, | ||
source_path_override="tests/extensions/python_test_files/choice_failures_1.pyt", | ||
) | ||
search = StaticSearch(config) | ||
results = search.search() | ||
search.check_results(results) | ||
|
||
# The first error should be an invalid choice error | ||
annotation, error_type, args = search.annotation_errors[0] | ||
assert { | ||
"annotation_data": ["doesnotexist"], | ||
"annotation_token": ".. ignored:", | ||
"filename": "choice_failures_1.pyt", | ||
"found_by": "python", | ||
"line_number": 1, | ||
} == annotation | ||
assert annotation_errors.InvalidChoice == error_type | ||
assert ( | ||
"doesnotexist", | ||
".. ignored:", | ||
["irrelevant", "terrible", "silly-silly"], | ||
) == args | ||
|
||
|
||
def test_annotation_errors_ordering(): | ||
# You should modify the value below every time a new annotation error type is added. | ||
assert 6 == len(annotation_errors.TYPES) | ||
# The value below must not be modified, ever. The number of annotation error types should NEVER exceed 10. Read the | ||
# module docs for more information. | ||
assert len(annotation_errors.TYPES) < 10 | ||
# This is just to check that the ordering of the annotation error types does not change. You should not change this | ||
# test, but eventually add your own below. | ||
assert annotation_errors.MissingToken == annotation_errors.TYPES[5] |