1010import yaml
1111from stevedore import named
1212
13+ from code_annotations import annotation_errors
1314from code_annotations .exceptions import ConfigurationException
1415from code_annotations .helpers import VerboseEcho
1516
@@ -314,7 +315,11 @@ def __init__(self, config):
314315 """
315316 self .config = config
316317 self .echo = self .config .echo
318+ # errors contains formatted error messages
317319 self .errors = []
320+ # annotation_errors contains (annotation, AnnotationErrorType, args) tuples
321+ # This attribute may be parsed by 3rd-parties, such as edx-lint.
322+ self .annotation_errors = []
318323
319324 def format_file_results (self , all_results , results ):
320325 """
@@ -377,20 +382,18 @@ def _check_results_choices(self, annotation):
377382 if choice not in self .config .choices [token ]:
378383 self ._add_annotation_error (
379384 annotation ,
380- '"{}" is not a valid choice for "{}". Expected one of {}.' .format (
381- choice ,
382- token ,
383- self .config .choices [token ]
384- )
385+ annotation_errors .InvalidChoice ,
386+ (choice , token , self .config .choices [token ])
385387 )
386388 elif choice in found_valid_choices :
387- self ._add_annotation_error (annotation , f'" { choice } " is already present in this annotation.' )
389+ self ._add_annotation_error (annotation , annotation_errors . DuplicateChoiceValue , ( choice ,) )
388390 else :
389391 found_valid_choices .append (choice )
390392 else :
391393 self ._add_annotation_error (
392394 annotation ,
393- 'no value found for "{}". Expected one of {}.' .format (token , self .config .choices [token ])
395+ annotation_errors .MissingChoiceValue ,
396+ (token , self .config .choices [token ])
394397 )
395398 return None
396399
@@ -502,7 +505,8 @@ def check_group(self, annotations):
502505 if token not in group_tokens :
503506 self ._add_annotation_error (
504507 annotation ,
505- "'{}' token does not belong to group '{}'. Expected one of: {}" .format (
508+ annotation_errors .InvalidToken ,
509+ (
506510 token ,
507511 group_name ,
508512 group_tokens
@@ -513,7 +517,8 @@ def check_group(self, annotations):
513517 if token in found_tokens :
514518 self ._add_annotation_error (
515519 annotation ,
516- "found duplicate token '{}'" .format (token )
520+ annotation_errors .DuplicateToken ,
521+ (token ,)
517522 )
518523 if group_name :
519524 found_tokens .add (token )
@@ -524,69 +529,26 @@ def check_group(self, annotations):
524529 if token not in found_tokens :
525530 self ._add_annotation_error (
526531 annotations [0 ],
527- "missing non-optional annotation: '{}'" .format (token )
528- )
529-
530- def check_annotation (self , annotation , current_group ):
531- """
532- Check an annotation and add annotation errors when necessary.
533-
534- Args:
535- annotation (dict): in particular, every annotation contains 'annotation_token' and 'annotation_data' keys.
536- current_group (str): None or the name of a group (from self.config.groups) to which preceding annotations
537- belong.
538- found_group_tokens (list): annotation tokens from the same group that were already found. This list is
539- cleared in case of error or when creating a new group.
540-
541- Return:
542- current_group (str or None)
543- """
544- self ._check_results_choices (annotation )
545- token = annotation ['annotation_token' ]
546-
547- if current_group :
548- # Add to existing group
549- if token not in self .config .groups [current_group ]:
550- # Check for token correctness
551- self ._add_annotation_error (
552- annotation ,
553- '"{}" is not in the group that starts with "{}". Expecting one of: {}' .format (
554- token ,
555- current_group ,
556- self .config .groups [current_group ]
532+ annotation_errors .MissingToken ,
533+ (token ,)
557534 )
558- )
559- current_group = None
560- else :
561- # Token is correct
562- self .echo .echo_vv ('Adding "{}", line {} to group {}' .format (
563- token ,
564- annotation ['line_number' ],
565- current_group
566- ))
567- else :
568- current_group = self ._get_group_for_token (token )
569- if current_group :
570- # Start a new group
571- self .echo .echo_vv ('Starting new group for "{}" token "{}", line {}' .format (
572- current_group , token , annotation ['line_number' ])
573- )
574-
575- return current_group
576535
577- def _add_annotation_error (self , annotation , message ):
536+ def _add_annotation_error (self , annotation , error_type , args = None ):
578537 """
579538 Add an error message to self.errors, formatted nicely.
580539
581540 Args:
582541 annotation: A single annotation dict found in search()
583- message: Custom error message to be added
584- """
585- if 'extra' in annotation and 'object_id' in annotation ['extra' ]:
586- error = "{}::{}: {}" .format (annotation ['filename' ], annotation ['extra' ]['object_id' ], message )
587- else :
588- error = "{}::{}: {}" .format (annotation ['filename' ], annotation ['line_number' ], message )
589- self .errors .append (error )
542+ error_type (annotation_errors.AnnotationErrorType): error type from which the error message will be
543+ generated.
544+ args (tuple): arguments for error message formatting.
545+ """
546+ args = args or tuple ()
547+ error_message = error_type .message % args
548+ location = annotation .get ("extra" , {}).get ("object_id" , annotation ["line_number" ])
549+ message = "{}::{}: {}" .format (annotation ['filename' ], location , error_message )
550+ self .annotation_errors .append ((annotation , error_type , args ))
551+ self ._add_error (message )
590552
591553 def _add_error (self , message ):
592554 """
0 commit comments