1

I'm using decorators to validate parameters arriving to my function (via a dictionary object), when I have 2 keys or more it works fine. But if I have only key it returns an error (check_person). I defined 2 functions to exemplify my problem:

    def required(**mandatory):
        """

        :param mandatory:
        :return:
        """

        def decorator(f):
            @wraps(f)
            def wrapper(**dicts):
                for argname, d in dicts.items():
                    for key in mandatory.get(argname, []):
                        if key not in d:
                            raise Exception('Key "%s" is missing from argument "%s"' % (key, argname))
                return f(**dicts)
            return wrapper
        return decorator

@required(json_request=(_PROVIDER, _REPORT))
def check_campaign(json_request):
    """

    :param json_request:
    :return:
    """

    return True

@required(json_request=(_NAME))
def check_person(json_request=None):
    """

    :param json_request:
    :return:
    """
    return True

I need to change check_person to:

if _NAME in json_request:
        return True
    return False

To make it work.

When I try:

self.assertTrue(validator.check_person(json_request=json.loads("""{"name": "Elon Musk"}""")))

or specifically:

{"name": "Elon Musk"}

I get:

Error
Traceback (most recent call last):
  File "/Users/spicyramen/Documents/OpenSource/Development/Python/gonzo/utils/validate/validator_test.py", line 46, in test_person
    self.assertTrue(validator.check_person(json_request=json.loads("""{"name": "Elon Musk"}""")))
  File "/Users/spicyramen/Documents/OpenSource/Development/Python/gonzo/utils/validate/validator.py", line 26, in wrapper
    raise Exception('Key "%s" is missing from argument "%s"' % (key, argname))
Exception: Key "n" is missing from argument "json_request"

When my dictionary has more than 1 key it works fine (Like check_campaign).

1 Answer 1

1

The problem is a subtle syntax distinction.

With @required(json_request=(_PROVIDER, _REPORT)), your request is a tuple: (_PROVIDER, _REPORT).

By contrast, in your failing example @required(json_request=(_NAME)), the request is only the value _NAME. To make it a tuple, add a comma: @required(json_request=(_NAME,)). That ought to fix all your troubles.


As to why you get that exact error, you iterate over the argument. When it's a tuple, it works as you want. When it's a string, iterating over it gets you each letter. That's why 'n' was missing: it's the first letter of 'name'.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.