def w_settings(*args, **kwargs): settings = kwargs.get("kwargs") params = get_function_arguments(func) if not get_function_defaults(func): defaults = {} else: defaults = { k: v for k, v in zip(reversed(params), reversed(get_function_defaults(func))) } ordered_params = dict(zip(params, args)) return func(**params_pack(params, ordered_params, kwargs, settings, defaults))
def __call__(self, *args, **kwargs): settings = wrap(kwargs).settings params = get_function_arguments(self.constructor)[1:] func_defaults = get_function_defaults(self.constructor) if not func_defaults: defaults = {} else: defaults = {k: v for k, v in zip(reversed(params), reversed(func_defaults))} ordered_params = dict(zip(params, args)) output = self.class_(**params_pack(params, ordered_params, kwargs, settings, defaults)) return DataObject(output)
def override(func): """ THIS DECORATOR WILL PUT ALL PARAMETERS INTO THE `kwargs` PARAMETER AND THEN PUT ALL `kwargs` PARAMETERS INTO THE FUNCTION PARAMETERS. THIS HAS THE BENEFIT OF HAVING ALL PARAMETERS IN ONE PLACE (kwargs), PLUS ALL PARAMETERS ARE EXPLICIT FOR CLARITY. OF COURSE, THIS MEANS PARAMETER ASSIGNMENT MAY NOT BE UNIQUE: VALUES CAN COME FROM EXPLICIT CALL PARAMETERS, OR FROM THE kwargs PARAMETER. IN THESE CASES, PARAMETER VALUES ARE CHOSEN IN THE FOLLOWING ORDER: 1) EXPLICT CALL PARAMETERS 2) PARAMETERS FOUND IN kwargs 3) DEFAULT VALUES ASSIGNED IN FUNCTION DEFINITION """ func_name = get_function_name(func) params = get_function_arguments(func) if not get_function_defaults(func): defaults = {} else: defaults = { k: v for k, v in zip(reversed(params), reversed(get_function_defaults(func))) } def raise_error(e, a, k): packed = set_default(dict(zip(params, a)), k) err = text(e) e = Except.wrap(e) if err.startswith(func_name) and ( "takes at least" in err or "takes exactly " in err or "required positional argument" in err ): missing = [p for p in params if str(p) not in packed] given = [p for p in params if str(p) in packed] if not missing: raise e else: get_logger().error( "Problem calling {{func_name}}: Expecting parameter {{missing}}, given {{given}}", func_name=func_name, missing=missing, given=given, stack_depth=2, cause=e, ) raise e if KWARGS not in params: # ADDING A kwargs PARAMETER TO SOME REGULAR METHOD def wo_kwargs(*args, **kwargs): settings = kwargs.get(KWARGS, {}) ordered_params = dict(zip(params, args)) a, k = params_pack(params, defaults, settings, kwargs, ordered_params) try: return func(*a, **k) except TypeError as e: raise_error(e, a, k) return update_wrapper(wo_kwargs, func) elif func_name in ("__init__", "__new__") or params[0] in ("self", "cls"): def w_bound_method(*args, **kwargs): if len(args) == 2 and len(kwargs) == 0 and is_data(args[1]): # ASSUME SECOND UNNAMED PARAM IS kwargs a, k = params_pack( params, defaults, args[1], {params[0]: args[0]}, kwargs ) elif KWARGS in kwargs and is_data(kwargs[KWARGS]): # PUT args INTO kwargs a, k = params_pack( params, defaults, kwargs[KWARGS], dict_zip(params, args), kwargs ) else: a, k = params_pack(params, defaults, dict_zip(params, args), kwargs) try: return func(*a, **k) except TypeError as e: raise_error(e, a, k) return update_wrapper(w_bound_method, func) else: def w_kwargs(*args, **kwargs): if len(args) == 1 and len(kwargs) == 0 and is_data(args[0]): # ASSUME SINGLE PARAMETER IS kwargs a, k = params_pack(params, defaults, args[0]) elif KWARGS in kwargs and is_data(kwargs[KWARGS]): # PUT args INTO kwargs a, k = params_pack( params, defaults, kwargs[KWARGS], dict_zip(params, args), kwargs ) else: # PULL kwargs OUT INTO PARAMS a, k = params_pack(params, defaults, dict_zip(params, args), kwargs) try: return func(*a, **k) except TypeError as e: raise_error(e, a, k) return update_wrapper(w_kwargs, func)
def override(func): """ THIS DECORATOR WILL PUT ALL PARAMETERS INTO THE `kwargs` PARAMETER AND THEN PUT ALL `kwargs` PARAMETERS INTO THE FUNCTION PARAMETERS. THIS HAS THE BENEFIT OF HAVING ALL PARAMETERS IN ONE PLACE (kwargs), PLUS ALL PARAMETERS ARE EXPLICIT FOR CLARITY. OF COURSE, THIS MEANS PARAMETER ASSIGNMENT MAY NOT BE UNIQUE: VALUES CAN COME FROM EXPLICIT CALL PARAMETERS, OR FROM THE kwargs PARAMETER. IN THESE CASES, PARAMETER VALUES ARE CHOSEN IN THE FOLLOWING ORDER: 1) EXPLICT CALL PARAMETERS 2) PARAMETERS FOUND IN kwargs 3) DEFAULT VALUES ASSIGNED IN FUNCTION DEFINITION """ func_name = get_function_name(func) params = get_function_arguments(func) if not get_function_defaults(func): defaults = {} else: defaults = {k: v for k, v in zip(reversed(params), reversed(get_function_defaults(func)))} def raise_error(e, packed): err = text_type(e) e = Except.wrap(e) if err.startswith(func_name) and ("takes at least" in err or "required positional argument" in err): missing = [p for p in params if str(p) not in packed] given = [p for p in params if str(p) in packed] if not missing: raise e else: get_logger().error( "Problem calling {{func_name}}: Expecting parameter {{missing}}, given {{given}}", func_name=func_name, missing=missing, given=given, stack_depth=2, cause=e ) raise e if "kwargs" not in params: # WE ASSUME WE ARE ONLY ADDING A kwargs PARAMETER TO SOME REGULAR METHOD def wo_kwargs(*args, **kwargs): settings = kwargs.get("kwargs") ordered_params = dict(zip(params, args)) packed = params_pack(params, ordered_params, kwargs, settings, defaults) try: return func(**packed) except TypeError as e: raise_error(e, packed) return wo_kwargs elif func_name in ("__init__", "__new__"): def w_constructor(*args, **kwargs): if "kwargs" in kwargs: packed = params_pack(params, dict_zip(params[1:], args[1:]), kwargs, kwargs["kwargs"], defaults) elif len(args) == 2 and len(kwargs) == 0 and is_data(args[1]): # ASSUME SECOND UNNAMED PARAM IS kwargs packed = params_pack(params, args[1], defaults) else: # DO NOT INCLUDE self IN kwargs packed = params_pack(params, dict_zip(params[1:], args[1:]), kwargs, defaults) try: return func(args[0], **packed) except TypeError as e: packed['self'] = args[0] # DO NOT SAY IS MISSING raise_error(e, packed) return w_constructor elif params[0] == "self": def w_bound_method(*args, **kwargs): if len(args) == 2 and len(kwargs) == 0 and is_data(args[1]): # ASSUME SECOND UNNAMED PARAM IS kwargs packed = params_pack(params, args[1], defaults) elif "kwargs" in kwargs and is_data(kwargs["kwargs"]): # PUT args INTO kwargs packed = params_pack(params, kwargs, dict_zip(params[1:], args[1:]), kwargs["kwargs"], defaults) else: packed = params_pack(params, kwargs, dict_zip(params[1:], args[1:]), defaults) try: return func(args[0], **packed) except TypeError as e: raise_error(e, packed) return w_bound_method else: def w_kwargs(*args, **kwargs): if len(args) == 1 and len(kwargs) == 0 and is_data(args[0]): # ASSUME SINGLE PARAMETER IS kwargs packed = params_pack(params, args[0], defaults) elif "kwargs" in kwargs and is_data(kwargs["kwargs"]): # PUT args INTO kwargs packed = params_pack(params, kwargs, dict_zip(params, args), kwargs["kwargs"], defaults) else: # PULL kwargs OUT INTO PARAMS packed = params_pack(params, kwargs, dict_zip(params, args), defaults) try: return func(**packed) except TypeError as e: raise_error(e, packed) return w_kwargs
def output(func): func_name = get_function_name(func) params = get_function_arguments(func) if not get_function_defaults(func): defaults = {} else: defaults = { k: v for k, v in zip(reversed(params), reversed(get_function_defaults(func))) } def raise_error(e, a, k): packed = set_default(dict(zip(params, a)), k) err = text(e) e = Except.wrap(e) if err.startswith(func_name) and ( "takes at least" in err or "takes exactly " in err or "required positional argument" in err): missing = [p for p in params if str(p) not in packed] given = [p for p in params if str(p) in packed] if not missing: raise e else: get_logger().error( "Problem calling {{func_name}}: Expecting parameter {{missing}}, given {{given}}", func_name=func_name, missing=missing, given=given, stack_depth=2, cause=e, ) raise e if kwargs not in params: # ADDING A kwargs PARAMETER TO SOME REGULAR METHOD def wo_kwargs(*given_args, **given_kwargs): settings = given_kwargs.get(kwargs, {}) ordered_params = dict(zip(params, given_args)) a, k = params_pack(params, defaults, settings, given_kwargs, ordered_params) try: return func(*a, **k) except TypeError as e: raise_error(e, a, k) return update_wrapper(wo_kwargs, func) elif func_name in ("__init__", "__new__") or params[0] in ("self", "cls"): def w_bound_method(*given_args, **given_kwargs): if len(given_args) == 2 and len(given_kwargs) == 0 and is_data( given_args[1]): # ASSUME SECOND UNNAMED PARAM IS kwargs a, k = params_pack(params, defaults, given_args[1], {params[0]: given_args[0]}, given_kwargs) elif kwargs in given_kwargs and is_data(given_kwargs[kwargs]): # PUT args INTO given_kwargs a, k = params_pack(params, defaults, given_kwargs[kwargs], dict_zip(params, given_args), given_kwargs) else: a, k = params_pack(params, defaults, dict_zip(params, given_args), given_kwargs) try: return func(*a, **k) except TypeError as e: raise_error(e, a, k) return update_wrapper(w_bound_method, func) else: def w_kwargs(*given_args, **given_kwargs): if len(given_args) == 1 and len(given_kwargs) == 0 and is_data( given_args[0]): # ASSUME SINGLE PARAMETER IS kwargs a, k = params_pack(params, defaults, given_args[0]) elif kwargs in given_kwargs and is_data(given_kwargs[kwargs]): # PUT given_args INTO given_kwargs a, k = params_pack(params, defaults, given_kwargs[kwargs], dict_zip(params, given_args), given_kwargs) else: # PULL kwargs OUT INTO PARAMS a, k = params_pack(params, defaults, dict_zip(params, given_args), given_kwargs) try: return func(*a, **k) except TypeError as e: raise_error(e, a, k) return update_wrapper(w_kwargs, func)
def override(func): """ THIS DECORATOR WILL PUT ALL PARAMETERS INTO THE `kwargs` PARAMETER AND THEN PUT ALL `kwargs` PARAMETERS INTO THE FUNCTION PARAMETERS. THIS HAS THE BENEFIT OF HAVING ALL PARAMETERS IN ONE PLACE (kwargs), PLUS ALL PARAMETERS ARE EXPLICIT FOR CLARITY. OF COURSE, THIS MEANS PARAMETER ASSIGNMENT MAY NOT BE UNIQUE: VALUES CAN COME FROM EXPLICIT CALL PARAMETERS, OR FROM THE kwargs PARAMETER. IN THESE CASES, PARAMETER VALUES ARE CHOSEN IN THE FOLLOWING ORDER: 1) EXPLICT CALL PARAMETERS 2) PARAMETERS FOUND IN kwargs 3) DEFAULT VALUES ASSIGNED IN FUNCTION DEFINITION """ func_name = get_function_name(func) params = get_function_arguments(func) if not get_function_defaults(func): defaults = {} else: defaults = { k: v for k, v in zip(reversed(params), reversed(get_function_defaults(func))) } def raise_error(e, packed): err = text_type(e) e = Except.wrap(e) if err.startswith(func_name) and ("takes at least" in err or "required positional argument" in err): missing = [p for p in params if str(p) not in packed] given = [p for p in params if str(p) in packed] get_logger().error( "Problem calling {{func_name}}: Expecting parameter {{missing}}, given {{given}}", func_name=func_name, missing=missing, given=given, stack_depth=2) get_logger().error("Error dispatching call", e) if "kwargs" not in params: # WE ASSUME WE ARE ONLY ADDING A kwargs PARAMETER TO SOME REGULAR METHOD def wo_kwargs(*args, **kwargs): settings = kwargs.get("kwargs") ordered_params = dict(zip(params, args)) packed = params_pack(params, ordered_params, kwargs, settings, defaults) try: return func(**packed) except TypeError as e: raise_error(e, packed) return wo_kwargs elif func_name in ("__init__", "__new__"): def w_constructor(*args, **kwargs): if "kwargs" in kwargs: packed = params_pack(params, kwargs, dict_zip(params[1:], args[1:]), kwargs["kwargs"], defaults) elif len(args) == 2 and len(kwargs) == 0 and isinstance( args[1], Mapping): # ASSUME SECOND UNNAMED PARAM IS kwargs packed = params_pack(params, args[1], defaults) else: # DO NOT INCLUDE self IN kwargs packed = params_pack(params, kwargs, dict_zip(params[1:], args[1:]), defaults) try: return func(args[0], **packed) except TypeError as e: raise_error(e, packed) return w_constructor elif params[0] == "self": def w_bound_method(*args, **kwargs): if len(args) == 2 and len(kwargs) == 0 and isinstance( args[1], Mapping): # ASSUME SECOND UNNAMED PARAM IS kwargs packed = params_pack(params, args[1], defaults) elif "kwargs" in kwargs and isinstance(kwargs["kwargs"], Mapping): # PUT args INTO kwargs packed = params_pack(params, kwargs, dict_zip(params[1:], args[1:]), kwargs["kwargs"], defaults) else: packed = params_pack(params, kwargs, dict_zip(params[1:], args[1:]), defaults) try: return func(args[0], **packed) except TypeError as e: raise_error(e, packed) return w_bound_method else: def w_kwargs(*args, **kwargs): if len(args) == 1 and len(kwargs) == 0 and isinstance( args[0], Mapping): # ASSUME SINGLE PARAMETER IS kwargs packed = params_pack(params, args[0], defaults) elif "kwargs" in kwargs and isinstance(kwargs["kwargs"], Mapping): # PUT args INTO kwargs packed = params_pack(params, kwargs, dict_zip(params, args), kwargs["kwargs"], defaults) else: # PULL kwargs OUT INTO PARAMS packed = params_pack(params, kwargs, dict_zip(params, args), defaults) try: return func(**packed) except TypeError as e: raise_error(e, packed) return w_kwargs
def wrap_function(cache_store, func_): attr_name = "_cache_for_" + func_.__name__ func_name = get_function_name(func_) params = get_function_arguments(func_) if not get_function_defaults(func_): defaults = {} else: defaults = { k: v for k, v in zip(reversed(params), reversed(get_function_defaults(func_))) } func_args = get_function_arguments(func_) if len(func_args) > 0 and func_args[0] == "self": using_self = True func = lambda self, *args: func_(self, *args) else: using_self = False func = lambda self, *args: func_(*args) def output(*args, **kwargs): if kwargs: Log.error( "Sorry, caching only works with ordered parameter, not keyword arguments" ) with cache_store.locker: if using_self: self = args[0] args = args[1:] else: self = cache_store now = Date.now() try: _cache = getattr(self, attr_name) except Exception: _cache = {} setattr(self, attr_name, _cache) if randoms.int(100) == 0: # REMOVE OLD CACHE _cache = { k: v for k, v in _cache.items() if v.timeout == None or v.timeout > now } setattr(self, attr_name, _cache) timeout, key, value, exception = _cache.get( args, (Null, Null, Null, Null)) if now >= timeout: value = func(self, *args) with cache_store.locker: _cache[args] = CacheElement(now + cache_store.timeout, args, value, None) return value if value == None: if exception == None: try: value = func(self, *args) with cache_store.locker: _cache[args] = CacheElement(now + cache_store.timeout, args, value, None) return value except Exception as e: e = Except.wrap(e) with cache_store.locker: _cache[args] = CacheElement(now + cache_store.timeout, args, None, e) raise e else: raise exception else: return value return update_wrapper(output, func)