@@ -146,6 +146,11 @@ def is_disjoint_base_related(self) -> bool:
146146 # TODO: This is hacky, use error codes or something more resilient
147147 return "@disjoint_base" in self .message
148148
149+ def is_private_type_check_only_related (self ) -> bool :
150+ """Whether or not the error is related to @type_check_only on private types."""
151+ # TODO: This is hacky, use error codes or something more resilient
152+ return self .message .endswith ('Maybe mark it as "@type_check_only"?' )
153+
149154 def get_description (self , concise : bool = False ) -> str :
150155 """Returns a description of the error.
151156
@@ -2330,6 +2335,7 @@ class _Arguments:
23302335 ignore_missing_stub : bool
23312336 ignore_positional_only : bool
23322337 ignore_disjoint_bases : bool
2338+ strict_type_check_only : bool
23332339 allowlist : list [str ]
23342340 generate_allowlist : bool
23352341 ignore_unused_allowlist : bool
@@ -2429,6 +2435,8 @@ def warning_callback(msg: str) -> None:
24292435 if error .object_desc in allowlist :
24302436 allowlist [error .object_desc ] = True
24312437 continue
2438+ if not args .strict_type_check_only and error .is_private_type_check_only_related ():
2439+ continue
24322440 is_allowlisted = False
24332441 for w in allowlist :
24342442 if allowlist_regexes [w ].fullmatch (error .object_desc ):
@@ -2522,6 +2530,11 @@ def parse_options(args: list[str]) -> _Arguments:
25222530 action = "store_true" ,
25232531 help = "Disable checks for PEP 800 @disjoint_base classes" ,
25242532 )
2533+ parser .add_argument (
2534+ "--strict-type-check-only" ,
2535+ action = "store_true" ,
2536+ help = "Require @type_check_only on private types that are not present at runtime" ,
2537+ )
25252538 parser .add_argument (
25262539 "--allowlist" ,
25272540 "--whitelist" ,
0 commit comments