11from __future__ import annotations
22
3+ from typing import TYPE_CHECKING
4+
5+ from returns .maybe import Maybe , Nothing , Some
6+
37from t4_devkit .schema import SchemaName
48
59from ..checker import RuleID , RuleName , Severity
610from ..registry import CHECKERS
711from ..result import Reason
12+ from ..safety import load_json_safe
813from .base import RecordCountChecker
914
15+ if TYPE_CHECKING :
16+ from ..context import SanityContext
17+
1018__all__ = ["REC006" ]
1119
1220
@@ -17,9 +25,45 @@ class REC006(RecordCountChecker):
1725 id = RuleID ("REC006" )
1826 name = RuleName ("instance-not-empty" )
1927 severity = Severity .ERROR
20- description = "'Instance' record is not empty."
28+ description = (
29+ "'Instance' record is not empty if either 'SampleAnnotation' or 'ObjectAnn' is not empty."
30+ )
2131 schema = SchemaName .INSTANCE
2232
33+ def can_skip (self , context : SanityContext ) -> Maybe [Reason ]:
34+ # return skip reason if instance.json does not exist
35+ match super ().can_skip (context ):
36+ case Some (x ):
37+ return Maybe .from_value (x )
38+
39+ # instance.json should contain any records if either
40+ # SampleAnnotation or ObjectAnn records exist
41+ sample_ann_file = context .to_schema_file (SchemaName .SAMPLE_ANNOTATION )
42+ object_ann_file = context .to_schema_file (SchemaName .OBJECT_ANN )
43+ match (sample_ann_file , object_ann_file ):
44+ case (Some (s ), Some (o )):
45+ # check both files exist
46+ if not s .exists ():
47+ return Maybe .from_value (
48+ Reason (f"Missing { SchemaName .SAMPLE_ANNOTATION .filename } " )
49+ )
50+ if not o .exists ():
51+ return Maybe .from_value (Reason (f"Missing { SchemaName .OBJECT_ANN .filename } " ))
52+
53+ # check if both files are empty
54+ sample_ann = load_json_safe (s ).unwrap ()
55+ object_ann = load_json_safe (o ).unwrap ()
56+ return Maybe .from_value (
57+ Reason (
58+ f"Both { SchemaName .SAMPLE_ANNOTATION } "
59+ f"and { SchemaName .OBJECT_ANN } records are empty"
60+ )
61+ if len (sample_ann ) == 0 and len (object_ann ) == 0
62+ else Nothing
63+ )
64+ case _:
65+ return Maybe .from_value (Reason ("Missing 'annotation' directory" ))
66+
2367 def check_count (self , records : list [dict ]) -> list [Reason ] | None :
2468 num_instance = len (records )
2569 return [Reason ("'Instance' record must not be empty" )] if num_instance == 0 else None
0 commit comments