22# pylint: disable=R0904
33# have to skip B404, import_subprocess is required for executing typescript
44# have to skip B60*, to allow typescript code to be executed using subprocess
5+ import fnmatch
56import json
67import logging
78import re
@@ -98,6 +99,7 @@ def __init__(
9899 self ._docker_client = docker .from_env () if self ._docker_image else None
99100 self ._executable_entrypoint = executable_entrypoint
100101 self ._target_info = self ._setup_target_info (target_info )
102+ self ._resolved_targets = {}
101103
102104 @staticmethod
103105 def _properties_to_paths (schema , key ):
@@ -140,12 +142,24 @@ def get_hook_type_name(self):
140142 return self ._type_name if self ._type_name else self ._schema ["typeName" ]
141143
142144 def get_handler_targets (self , invocation_point ):
143- try :
144- handlers = self ._schema ["handlers" ]
145- handler = handlers [generate_handler_name (invocation_point )]
146- return handler ["targetNames" ]
147- except KeyError :
148- return set ()
145+ handler = self ._schema ["handlers" ][generate_handler_name (invocation_point )]
146+
147+ targets = set ()
148+ for target_name in handler .get ("targetNames" , []):
149+ if self ._contains_wildcard (target_name ):
150+ if target_name not in self ._resolved_targets :
151+ self ._resolved_targets [target_name ] = fnmatch .filter (
152+ self ._target_info .keys (), target_name
153+ )
154+ targets .update (self ._resolved_targets [target_name ])
155+ else :
156+ targets .add (target_name )
157+
158+ return sorted (targets )
159+
160+ @staticmethod
161+ def _contains_wildcard (pattern ):
162+ return pattern and ("*" in pattern or "?" in pattern )
149163
150164 @staticmethod
151165 def assert_in_progress (status , response , target = "" ):
@@ -239,7 +253,7 @@ def _generate_target_example(self, target):
239253 return {}
240254
241255 info = self ._target_info .get (target )
242- if not info .get ("SchemaStrategy" ):
256+ if not info .get ("SchemaStrategy" ): # pragma: no cover
243257 # imported here to avoid hypothesis being loaded before pytest is loaded
244258 from .resource_generator import ResourceGenerator
245259
@@ -260,7 +274,7 @@ def _generate_target_update_example(self, target, model):
260274 return {}
261275
262276 info = self ._target_info .get (target )
263- if not info .get ("UpdateSchemaStrategy" ):
277+ if not info .get ("UpdateSchemaStrategy" ): # pragma: no cover
264278 # imported here to avoid hypothesis being loaded before pytest is loaded
265279 from .resource_generator import ResourceGenerator
266280
@@ -497,3 +511,11 @@ def call(
497511 status = HookStatus [response ["hookStatus" ]]
498512
499513 return status , response
514+
515+ def handler_has_wildcard_targets (self , invocation_point ):
516+ return any (
517+ self ._contains_wildcard (target_name )
518+ for target_name in self ._schema ["handlers" ][
519+ generate_handler_name (invocation_point )
520+ ]["targetNames" ]
521+ )
0 commit comments