Ejemplo n.º 1
0
 def wrapper(*args, **kwargs):
     try:
         func_name = get_function_name(func)
         if func_name in ("__init__", "__new__") and "kwargs" in kwargs:
             packed = params_pack(params, kwargs,
                                  dict_zip(params[1:], args[1:]),
                                  kwargs["kwargs"], defaults)
             return func(args[0], **packed)
         elif func_name in ("__init__", "__new__") and 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)
             return func(args[0], **packed)
         elif func_name in ("__init__", "__new__"):
             # DO NOT INCLUDE self IN kwargs
             packed = params_pack(params, kwargs,
                                  dict_zip(params[1:], args[1:]), defaults)
             return func(args[0], **packed)
         elif params[0] == "self" and "kwargs" in kwargs:
             packed = params_pack(params, kwargs,
                                  dict_zip(params[1:], args[1:]),
                                  kwargs["kwargs"], defaults)
             return func(args[0], **packed)
         elif params[0] == "self" and 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)
             return func(args[0], **packed)
         elif params[0] == "self":
             packed = params_pack(params, kwargs,
                                  dict_zip(params[1:], args[1:]), defaults)
             return func(args[0], **packed)
         elif len(args) == 1 and len(kwargs) == 0 and isinstance(
                 args[0], Mapping):
             # ASSUME SINGLE PARAMETER IS A SETTING
             packed = params_pack(params, args[0], defaults)
             return func(**packed)
         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)
             return func(**packed)
         else:
             # PULL kwargs OUT INTO PARAMS
             packed = params_pack(params, kwargs, dict_zip(params, args),
                                  defaults)
             return func(**packed)
     except TypeError as e:
         e = Except.wrap(e)
         if e.message.startswith(func_name) and "takes at least" in e:
             missing = [p for p in params if str(p) not in packed]
             get_logger().error(
                 "Problem calling {{func_name}}:  Expecting parameter {{missing}}, given {{given}}",
                 func_name=func_name,
                 missing=missing,
                 given=packed.keys(),
                 stack_depth=1)
         get_logger().error("Error dispatching call", e)
Ejemplo n.º 2
0
    def run(name, target, *args, **kwargs):
        # ENSURE target HAS please_stop ARGUMENT
        if get_function_name(target) == 'wrapper':
            pass  # GIVE THE override DECORATOR A PASS
        elif "please_stop" not in target.__code__.co_varnames:
            Log.error("function must have please_stop argument for signalling emergency shutdown")

        Thread.num_threads += 1

        output = Thread(name, target, *args, **kwargs)
        output.start()
        return output
Ejemplo n.º 3
0
def simplified(func):
    def mark_as_simple(self):
        if self.simplified:
            return self

        output = func(self)
        output.simplified = True
        return output

    func_name = get_function_name(func)
    mark_as_simple.__name__ = func_name
    return mark_as_simple
Ejemplo n.º 4
0
    def run(name, target, *args, **kwargs):
        # ENSURE target HAS please_stop ARGUMENT
        if get_function_name(target) == 'wrapper':
            pass  # GIVE THE override DECORATOR A PASS
        elif "please_stop" not in target.__code__.co_varnames:
            Log.error("function must have please_stop argument for signalling emergency shutdown")

        Thread.num_threads += 1

        output = Thread(name, target, *args, **kwargs)
        output.start()
        return output
Ejemplo n.º 5
0
def formatter(func):
    """
    register formatters
    """
    FORMATTERS[get_function_name(func)] = func
    return func
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
 def extender(func):
     setattr(cls, get_function_name(func), func)
     return func
Ejemplo n.º 9
0
def formatter(func):
    """
    register formatters
    """
    FORMATTERS[get_function_name(func)]=func
    return func
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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)