def combine_contract(parent, child): if type(parent) is NullContract and type(child) is NullContract: combine_argsets(parent, child) return elif type(parent) is SpecContract and type(child) is SpecContract: repeated = set(parent.declared) & set(child.declared) if repeated: # FIXME: Repeated variables can occur in three different # classes. key = next(iter(repeated)) message = incompatible_contracts_template.format( repeated=", ".join(map(repr, sorted(repeated))), cls=parent.declared[key][0], method=parent.declared[key][1], other_cls=child.declared[key][0], other_method=child.declared[key][1], ) raise ContextContractError(message) combine_argsets(parent, child) combine_declared(parent, child) else: message = type_error_template.format( cls=parent.cls_name, method=parent.name, contract=format_contract(parent), other_cls=child.cls_name, other_method=child.name, other_contract=format_contract(child), ) raise ContextContractError(message)
def check_assign_statement(self, method, ctx, ns, seen, name, value): __tracebackhide__ = True super(SpecContract, self).check_assign_statement( method, ctx, ns, seen, name, value ) unknown = self.identify(name) if unknown: message = unknown_variable_template.format( unknown=name, cls=method.__self__.__class__.__name__, method=method.__name__, contract=self, ) raise ContextContractError(message) normalized, errors = self.validate({name: value}, ns, seen) if errors: message = invalid_variable_template.format( variable=name, cls=method.__self__.__class__.__name__, method=method.__name__, violations=format_violations({name: value}, errors), contract=self.format_contract_fields(errors), ) raise ContextContractError(message) return normalized[name]
def validate(self, kwargs, ns, seen): __tracebackhide__ = True result, errors, conflict = {}, {}, {} for key, value in kwargs.items(): if key in self.spec: self.validate_spec(result, errors, ns, seen, key, value) else: self.validate_argset(result, errors, ns, seen, conflict, key, value) if conflict: conflict_vars = sorted({j for i in conflict.values() for j in i}) message = normalization_conflict_template.format( conflict=", ".join(map(repr, conflict_vars)), results="\n\n".join( "%s.%s:\n%s" % ( cls, method, "\n".join( " - {}: {!r}".format(i, result[i]) for i in sorted(result) ), ) for (cls, method), result in ( (i, conflict[i]) for i in sorted(conflict) ) ), contract=self.format_contract_fields(conflict_vars), ) raise ContextContractError(message) return result, errors
def combine_contract(parent, child): if type(parent) is NullContract and type(child) is NullContract: combine_argsets(parent, child) return elif (type(parent) is SpecContract and type(child) is SpecContract and parent.origin is child.origin): combine_argsets(parent, child) return elif (type(parent) is SpecContract and type(child) is SpecContract and any( isinstance(parent.origin, spec_type) and isinstance(child.origin, spec_type) for spec_type in [ PydanticSpec, Marshmallow3Spec, Marshmallow2Spec, CerberusSpec, dict, ])): repeated = set(parent.declared) & set(child.declared) if repeated: # FIXME: Repeated variables can occur in three different # classes. key = next(iter(repeated)) message = incompatible_contracts_template.format( repeated=", ".join(map(repr, sorted(repeated))), cls=parent.declared[key][0], method=parent.declared[key][1], other_cls=child.declared[key][0], other_method=child.declared[key][1], ) raise ContextContractError(message) combine_argsets(parent, child) combine_declared(parent, child) else: message = type_error_template.format( cls=parent.cls_name, method=parent.name, contract=format_contract(parent), other_cls=child.cls_name, other_method=child.name, other_contract=format_contract(child), ) raise ContextContractError(message)
def check_arguments_definitions(cls_name, name, arguments, spec): __tracebackhide__ = True undefined = set(arguments) - set(spec) if undefined: message = undefined_argument_template.format( undefined=", ".join(sorted(undefined)), cls=cls_name, method=name, arguments=", ".join(arguments), ) raise ContextContractError(message)
def check_assign_statement(self, method, ctx, ns, seen, name, value): __tracebackhide__ = True if name in ns: message = variable_override_template.format( variable=name, cls=method.__self__.__class__.__name__, method=method.__name__, ctx=ctx, ) raise ContextContractError(message) return value
def check_success_statement(self, method, ctx, ns): __tracebackhide__ = True tries_to_override = set(ctx._Context__ns) & set(ns) if tries_to_override: message = variable_override_template.format( variables=", ".join(map(repr, sorted(tries_to_override))), cls=method.__self__.__class__.__name__, method=method.__name__, ctx=ctx, ) raise ContextContractError(message) return ns
def check_substory_call(self, ctx): __tracebackhide__ = True missed = set(self.arguments) - set(ctx._Context__ns) if missed: message = missed_variable_template.format( missed=", ".join(sorted(missed)), cls=self.cls_name, method=self.name, arguments=", ".join(self.arguments), ctx=ctx, ) raise ContextContractError(message)
def check_story_call(self, kwargs): __tracebackhide__ = True # FIXME: Check required arguments here. unknown_arguments = set(kwargs) - set(self.argset) if unknown_arguments: message = unknown_argument_template.format( unknown=", ".join(sorted(unknown_arguments)), cls=self.cls_name, method=self.name, contract=self, ) raise ContextContractError(message) return kwargs
def check_success_statement(self, method, ctx, ns): __tracebackhide__ = True super(SpecContract, self).check_success_statement(method, ctx, ns) unknown = self.identify(ns) if unknown: message = unknown_variable_template.format( unknown=", ".join(map(repr, sorted(unknown))), cls=method.__self__.__class__.__name__, method=method.__name__, contract=self, ) raise ContextContractError(message) kwargs, errors = self.validate(ns) if errors: message = invalid_variable_template.format( variables=", ".join(map(repr, sorted(errors))), cls=method.__self__.__class__.__name__, method=method.__name__, violations=format_violations(ns, errors), contract=self.format_contract_fields(errors), ) raise ContextContractError(message) return kwargs
def check_story_call(self, kwargs): __tracebackhide__ = True super(SpecContract, self).check_story_call(kwargs) result, errors = self.validate(kwargs) if errors: message = invalid_argument_template.format( variables=", ".join(map(repr, sorted(errors))), cls=self.cls_name, method=self.name, violations=format_violations(kwargs, errors), contract=self.format_contract_fields(errors), ) raise ContextContractError(message) return result