From a5e1f7c7d15d23b8f3adffc4cf59fd5adfaf8927 Mon Sep 17 00:00:00 2001 From: Pablo Acosta Date: Wed, 25 Feb 2015 06:28:20 -0500 Subject: [PATCH] Abstracted decorated function argument parsing and related decorated function processing and validation into a separate function. Results are cached for speed gains on multiple calls to the same decorated function --- src/contracts/main.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/contracts/main.py b/src/contracts/main.py index c5a6c44..4bd2450 100644 --- a/src/contracts/main.py +++ b/src/contracts/main.py @@ -155,10 +155,12 @@ def tmp_wrap(f): return tmp_wrap -def contracts_decorate(function_, modify_docstring=True, **kwargs): - """ An explicit way to decorate a given function. - The decorator :py:func:`decorate` calls this function internally. - """ +_FUNCTION_CACHE = {} +def process_function(function_, **kwargs): + + record = _FUNCTION_CACHE.get(function_, None) + if record: + return record if isinstance(function_, classmethod): msg = """ @@ -192,10 +194,10 @@ def f(cls, a): returns = kwargs.pop('returns', None) - for kw in kwargs: - if not kw in all_args: - msg = 'Unknown parameter %r; I know %r.' % (kw, all_args) - raise ContractException(msg) + sdiff = set(kwargs) - set(all_args) + if sdiff: + msg = 'Unknown parameter %r; I know %r.' % (next(iter(sdiff)), all_args) + raise ContractException(msg) accepts_dict = dict(**kwargs) @@ -234,6 +236,17 @@ def f(cls, a): is_bound_method = 'self' in all_args + _FUNCTION_CACHE[function_] = (all_args, accepts_parsed, returns_parsed, is_bound_method) + + return _FUNCTION_CACHE[function_] + + +def contracts_decorate(function_, modify_docstring=True, **kwargs): + """ An explicit way to decorate a given function. + The decorator :py:func:`decorate` calls this function internally. + """ + all_args, accepts_parsed, returns_parsed, is_bound_method = process_function(function_, **kwargs) + def contracts_checker(unused, *args, **kwargs): do_checks = not all_disabled() if not do_checks: