1717from sinol_make .interfaces .BaseCommand import BaseCommand
1818from sinol_make .interfaces .Errors import CompilationError , CheckerOutputException , UnknownContestType
1919from sinol_make .helpers import compile , compiler , package_util , printer , paths , cache
20- from sinol_make .structs .status_structs import Status , ResultChange , PointsChange , ValidationResult , ExecutionResult
20+ from sinol_make .structs .status_structs import Status , ResultChange , PointsChange , ValidationResult , ExecutionResult , \
21+ TotalPointsChange
2122import sinol_make .util as util
2223import yaml , os , collections , sys , re , math , dictdiffer
2324import multiprocessing as mp
@@ -827,6 +828,7 @@ def validate_expected_scores(self, results):
827828 added_groups = set ()
828829 removed_groups = set ()
829830 changes = []
831+ unknown_change = False
830832
831833 for type , field , change in list (expected_scores_diff ):
832834 if type == "add" :
@@ -877,6 +879,16 @@ def validate_expected_scores(self, results):
877879 old_result = change [0 ],
878880 result = change [1 ]
879881 ))
882+ elif field [1 ] == "points" : # Points for at least one solution has changed
883+ solution = field [0 ]
884+ changes .append (TotalPointsChange (
885+ solution = solution ,
886+ old_points = change [0 ],
887+ new_points = change [1 ]
888+ ))
889+ else :
890+ unknown_change = True
891+
880892
881893 return ValidationResult (
882894 added_solutions ,
@@ -885,14 +897,19 @@ def validate_expected_scores(self, results):
885897 removed_groups ,
886898 changes ,
887899 expected_scores ,
888- new_expected_scores
900+ new_expected_scores ,
901+ unknown_change ,
889902 )
890903
891904
892905 def print_expected_scores_diff (self , validation_results : ValidationResult ):
893906 diff = validation_results
894907 config_expected_scores = self .config .get ("sinol_expected_scores" , {})
895908
909+ if diff .unknown_change :
910+ print (util .error ("There was an unknown change in expected scores. "
911+ "You should apply the suggested changes to avoid errors." ))
912+
896913 def warn_if_not_empty (set , message ):
897914 if len (set ) > 0 :
898915 print (util .warning (message + ": " ), end = '' )
@@ -916,8 +933,11 @@ def print_points_change(solution, group, new_points, old_points):
916933 print_points_change (change .solution , change .group , change .result , change .old_result )
917934 elif isinstance (change , PointsChange ):
918935 print_points_change (change .solution , change .group , change .new_points , change .old_points )
936+ elif isinstance (change , TotalPointsChange ):
937+ print (util .warning ("Solution %s passed all groups with %d points while it should pass with %d points." %
938+ (change .solution , change .new_points , change .old_points )))
919939
920- if diff .expected_scores == diff .new_expected_scores :
940+ if diff .expected_scores == diff .new_expected_scores and not diff . unknown_change :
921941 print (util .info ("Expected scores are correct!" ))
922942 else :
923943 def delete_group (solution , group ):
@@ -935,7 +955,6 @@ def set_group_result(solution, group, result):
935955 self .possible_score
936956 )
937957
938-
939958 if self .args .apply_suggestions :
940959 for solution in diff .removed_solutions :
941960 del config_expected_scores [solution ]
@@ -951,7 +970,6 @@ def set_group_result(solution, group, result):
951970 else :
952971 config_expected_scores [solution ] = diff .new_expected_scores [solution ]
953972
954-
955973 self .config ["sinol_expected_scores" ] = self .convert_status_to_string (config_expected_scores )
956974 util .save_config (self .config )
957975 print (util .info ("Saved suggested expected scores description." ))
@@ -1129,6 +1147,7 @@ def run(self, args):
11291147 print ("Task: %s (tag: %s)" % (title , self .ID ))
11301148 self .cpus = args .cpus or mp .cpu_count ()
11311149 cache .save_to_cache_extra_compilation_files (self .config .get ("extra_compilation_files" , []), self .ID )
1150+ cache .remove_results_if_contest_type_changed (self .config .get ("sinol_contest_type" , "default" ))
11321151
11331152 checker = package_util .get_files_matching_pattern (self .ID , f'{ self .ID } chk.*' )
11341153 if len (checker ) != 0 :
@@ -1158,6 +1177,15 @@ def run(self, args):
11581177
11591178 results , all_results = self .compile_and_run (solutions )
11601179 self .check_errors (all_results )
1161- validation_results = self .validate_expected_scores (results )
1180+ try :
1181+ validation_results = self .validate_expected_scores (results )
1182+ except :
1183+ self .config = util .try_fix_config (self .config )
1184+ try :
1185+ validation_results = self .validate_expected_scores (results )
1186+ except :
1187+ util .exit_with_error ("Validating expected scores failed. "
1188+ "This probably means that `sinol_expected_scores` is broken. "
1189+ "Delete it and run `sinol-make run --apply-suggestions` again." )
11621190 self .print_expected_scores_diff (validation_results )
11631191 self .exit ()
0 commit comments