{"action":"created","issue":{"url":"https://api.github.com/repos/alecthomas/voluptuous/issues/127","labels_url":"https://api.github.com/repos/alecthomas/voluptuous/issues/127/labels{/name}","comments_url":"https://api.github.com/repos/alecthomas/voluptuous/issues/127/comments","events_url":"https://api.github.com/repos/alecthomas/voluptuous/issues/127/events","html_url":"https://github.com/alecthomas/voluptuous/issues/127","id":103064699,"number":127,"title":"Bug: Inaccurate Error Messages When Dict Keys Require Complex Validation","user":{"login":"kennytrytek-wf","id":1466480,"avatar_url":"https://avatars.githubusercontent.com/u/1466480?v=3","gravatar_id":"","url":"https://api.github.com/users/kennytrytek-wf","html_url":"https://github.com/kennytrytek-wf","followers_url":"https://api.github.com/users/kennytrytek-wf/followers","following_url":"https://api.github.com/users/kennytrytek-wf/following{/other_user}","gists_url":"https://api.github.com/users/kennytrytek-wf/gists{/gist_id}","starred_url":"https://api.github.com/users/kennytrytek-wf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kennytrytek-wf/subscriptions","organizations_url":"https://api.github.com/users/kennytrytek-wf/orgs","repos_url":"https://api.github.com/users/kennytrytek-wf/repos","events_url":"https://api.github.com/users/kennytrytek-wf/events{/privacy}","received_events_url":"https://api.github.com/users/kennytrytek-wf/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-08-25T16:25:11Z","updated_at":"2015-08-25T20:33:00Z","closed_at":null,"body":"```\r\n>>> from voluptuous import *\r\n>>> s = Schema({All('abc', Coerce(int)): 1})\r\n>>> s({'abc': 1})\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/Users/kennytrytek/virtual_env/skynet-cli/lib/python2.7/site-packages/voluptuous.py\", line 333, in __call__\r\n    return self._compiled([], data)\r\n  File \"/Users/kennytrytek/virtual_env/skynet-cli/lib/python2.7/site-packages/voluptuous.py\", line 631, in validate_dict\r\n    return base_validate(path, iteritems(data), out)\r\n  File \"/Users/kennytrytek/virtual_env/skynet-cli/lib/python2.7/site-packages/voluptuous.py\", line 467, in validate_mapping\r\n    raise MultipleInvalid(errors)\r\nvoluptuous.MultipleInvalid: extra keys not allowed @ data['abc']\r\n```\r\n\r\nThe real error is that `Coerce` fails because `'abc'` isn't a valid `int`, but it gets clobbered by the extra keys error."},"comment":{"url":"https://api.github.com/repos/alecthomas/voluptuous/issues/comments/134731769","html_url":"https://github.com/alecthomas/voluptuous/issues/127#issuecomment-134731769","issue_url":"https://api.github.com/repos/alecthomas/voluptuous/issues/127","id":134731769,"user":{"login":"kennytrytek-wf","id":1466480,"avatar_url":"https://avatars.githubusercontent.com/u/1466480?v=3","gravatar_id":"","url":"https://api.github.com/users/kennytrytek-wf","html_url":"https://github.com/kennytrytek-wf","followers_url":"https://api.github.com/users/kennytrytek-wf/followers","following_url":"https://api.github.com/users/kennytrytek-wf/following{/other_user}","gists_url":"https://api.github.com/users/kennytrytek-wf/gists{/gist_id}","starred_url":"https://api.github.com/users/kennytrytek-wf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kennytrytek-wf/subscriptions","organizations_url":"https://api.github.com/users/kennytrytek-wf/orgs","repos_url":"https://api.github.com/users/kennytrytek-wf/repos","events_url":"https://api.github.com/users/kennytrytek-wf/events{/privacy}","received_events_url":"https://api.github.com/users/kennytrytek-wf/received_events","type":"User","site_admin":false},"created_at":"2015-08-25T20:33:00Z","updated_at":"2015-08-25T20:33:00Z","body":"Workaround:\r\n```\r\nclass DictKeyInvalid(Invalid):\r\n    \"\"\"Dict key does not match the given schema.\"\"\"\r\n\r\n\r\ndef DictKey(schema):\r\n    \"\"\"\r\n    Dict key does not match the given schema.\r\n\r\n    :type schema: Schema\r\n    :param schema: Schema with which to validate each dict key.\r\n    \r\n    >>> schema = Schema(All(DictKey(All(str, Coerce(int))), {str: int}))\r\n    >>> schema({'123': 123, 'abc': 'abc'})\r\n    voluptuous.MultipleInvalid: key abc is invalid\r\n    >>> schema({'123': 123, '456': 456})\r\n    {'123': 123, '456': 456}\r\n    \"\"\"\r\n    def f(x):\r\n        if not x:\r\n            return x\r\n        key = None\r\n        try:\r\n            for k in x.keys():\r\n                key = k\r\n                schema(k)\r\n        except Invalid:\r\n            raise DictKeyInvalid('key {} is invalid'.format(key))\r\n        return x\r\n    return f\r\n```\r\n\r\nSee `DictKey` docstring for examples. It's not pretty, but it does the job with an understandable error message."}}