def compatible(self, other: Union["task.Task", "Wrap"], extra_params: Optional[Mapping] = None) -> bool: """ Return True if self (current wrap) provides valid inputs for other. Parameters ---------- other Another task or wrap extra_params A mapping of extra parameters Returns ------- bool """ if isinstance(other, task.Task): other = other.wrap() # ensure we are working with a wrap if not isinstance(other, Wrap): return False adapter = self.features.get("adapter", None) try: args, kwargs = sig_to_args_kwargs(self.signature, adapter) except NoReturnAnnotation: # if there is no return annotation return True sig = other.signature check_type = self.check_type and other.check_type # check if raw inputs work, if not look in extra_params for args if valid_input(sig, *args, check_type=check_type, **kwargs): return True extra_params = extra_params or other._partials # else determine if any params should be provided by extra_params return _compatible_extra(sig, args, kwargs, extra_params, check_type)
def _check_inputs(self, _bound, *args, **kwargs): """ Ensure the inputs are of compatible types with the signature and get return type. """ check_type = self.get_option("check_type") sig = _bound.signature valid = valid_input(sig, *args, bound=_bound, check_type=check_type, **kwargs) if not valid: msg = (f"{args} and {kwargs} are not valid inputs for {self} " f"which expects a signature of {sig}") raise TypeError(msg) return _get_return_type(_bound)
def _check_inputs(self, bound, *args, check_type=True, **kwargs): """ Ensure the inputs are of compatible types with the signature and get return type. Also take into account possible fixture values. """ sig = bound.signature valid = valid_input(sig, *args, bound=bound, check_type=check_type, **kwargs) if not valid: msg = (f'{args} and {kwargs} are not valid inputs for {self} ' f'which expects a signature of {sig}') raise TypeError(msg) return _get_return_type(bound)
def _compatible_extra(sig, args, kwargs, extra_params, check_type): """ Determine if args, kwargs are valid inputs to sig if supplemented with extra_params """ extra_params = extra_params or {} commons = set(sig.parameters) & set(extra_params) if not commons: return False # iterate over commons and pull out values or parameter annotations partials = {} for common in commons: new = extra_params[common] # need to extact type from task signature return value if isinstance(new, (task.Task, Wrap)): partials[common] = Wrap(new).signature.return_annotation else: # else this is the desired value, just get the type partials[common] = type(new) new_kwargs = partial_to_kwargs(None, *args, partial_dict=partials, signature=sig, **kwargs) return valid_input(sig, check_type=check_type, **new_kwargs)
def test_non_compat_inputs(self, func, args, kwargs): assert not valid_input(func, *args, **kwargs)