def _add_validators_to_setter(setter_fun, var_name, validators, property_name):
# 0. check that we can import validate
# note: this is useless now but maybe one day validate will be another project ?
try:
# noinspection PyUnresolvedReferences
from valid8 import decorate_with_validators
except ImportError:
raise Exception('Use of _add_contract_to_setter requires that validate library is installed. Check that you can'
' \'import validate\'')
# -- check if a contract already exists on the function
if hasattr(setter_fun, '__validators__'):
msg = 'overridden setter for attribute ' + property_name + ' implemented by function ' \
+ str(setter_fun.__qualname__) + ' has validators while there are validators already defined ' \
'for this property in the __init__ constructor. This will lead to double-contract in the final ' \
'setter, please remove the one on the overridden setter.'
warn(msg)
# -- add the generated contract
setter_fun_with_validation = decorate_with_validators(setter_fun, **{var_name: validators})
# # the only thing we can't do is to replace the function's parameter name dynamically in the validation error
# # messages so we wrap the function again to catch the potential pycontracts error :(
# # old:
# # @functools.wraps(func) -> to make the wrapper function look like the wrapped function
# # def wrapper(self, *args, **kwargs):
# # new:
# # we now use 'decorate' to have a wrapper that has the same signature, see below
# def _contracts_parser_interceptor(func, self, *args, **kwargs):
# try:
# return func(self, *args, **kwargs)
# except ContractNotRespected as e:
# e.error = e.error.replace('\'val\'', '\'' + property_name + '\'')
# raise e
# f = _contracts_parser_interceptor(f)
# setter_fun_with_possible_contract = decorate(setter_fun_with_possible_contract, _contracts_parser_interceptor)
return setter_fun_with_validation
评论列表
文章目录