)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"b5fbfbdf51c51dae26bdaf82d8ae198ec0a3ca08","unresolved":false,"context_lines":[{"line_number":12,"context_line":"TODOs:"},{"line_number":13,"context_line":"* Discuss basic design of the framework."},{"line_number":14,"context_line":"* Apply the framework to other APIs by defining each API schema."},{"line_number":15,"context_line":"* Test and test."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"blueprint nova-api-validation-fw"},{"line_number":18,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"AAAAOH%2F%2Fzp0%3D","line":15,"updated":"2013-03-26 20:05:49.000000000","message":"Do these TODOs imply that this patch is a work in progress?  If so, please hit the \"work-in-progress\" button…","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"85577b270f32105901f1b2f9e828d59ae612dad7","unresolved":false,"context_lines":[{"line_number":12,"context_line":"TODOs:"},{"line_number":13,"context_line":"* Discuss basic design of the framework."},{"line_number":14,"context_line":"* Apply the framework to other APIs by defining each API schema."},{"line_number":15,"context_line":"* Test and test."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"blueprint nova-api-validation-fw"},{"line_number":18,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"AAAAOH%2F%2FzS4%3D","line":15,"in_reply_to":"AAAAOH%2F%2Fzp0%3D","updated":"2013-03-27 02:44:31.000000000","message":"Thanks, I pushed the \"work-in-progress\" button.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"707016949e98d8fa1fd80f5a2f22d290d5b87c3a","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch adds a core part of API validation framework."},{"line_number":10,"context_line":"Other patches of each API schema are necessary."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"The validation method is implmented with jsonschema library,"},{"line_number":13,"context_line":"and some features are added:"},{"line_number":14,"context_line":" * validate minimum/maximum value of string number(ex. \"10\")"},{"line_number":15,"context_line":" * validate uuid string format"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":50,"id":"AAAATn%2F%2BdTo%3D","line":12,"updated":"2013-11-25 20:44:49.000000000","message":"femtonit: s/implmented/implemented/","commit_id":"f25fbaa2f72030dec48eee30c354b34356cd6808"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"cc71ef9e40931f35f64cdf5d73a8af8651cc4d93","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch adds a core part of API validation framework."},{"line_number":10,"context_line":"Other patches of each API schema are necessary."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"The validation method is implmented with jsonschema library,"},{"line_number":13,"context_line":"and some features are added:"},{"line_number":14,"context_line":" * validate minimum/maximum value of string number(ex. \"10\")"},{"line_number":15,"context_line":" * validate uuid string format"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":50,"id":"AAAATn%2F%2BdI8%3D","line":12,"in_reply_to":"AAAATn%2F%2BdTo%3D","updated":"2013-11-25 21:19:21.000000000","message":"thanks, will fix it.","commit_id":"f25fbaa2f72030dec48eee30c354b34356cd6808"}],"nova/api/api_validator.py":[{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"60d66b1685af6c693f8065f546304134fd2fbd5d","unresolved":false,"context_lines":[{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class APIValidator(jsonschema.Draft4Validator):"},{"line_number":38,"context_line":"    def __init__(self, schema):"},{"line_number":39,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":40,"context_line":"            self._minimum_original \u003d self.VALIDATORS[\u0027minimum\u0027]"},{"line_number":41,"context_line":"            self._maximum_original \u003d self.VALIDATORS[\u0027maximum\u0027]"},{"line_number":42,"context_line":"            self.VALIDATORS[\u0027minimum\u0027] \u003d self._validate_minimum_v1_4"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAPX%2F%2FoC0%3D","line":39,"updated":"2013-06-14 03:04:08.000000000","message":"Is this code for checking whether jsonschema library \u003e\u003d v1.4.0?\nIf so, do we need a comment or a version check function about that?","commit_id":"09d0667620ce31d9de9d316566ac5888629ca9bd"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"9d3571d783facc3ea9305d028517f57dccde4d20","unresolved":false,"context_lines":[{"line_number":36,"context_line":""},{"line_number":37,"context_line":"class APIValidator(jsonschema.Draft4Validator):"},{"line_number":38,"context_line":"    def __init__(self, schema):"},{"line_number":39,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":40,"context_line":"            self._minimum_original \u003d self.VALIDATORS[\u0027minimum\u0027]"},{"line_number":41,"context_line":"            self._maximum_original \u003d self.VALIDATORS[\u0027maximum\u0027]"},{"line_number":42,"context_line":"            self.VALIDATORS[\u0027minimum\u0027] \u003d self._validate_minimum_v1_4"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAPX%2F%2Fn%2Bw%3D","line":39,"in_reply_to":"AAAAPX%2F%2FoC0%3D","updated":"2013-06-14 03:35:18.000000000","message":"It is good idea to add the comment for explaining it. I will do it.\n\nand I don\u0027t feel a version check function is necessary for here, because the point is the internal functions are different and the above code can distinguish it.","commit_id":"09d0667620ce31d9de9d316566ac5888629ca9bd"},{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"60d66b1685af6c693f8065f546304134fd2fbd5d","unresolved":false,"context_lines":[{"line_number":59,"context_line":"                return None"},{"line_number":60,"context_line":"        return value"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":63,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":64,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":65,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAPX%2F%2FoB8%3D","line":62,"updated":"2013-06-14 03:04:08.000000000","message":"Do we need support for jsonschema library \u003c v1.4.0?","commit_id":"09d0667620ce31d9de9d316566ac5888629ca9bd"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"9d3571d783facc3ea9305d028517f57dccde4d20","unresolved":false,"context_lines":[{"line_number":59,"context_line":"                return None"},{"line_number":60,"context_line":"        return value"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":63,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":64,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":65,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAPX%2F%2Fn%2Bk%3D","line":62,"in_reply_to":"AAAAPX%2F%2FoB8%3D","updated":"2013-06-14 03:35:18.000000000","message":"It is good point.\nFor many environments, I feel good to support older jsonschema library.","commit_id":"09d0667620ce31d9de9d316566ac5888629ca9bd"},{"author":{"_account_id":7203,"name":"yuuichi fujioka","email":"fujioka.yuuichi@gmail.com","username":"FujiokaYuuichi"},"change_message_id":"9fe9224fc746d337d1ad1912c9c70187cafc7eb9","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    schema_validator \u003d APIValidator(request_body_schema)"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def add_validator(func):"},{"line_number":99,"context_line":"        def wrapper(self, *args, **kwargs):"},{"line_number":100,"context_line":"            schema_validator.validate(kwargs[\u0027body\u0027])"},{"line_number":101,"context_line":"            return func(self, *args, **kwargs)"},{"line_number":102,"context_line":"        return wrapper"}],"source_content_type":"text/x-python","patch_set":26,"id":"AAAAPn%2F%2FshY%3D","line":99,"updated":"2013-06-25 03:25:35.000000000","message":"I think wrapper should be decorated @functools.wraps, because this case lost information of function.(func_name, __doc__, etc...)","commit_id":"edaaa41c3772aac6f9396d62ee9cd21421f40200"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4520c5124537f73fd4b0a48fc41755b51246a122","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    schema_validator \u003d APIValidator(request_body_schema)"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def add_validator(func):"},{"line_number":99,"context_line":"        def wrapper(self, *args, **kwargs):"},{"line_number":100,"context_line":"            schema_validator.validate(kwargs[\u0027body\u0027])"},{"line_number":101,"context_line":"            return func(self, *args, **kwargs)"},{"line_number":102,"context_line":"        return wrapper"}],"source_content_type":"text/x-python","patch_set":26,"id":"AAAAPn%2F%2Fscg%3D","line":99,"in_reply_to":"AAAAPn%2F%2FshY%3D","updated":"2013-06-25 04:29:45.000000000","message":"will fix","commit_id":"edaaa41c3772aac6f9396d62ee9cd21421f40200"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0130ecff5ed466d48dc2bda4ffd7d0341485eef3","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    return uuidutils.is_uuid_like(instance)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class APIValidator(jsonschema.Draft4Validator):"},{"line_number":39,"context_line":"    def __init__(self, schema):"},{"line_number":40,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":41,"context_line":"            # NOTE(oomichi): Here is for jsonschema library v1.4.0+."}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FncY%3D","line":38,"updated":"2013-06-26 17:35:19.000000000","message":"I think we should have a nova exception that is raised to convert from the jsonschema exception, so we can encapsulate our dependency on jsonschema inside here.\n\nOr maybe just throw the appropriate webob exception?","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"3df9e6178ce0815d23b8f72404e90060464daa17","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    return uuidutils.is_uuid_like(instance)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class APIValidator(jsonschema.Draft4Validator):"},{"line_number":39,"context_line":"    def __init__(self, schema):"},{"line_number":40,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":41,"context_line":"            # NOTE(oomichi): Here is for jsonschema library v1.4.0+."}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FlcM%3D","line":38,"in_reply_to":"AAAAPn%2F%2FlfM%3D","updated":"2013-06-27 10:52:21.000000000","message":"OK, it has done with new patch(#28).","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"91e9ca883d8f50b78a8a415e81d753964f123763","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    return uuidutils.is_uuid_like(instance)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class APIValidator(jsonschema.Draft4Validator):"},{"line_number":39,"context_line":"    def __init__(self, schema):"},{"line_number":40,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":41,"context_line":"            # NOTE(oomichi): Here is for jsonschema library v1.4.0+."}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FlfM%3D","line":38,"in_reply_to":"AAAAPn%2F%2FmPQ%3D","updated":"2013-06-27 09:31:35.000000000","message":"Yeah, I agree, I think nova.exception.ValidationError (marked with the correct response code) is probably the best.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"6291c2869979617ca2aa6bfc5af651d176b933e5","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    return uuidutils.is_uuid_like(instance)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class APIValidator(jsonschema.Draft4Validator):"},{"line_number":39,"context_line":"    def __init__(self, schema):"},{"line_number":40,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":41,"context_line":"            # NOTE(oomichi): Here is for jsonschema library v1.4.0+."}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FmPQ%3D","line":38,"in_reply_to":"AAAAPn%2F%2FncY%3D","updated":"2013-06-27 03:49:27.000000000","message":"Thanks, good point.\n\nI had made nova.exception.ValidationError(https://review.openstack.org/#/c/25358/5/nova/api/openstack/wsgi.py),\nand I dropped it because the point, where jsonschema.ValidationError happens, was near the \"except\" point.\nbut now, they are far and I feel nova.exception.ValidationError is necessary as you said.\nso I will add the exception with next version.\n\n\u003e Or maybe just throw the appropriate webob exception?\n\nI feel nova.exception.ValidationError is better than webob exception because we can keep webob exceptions in wsgi.py and that means easy moving to other web framework in the future.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0130ecff5ed466d48dc2bda4ffd7d0341485eef3","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                return None"},{"line_number":65,"context_line":"        return value"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":68,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":69,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":70,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2Fns4%3D","line":67,"updated":"2013-06-26 17:35:19.000000000","message":"can we not just look to either require a new version, or does that clash with another project?","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"3df9e6178ce0815d23b8f72404e90060464daa17","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                return None"},{"line_number":65,"context_line":"        return value"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":68,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":69,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":70,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FlWs%3D","line":67,"in_reply_to":"AAAAPn%2F%2Fle8%3D","updated":"2013-06-27 10:52:21.000000000","message":"Great, thanks!\nI will remove the code related to jsonschema 1.4.0+.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"91e9ca883d8f50b78a8a415e81d753964f123763","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                return None"},{"line_number":65,"context_line":"        return value"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":68,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":69,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":70,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2Fle8%3D","line":67,"in_reply_to":"AAAAPn%2F%2FmOM%3D","updated":"2013-06-27 09:31:35.000000000","message":"I would go on the side of requiring 1.4 and that will give us less code to maintain.\n\nBut maybe go with what you have now because of this:\nhttps://github.com/openstack/requirements/blob/master/tools/pip-requires#L22","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"6291c2869979617ca2aa6bfc5af651d176b933e5","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                return None"},{"line_number":65,"context_line":"        return value"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":68,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":69,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":70,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FmOM%3D","line":67,"in_reply_to":"AAAAPn%2F%2Fns4%3D","updated":"2013-06-27 03:49:27.000000000","message":"To be honesty, I don\u0027t know another project uses what version of jsonschema.\nbut I guess it is good to support many versions of the library for many environments.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0130ecff5ed466d48dc2bda4ffd7d0341485eef3","unresolved":false,"context_lines":[{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":68,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":69,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":70,"context_line":"        if value is None:"},{"line_number":71,"context_line":"            return"},{"line_number":72,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FnZI%3D","line":69,"updated":"2013-06-26 17:35:19.000000000","message":"Why do we need these changes, is this because of the XML not coming out with integers? Or do we always do strings?","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"3df9e6178ce0815d23b8f72404e90060464daa17","unresolved":false,"context_lines":[{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":68,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":69,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":70,"context_line":"        if value is None:"},{"line_number":71,"context_line":"            return"},{"line_number":72,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FlVo%3D","line":69,"in_reply_to":"AAAAPn%2F%2Flek%3D","updated":"2013-06-27 10:52:21.000000000","message":"Good idea, thanks. I will add that.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"91e9ca883d8f50b78a8a415e81d753964f123763","unresolved":false,"context_lines":[{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":68,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":69,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":70,"context_line":"        if value is None:"},{"line_number":71,"context_line":"            return"},{"line_number":72,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2Flek%3D","line":69,"in_reply_to":"AAAAPn%2F%2FmIM%3D","updated":"2013-06-27 09:31:35.000000000","message":"OK, cool.\n\nCan we add a #NOTE just to state that it can be removed when we tighten up the API definition and the XML-\u003eJSON conversion?","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"6291c2869979617ca2aa6bfc5af651d176b933e5","unresolved":false,"context_lines":[{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":68,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":69,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":70,"context_line":"        if value is None:"},{"line_number":71,"context_line":"            return"},{"line_number":72,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FmIM%3D","line":69,"in_reply_to":"AAAAPn%2F%2FnZI%3D","updated":"2013-06-27 03:49:27.000000000","message":"You are right, here is useful for XML request.\n\nalso in JSON request, it is good to handle a string number because the data type of each parameter is not written on API specification document(http://api.openstack.org/api-ref.html) now.\n\n# I hope the document will be created from API schemas of this framework in the future :-)","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"c4dded95e4956ad9c104947d1eb499b50435ca36","unresolved":false,"context_lines":[{"line_number":56,"context_line":"            value \u003d int(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            try:"},{"line_number":59,"context_line":"                value \u003d float(instance)"},{"line_number":60,"context_line":"            except (ValueError, TypeError):"},{"line_number":61,"context_line":"                return None"},{"line_number":62,"context_line":"        return value"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FlC4%3D","line":59,"updated":"2013-06-27 13:13:25.000000000","message":"Do we need this? We don\u0027t seem to check any floats here.\n\nIf we drop the float bit, you can use the conversion methods in openstack.common.","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4f14cebbae373387e6626d76bf222e1b3c067c1b","unresolved":false,"context_lines":[{"line_number":56,"context_line":"            value \u003d int(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            try:"},{"line_number":59,"context_line":"                value \u003d float(instance)"},{"line_number":60,"context_line":"            except (ValueError, TypeError):"},{"line_number":61,"context_line":"                return None"},{"line_number":62,"context_line":"        return value"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FksU%3D","line":59,"in_reply_to":"AAAAPn%2F%2FlC4%3D","updated":"2013-06-27 15:06:36.000000000","message":"To check the value range if string float(e.g. \"1.5\"), I\u0027d like to keep this lines.\nI\u0027m sorry if I misunderstand your comment.","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"c4dded95e4956ad9c104947d1eb499b50435ca36","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                return None"},{"line_number":62,"context_line":"        return value"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":65,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":66,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":67,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FlCY%3D","line":64,"updated":"2013-06-27 13:13:25.000000000","message":"Probably my bad for confusing you, but your requires actually states use anything between 1.2 and 2.0 except 1.4.0, I think. Maybe you still need that other code too?","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4f14cebbae373387e6626d76bf222e1b3c067c1b","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                return None"},{"line_number":62,"context_line":"        return value"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":65,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":66,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":67,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FktM%3D","line":64,"in_reply_to":"AAAAPn%2F%2FlCY%3D","updated":"2013-06-27 15:06:36.000000000","message":"oops, my bad.. I will revert some code.","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"4c300c640ff05fe9fa1890f30e9da3c8e4881127","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"@jsonschema.FormatChecker.cls_checks(\u0027integer\u0027)"},{"line_number":25,"context_line":"def validate_integer_format(instance):"},{"line_number":26,"context_line":"    try:"},{"line_number":27,"context_line":"        int(instance)"},{"line_number":28,"context_line":"    except (ValueError, TypeError):"}],"source_content_type":"text/x-python","patch_set":31,"id":"AAAAPn%2F%2FbNI%3D","line":25,"updated":"2013-07-02 08:37:38.000000000","message":"There have been a few patches over the last period where the validation of the an integer does the following int(str(value)). This is to check that the value is not say 2.5. (https://github.com/openstack/nova/blob/master/nova/api/openstack/compute/servers.py#L852)\nIs this relevant here?","commit_id":"80fd9096b89be03b3534ce40f0372c6d625203b8"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"949de8c6b7e031175bfffe4f6bd829ab54b66d51","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"@jsonschema.FormatChecker.cls_checks(\u0027integer\u0027)"},{"line_number":25,"context_line":"def validate_integer_format(instance):"},{"line_number":26,"context_line":"    try:"},{"line_number":27,"context_line":"        int(instance)"},{"line_number":28,"context_line":"    except (ValueError, TypeError):"}],"source_content_type":"text/x-python","patch_set":31,"id":"AAAAPn%2F%2FbEs%3D","line":25,"in_reply_to":"AAAAPn%2F%2FbNI%3D","updated":"2013-07-02 09:54:49.000000000","message":"Good point, thanks.\nI confirm the behavior of FormatChecker now.\n\nFormatChecker is used only if the type \"string\" because of the following code of jsonschema library:\n\n 444     def validate_format(self, format, instance, schema):\n 445         if (\n 446             self.format_checker is not None and\n 447             self.is_type(instance, \"string\")\n 448         ):\n 449             try:\n 450                 self.format_checker.check(instance, format)\n\nThe argument \"instance\" of validate_integer_format() should be string, so we don\u0027t need int(str(value)).","commit_id":"80fd9096b89be03b3534ce40f0372c6d625203b8"},{"author":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"change_message_id":"7132d16549c9f6201ebb82be847c1c5e486b15f1","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":14,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":15,"context_line":"#    under the License."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"import functools"},{"line_number":18,"context_line":"import jsonschema"},{"line_number":19,"context_line":""}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FZ8c%3D","line":16,"updated":"2013-07-31 17:32:04.000000000","message":"This file should have a docstring as well","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"30c1fcdbdb90e344bd10b66c279f382dcf71d23b","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":14,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":15,"context_line":"#    under the License."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"import functools"},{"line_number":18,"context_line":"import jsonschema"},{"line_number":19,"context_line":""}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FY3w%3D","line":16,"in_reply_to":"AAAAQn%2F%2FZ8c%3D","updated":"2013-08-01 06:26:04.000000000","message":"I see. will add a docstring here.","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"d6d1b76bcc3eaa379c233b14dd7ad8a482b2c09b","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"@jsonschema.FormatChecker.cls_checks(\u0027integer\u0027)"},{"line_number":25,"context_line":"def validate_integer_format(instance):"},{"line_number":26,"context_line":"    try:"},{"line_number":27,"context_line":"        int(instance)"},{"line_number":28,"context_line":"    except (ValueError, TypeError):"}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FbFA%3D","line":25,"updated":"2013-07-31 12:37:39.000000000","message":"These validator functions look like private details of the implementation. Perhaps this module should be a package, so you can more easily separate the public and private parts of the API?","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"30c1fcdbdb90e344bd10b66c279f382dcf71d23b","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"@jsonschema.FormatChecker.cls_checks(\u0027integer\u0027)"},{"line_number":25,"context_line":"def validate_integer_format(instance):"},{"line_number":26,"context_line":"    try:"},{"line_number":27,"context_line":"        int(instance)"},{"line_number":28,"context_line":"    except (ValueError, TypeError):"}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FYtE%3D","line":25,"in_reply_to":"AAAAQn%2F%2FbFA%3D","updated":"2013-08-01 06:26:04.000000000","message":"Good idea, it would make code more readable.\nI am going to try it.","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"d6d1b76bcc3eaa379c233b14dd7ad8a482b2c09b","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    return uuidutils.is_uuid_like(instance)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class APIValidator(jsonschema.Draft4Validator):"},{"line_number":39,"context_line":"    def __init__(self, schema):"},{"line_number":40,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":41,"context_line":"            # NOTE(oomichi): Here is for jsonschema library v1.4.0+."}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FbFI%3D","line":38,"updated":"2013-07-31 12:37:39.000000000","message":"Are developers expected to instantiate this directly? If not, the name should start with _ to indicate that it is an implementation detail of the module.","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"30c1fcdbdb90e344bd10b66c279f382dcf71d23b","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    return uuidutils.is_uuid_like(instance)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class APIValidator(jsonschema.Draft4Validator):"},{"line_number":39,"context_line":"    def __init__(self, schema):"},{"line_number":40,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":41,"context_line":"            # NOTE(oomichi): Here is for jsonschema library v1.4.0+."}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FYsU%3D","line":38,"in_reply_to":"AAAAQn%2F%2FbFI%3D","updated":"2013-08-01 06:26:04.000000000","message":"You are right. will add prefix \"_\" to this class.","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"d6d1b76bcc3eaa379c233b14dd7ad8a482b2c09b","unresolved":false,"context_lines":[{"line_number":71,"context_line":"                return None"},{"line_number":72,"context_line":"        return value"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":75,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":76,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":77,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FbFk%3D","line":74,"updated":"2013-07-31 12:37:39.000000000","message":"We can pick a version of jsonschema to support, can\u0027t we? Why do we need separate methods for different versions?","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"30c1fcdbdb90e344bd10b66c279f382dcf71d23b","unresolved":false,"context_lines":[{"line_number":71,"context_line":"                return None"},{"line_number":72,"context_line":"        return value"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    # NOTE(oomichi): For jsonschema library \u003c v1.4.0"},{"line_number":75,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":76,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":77,"context_line":"        if value is None:"}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FYYg%3D","line":74,"in_reply_to":"AAAAQn%2F%2FbFk%3D","updated":"2013-08-01 06:26:04.000000000","message":"I feel it is better to support many versions of the library for many environments, is that wrong thought?","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"d6d1b76bcc3eaa379c233b14dd7ad8a482b2c09b","unresolved":false,"context_lines":[{"line_number":100,"context_line":"        return self._maximum_original(validator, minimum, value, schema)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"def validator(request_body_schema):"},{"line_number":104,"context_line":"    schema_validator \u003d APIValidator(request_body_schema)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def add_validator(func):"}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FbFQ%3D","line":103,"updated":"2013-07-31 12:37:39.000000000","message":"This public function needs a docstring.","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"30c1fcdbdb90e344bd10b66c279f382dcf71d23b","unresolved":false,"context_lines":[{"line_number":100,"context_line":"        return self._maximum_original(validator, minimum, value, schema)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"def validator(request_body_schema):"},{"line_number":104,"context_line":"    schema_validator \u003d APIValidator(request_body_schema)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def add_validator(func):"}],"source_content_type":"text/x-python","patch_set":34,"id":"AAAAQn%2F%2FY2A%3D","line":103,"in_reply_to":"AAAAQn%2F%2FbFQ%3D","updated":"2013-08-01 06:26:04.000000000","message":"I see, thanks. will add a docstring here also.","commit_id":"7fc2e9a973a402d25282ebbd044d7818ff3ddb19"}],"nova/api/api_validator/__init__.py":[{"author":{"_account_id":7996,"name":"Luis A. Garcia","email":"luis@linux.vnet.ibm.com","username":"luisg"},"change_message_id":"10b1d3478fc6444af8597b79577e9b06e79b438b","unresolved":false,"context_lines":[{"line_number":14,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":15,"context_line":"#    under the License."},{"line_number":16,"context_line":"\"\"\""},{"line_number":17,"context_line":"Request Body validating middleware."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"\"\"\""},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FUOk%3D","line":17,"updated":"2013-08-02 01:58:40.000000000","message":"I think when possible we should stick to package names without _ in their names. This package name is also a bit redundant, it is under the api package, but it still has the api_ prefix. How about just nova.api.validation","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"09d454c17998ca1669b8a66ec7f374e03b7f475c","unresolved":false,"context_lines":[{"line_number":14,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":15,"context_line":"#    under the License."},{"line_number":16,"context_line":"\"\"\""},{"line_number":17,"context_line":"Request Body validating middleware."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"\"\"\""},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FTp8%3D","line":17,"in_reply_to":"AAAAQn%2F%2FUOk%3D","updated":"2013-08-02 08:30:34.000000000","message":"I like your above idea, I will change.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":7996,"name":"Luis A. Garcia","email":"luis@linux.vnet.ibm.com","username":"luisg"},"change_message_id":"10b1d3478fc6444af8597b79577e9b06e79b438b","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from validators import _APIValidator"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def validator(request_body_schema):"},{"line_number":26,"context_line":"    \"\"\""},{"line_number":27,"context_line":"    Register a schema to validate request body."},{"line_number":28,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FUSM%3D","line":25,"updated":"2013-08-02 01:58:40.000000000","message":"With this annotation name the annotated API method would look like this:\n\n@validation.validator(schema)\ndef post(body):\n   ....\n\nI think it would be better if we changed the annotation name to @schema, it would look nicer and integrate better with the package name (see package rename comment):\n\n@validation.schema(server_schema)\ndef post(body):\n   ....\n\nAlso, with the original annotation name (@validator) it feels like the object that you pass in to the annotation is the validator itself, just like:\n\n@wsgi.serializer takes a serializer\n@wsgi.deserializer takes a deserializer\n\nHowever:\n\n@validation.validator does not take a validator, it actually takes a schema, hence the suggested rename.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"09d454c17998ca1669b8a66ec7f374e03b7f475c","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from validators import _APIValidator"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def validator(request_body_schema):"},{"line_number":26,"context_line":"    \"\"\""},{"line_number":27,"context_line":"    Register a schema to validate request body."},{"line_number":28,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FTpQ%3D","line":25,"in_reply_to":"AAAAQn%2F%2FUSM%3D","updated":"2013-08-02 08:30:34.000000000","message":"I also feel validation.schema is better than validation.validator.\nwill change here also.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"}],"nova/api/api_validator/validators.py":[{"author":{"_account_id":7996,"name":"Luis A. Garcia","email":"luis@linux.vnet.ibm.com","username":"luisg"},"change_message_id":"10b1d3478fc6444af8597b79577e9b06e79b438b","unresolved":false,"context_lines":[{"line_number":24,"context_line":"from nova.openstack.common import uuidutils"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"@jsonschema.FormatChecker.cls_checks(\u0027integer\u0027)"},{"line_number":28,"context_line":"def _validate_integer_format(instance):"},{"line_number":29,"context_line":"    try:"},{"line_number":30,"context_line":"        int(instance)"}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FUSc%3D","line":27,"updated":"2013-08-02 01:58:40.000000000","message":"Why do only integers get the special treatment of having their format checker? Should this be more generic, where the format could be something like a \u0027number\u0027 and we try to cast into a float() too, or should we also add another checker for floats?\n\nTo be honest, I would rather just have the types for these primitive types, and not the formats, but if not I think this part should be more complete by expanding it to all numbers.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"09d454c17998ca1669b8a66ec7f374e03b7f475c","unresolved":false,"context_lines":[{"line_number":24,"context_line":"from nova.openstack.common import uuidutils"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"@jsonschema.FormatChecker.cls_checks(\u0027integer\u0027)"},{"line_number":28,"context_line":"def _validate_integer_format(instance):"},{"line_number":29,"context_line":"    try:"},{"line_number":30,"context_line":"        int(instance)"}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FTeo%3D","line":27,"in_reply_to":"AAAAQn%2F%2FUSc%3D","updated":"2013-08-02 08:30:34.000000000","message":"\u003e I would rather just have the types for these primitive types, and not the formats,\n\nI can see your above comment. I defined \u0027integer\u0027 type which includes integer and string integer in old version.\nhttps://review.openstack.org/#/c/25358/2/nova/api/validator.py\n\nbut that broke compatibility with the JSON-Schema spec, and that has been changed to current implementation such as FormatChecker.\nhttps://review.openstack.org/#/c/25884/6/openstack/common/api_validator.py\n\nI guess it is ok to add these format types when we need them for defining each schema, isn\u0027t it?","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":7996,"name":"Luis A. Garcia","email":"luis@linux.vnet.ibm.com","username":"luisg"},"change_message_id":"10b1d3478fc6444af8597b79577e9b06e79b438b","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    return uuidutils.is_uuid_like(instance)"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"class _APIValidator(jsonschema.Draft4Validator):"},{"line_number":42,"context_line":"    def __init__(self, schema):"},{"line_number":43,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":44,"context_line":"            # NOTE(oomichi): Here is for jsonschema library v1.4.0+."}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FUZQ%3D","line":41,"updated":"2013-08-02 01:58:40.000000000","message":"Nit: Based on what this class does, should it be called _SchemaValidator instead, or _ResourceValidator (speaking of \"resource\" in the context of \"REST\").\n\nAlso could we add pydocs about what makes this class special over its parent?","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"09d454c17998ca1669b8a66ec7f374e03b7f475c","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    return uuidutils.is_uuid_like(instance)"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"class _APIValidator(jsonschema.Draft4Validator):"},{"line_number":42,"context_line":"    def __init__(self, schema):"},{"line_number":43,"context_line":"        if hasattr(self, \u0027VALIDATORS\u0027) and \u0027minimum\u0027 in self.VALIDATORS:"},{"line_number":44,"context_line":"            # NOTE(oomichi): Here is for jsonschema library v1.4.0+."}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FTnA%3D","line":41,"in_reply_to":"AAAAQn%2F%2FUZQ%3D","updated":"2013-08-02 08:30:34.000000000","message":"_SchemaValidator seems better, nice idea.\nalso I will add pydocs.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"}],"nova/api/openstack/compute/plugins/v3/fixed_ips.py":[{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"60d66b1685af6c693f8065f546304134fd2fbd5d","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        if \u0027reserve\u0027 in body:"},{"line_number":65,"context_line":"            LOG.debug(_(\"Reserving IP address %s\") % id)"},{"line_number":66,"context_line":"            return self._set_reserved(context, id, True)"},{"line_number":67,"context_line":"        elif \u0027unreserve\u0027 in body:"},{"line_number":68,"context_line":"            LOG.debug(_(\"Unreserving IP address %s\") % id)"},{"line_number":69,"context_line":"            return self._set_reserved(context, id, False)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAPX%2F%2FoBQ%3D","line":67,"updated":"2013-06-14 03:04:08.000000000","message":"I feel this \u0027elif ...:\u0027 code is not necessary. Because if body doesn\u0027t have \u0027reserve\u0027 or \u0027unreserve\u0027, the validator raise exception.","commit_id":"09d0667620ce31d9de9d316566ac5888629ca9bd"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"9d3571d783facc3ea9305d028517f57dccde4d20","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        if \u0027reserve\u0027 in body:"},{"line_number":65,"context_line":"            LOG.debug(_(\"Reserving IP address %s\") % id)"},{"line_number":66,"context_line":"            return self._set_reserved(context, id, True)"},{"line_number":67,"context_line":"        elif \u0027unreserve\u0027 in body:"},{"line_number":68,"context_line":"            LOG.debug(_(\"Unreserving IP address %s\") % id)"},{"line_number":69,"context_line":"            return self._set_reserved(context, id, False)"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAPX%2F%2Fn%2BY%3D","line":67,"in_reply_to":"AAAAPX%2F%2FoBQ%3D","updated":"2013-06-14 03:35:18.000000000","message":"Thanks, you are right.\nI will change here.","commit_id":"09d0667620ce31d9de9d316566ac5888629ca9bd"}],"nova/api/openstack/compute/servers.py":[{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"b5fbfbdf51c51dae26bdaf82d8ae198ec0a3ca08","unresolved":false,"context_lines":[{"line_number":692,"context_line":"    @wsgi.response(202)"},{"line_number":693,"context_line":"    @wsgi.serializers(xml\u003dFullServerTemplate)"},{"line_number":694,"context_line":"    @wsgi.deserializers(xml\u003dCreateDeserializer)"},{"line_number":695,"context_line":"    @wsgi.validator(schema\u003d{"},{"line_number":696,"context_line":"        \u0027type\u0027 : \u0027object\u0027,"},{"line_number":697,"context_line":"        \u0027properties\u0027 : {"},{"line_number":698,"context_line":"            \u0027server\u0027: {"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzpY%3D","line":695,"updated":"2013-03-26 20:05:49.000000000","message":"Can I suggest you define the schema elsewhere, perhaps as a top-level constant?  By including it directly here, it makes it a little more difficult to follow what\u0027s happening…","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"85577b270f32105901f1b2f9e828d59ae612dad7","unresolved":false,"context_lines":[{"line_number":692,"context_line":"    @wsgi.response(202)"},{"line_number":693,"context_line":"    @wsgi.serializers(xml\u003dFullServerTemplate)"},{"line_number":694,"context_line":"    @wsgi.deserializers(xml\u003dCreateDeserializer)"},{"line_number":695,"context_line":"    @wsgi.validator(schema\u003d{"},{"line_number":696,"context_line":"        \u0027type\u0027 : \u0027object\u0027,"},{"line_number":697,"context_line":"        \u0027properties\u0027 : {"},{"line_number":698,"context_line":"            \u0027server\u0027: {"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzRY%3D","line":695,"in_reply_to":"AAAAOH%2F%2FzmQ%3D","updated":"2013-03-27 02:44:31.000000000","message":"Good point, I also worried about this.\n\nNova has 200+ APIs now, and it is hard to maintain if all schemas are defined in one file.\nI feel it is better to define schemas by each API category. For example, nova/api/openstack/compute/servers.py\u0027s schema may be nova/api_schema/openstack/compute/servers.py\u0027.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"4c20b8f2b102089ecd342189747636678d46de14","unresolved":false,"context_lines":[{"line_number":692,"context_line":"    @wsgi.response(202)"},{"line_number":693,"context_line":"    @wsgi.serializers(xml\u003dFullServerTemplate)"},{"line_number":694,"context_line":"    @wsgi.deserializers(xml\u003dCreateDeserializer)"},{"line_number":695,"context_line":"    @wsgi.validator(schema\u003d{"},{"line_number":696,"context_line":"        \u0027type\u0027 : \u0027object\u0027,"},{"line_number":697,"context_line":"        \u0027properties\u0027 : {"},{"line_number":698,"context_line":"            \u0027server\u0027: {"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzmQ%3D","line":695,"in_reply_to":"AAAAOH%2F%2FzpY%3D","updated":"2013-03-26 20:40:38.000000000","message":"I would suggest exporting all schemas to one module like schema.py","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"}],"nova/api/openstack/extensions.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0130ecff5ed466d48dc2bda4ffd7d0341485eef3","unresolved":false,"context_lines":[{"line_number":470,"context_line":"            except jsonschema.ValidationError:"},{"line_number":471,"context_line":"                # Note(oomichi): Handle a validation error, which happens"},{"line_number":472,"context_line":"                # due to invalid API parameters, as an expected error."},{"line_number":473,"context_line":"                raise"},{"line_number":474,"context_line":"            except Exception as exc:"},{"line_number":475,"context_line":"                if isinstance(exc, webob.exc.WSGIHTTPException):"},{"line_number":476,"context_line":"                    if isinstance(errors, int):"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FnbY%3D","line":473,"updated":"2013-06-26 17:35:19.000000000","message":"This doesn\u0027t seem quite right, it should probably be something like exception.ValidationError, if we add that in, and put it next to the PolicyNotAuthorized one?","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"3df9e6178ce0815d23b8f72404e90060464daa17","unresolved":false,"context_lines":[{"line_number":470,"context_line":"            except jsonschema.ValidationError:"},{"line_number":471,"context_line":"                # Note(oomichi): Handle a validation error, which happens"},{"line_number":472,"context_line":"                # due to invalid API parameters, as an expected error."},{"line_number":473,"context_line":"                raise"},{"line_number":474,"context_line":"            except Exception as exc:"},{"line_number":475,"context_line":"                if isinstance(exc, webob.exc.WSGIHTTPException):"},{"line_number":476,"context_line":"                    if isinstance(errors, int):"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FlU8%3D","line":473,"in_reply_to":"AAAAPn%2F%2FleE%3D","updated":"2013-06-27 10:52:21.000000000","message":"I see. I will put the ValidationError next to the PolicyNotAuthorized for fitting current coding style.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"91e9ca883d8f50b78a8a415e81d753964f123763","unresolved":false,"context_lines":[{"line_number":470,"context_line":"            except jsonschema.ValidationError:"},{"line_number":471,"context_line":"                # Note(oomichi): Handle a validation error, which happens"},{"line_number":472,"context_line":"                # due to invalid API parameters, as an expected error."},{"line_number":473,"context_line":"                raise"},{"line_number":474,"context_line":"            except Exception as exc:"},{"line_number":475,"context_line":"                if isinstance(exc, webob.exc.WSGIHTTPException):"},{"line_number":476,"context_line":"                    if isinstance(errors, int):"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FleE%3D","line":473,"in_reply_to":"AAAAPn%2F%2FmM8%3D","updated":"2013-06-27 09:31:35.000000000","message":"yes, probably move the PolicyNotAuthorized one I guess. It will look nice when we move to exception.ValidationError.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"6291c2869979617ca2aa6bfc5af651d176b933e5","unresolved":false,"context_lines":[{"line_number":470,"context_line":"            except jsonschema.ValidationError:"},{"line_number":471,"context_line":"                # Note(oomichi): Handle a validation error, which happens"},{"line_number":472,"context_line":"                # due to invalid API parameters, as an expected error."},{"line_number":473,"context_line":"                raise"},{"line_number":474,"context_line":"            except Exception as exc:"},{"line_number":475,"context_line":"                if isinstance(exc, webob.exc.WSGIHTTPException):"},{"line_number":476,"context_line":"                    if isinstance(errors, int):"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FmM8%3D","line":473,"in_reply_to":"AAAAPn%2F%2FnbY%3D","updated":"2013-06-27 03:49:27.000000000","message":"\u003e This doesn\u0027t seem quite right, it should probably be something like exception.ValidationError, if we add that in,\n\nI see, will fix.\n\n\u003e and put it next to the PolicyNotAuthorized one?\n\nor should we move the block of the PolicyNotAuthorized to here?\nbecause it makes the *special* exceptions explicit.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":7996,"name":"Luis A. Garcia","email":"luis@linux.vnet.ibm.com","username":"luisg"},"change_message_id":"10b1d3478fc6444af8597b79577e9b06e79b438b","unresolved":false,"context_lines":[{"line_number":482,"context_line":"                    # calls. ResourceExceptionHandler silently"},{"line_number":483,"context_line":"                    # converts NotAuthorized to HTTPForbidden"},{"line_number":484,"context_line":"                    raise"},{"line_number":485,"context_line":"                elif isinstance(exc, exception.ValidationError):"},{"line_number":486,"context_line":"                    # Note(oomichi): Handle a validation error, which"},{"line_number":487,"context_line":"                    # happens due to invalid API parameters, as an"},{"line_number":488,"context_line":"                    # expected error."}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FUOw%3D","line":485,"updated":"2013-08-02 01:58:40.000000000","message":"I don\u0027t see where we convert all ValidationErrors to HTTP 400s. Like PolicyNotAuthorized are converted into 401s as described in the note above.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"09d454c17998ca1669b8a66ec7f374e03b7f475c","unresolved":false,"context_lines":[{"line_number":482,"context_line":"                    # calls. ResourceExceptionHandler silently"},{"line_number":483,"context_line":"                    # converts NotAuthorized to HTTPForbidden"},{"line_number":484,"context_line":"                    raise"},{"line_number":485,"context_line":"                elif isinstance(exc, exception.ValidationError):"},{"line_number":486,"context_line":"                    # Note(oomichi): Handle a validation error, which"},{"line_number":487,"context_line":"                    # happens due to invalid API parameters, as an"},{"line_number":488,"context_line":"                    # expected error."}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FTug%3D","line":485,"in_reply_to":"AAAAQn%2F%2FUOw%3D","updated":"2013-08-02 08:30:34.000000000","message":"exception.ValidationError inherits from exception.Invalid. The code of exception.Invalid is 400, that is why exception.ValidationError is converted to HTTP 400.\n\n 212 class Invalid(NovaException):\n 213     msg_fmt \u003d _(\"Unacceptable parameters.\")\n 214     code \u003d 400","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"6b8f5a8efea9d256e2d6f17ac4854e1976111d25","unresolved":false,"context_lines":[{"line_number":483,"context_line":"                    # calls. ResourceExceptionHandler silently"},{"line_number":484,"context_line":"                    # converts NotAuthorized to HTTPForbidden"},{"line_number":485,"context_line":"                    raise"},{"line_number":486,"context_line":"                elif isinstance(exc, exception.ValidationError):"},{"line_number":487,"context_line":"                    # Note(oomichi): Handle a validation error, which"},{"line_number":488,"context_line":"                    # happens due to invalid API parameters, as an"},{"line_number":489,"context_line":"                    # expected error."}],"source_content_type":"text/x-python","patch_set":45,"id":"AAAATn%2F%2BlT4%3D","line":486,"updated":"2013-11-22 20:13:00.000000000","message":"You could combine this with the previous elif:\n\n    elif isinstance(exc, (exception.PolicyNotAuthorized, exception.ValidationError)):\n        raise","commit_id":"f2b87f80ac4308764ba37b8a50530bf59f4b439c"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"93d207257c1064f762be0ef8ed601659bed279c5","unresolved":false,"context_lines":[{"line_number":483,"context_line":"                    # calls. ResourceExceptionHandler silently"},{"line_number":484,"context_line":"                    # converts NotAuthorized to HTTPForbidden"},{"line_number":485,"context_line":"                    raise"},{"line_number":486,"context_line":"                elif isinstance(exc, exception.ValidationError):"},{"line_number":487,"context_line":"                    # Note(oomichi): Handle a validation error, which"},{"line_number":488,"context_line":"                    # happens due to invalid API parameters, as an"},{"line_number":489,"context_line":"                    # expected error."}],"source_content_type":"text/x-python","patch_set":45,"id":"AAAATn%2F%2BdUA%3D","line":486,"in_reply_to":"AAAATn%2F%2Bj4M%3D","updated":"2013-11-25 20:40:45.000000000","message":"Indeed, which is why I say you \"could\" combine :)","commit_id":"f2b87f80ac4308764ba37b8a50530bf59f4b439c"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"b41189067bc56e6b803eaf21e5eda77adca35f95","unresolved":false,"context_lines":[{"line_number":483,"context_line":"                    # calls. ResourceExceptionHandler silently"},{"line_number":484,"context_line":"                    # converts NotAuthorized to HTTPForbidden"},{"line_number":485,"context_line":"                    raise"},{"line_number":486,"context_line":"                elif isinstance(exc, exception.ValidationError):"},{"line_number":487,"context_line":"                    # Note(oomichi): Handle a validation error, which"},{"line_number":488,"context_line":"                    # happens due to invalid API parameters, as an"},{"line_number":489,"context_line":"                    # expected error."}],"source_content_type":"text/x-python","patch_set":45,"id":"AAAATn%2F%2Bj4M%3D","line":486,"in_reply_to":"AAAATn%2F%2BlT4%3D","updated":"2013-11-23 12:17:48.000000000","message":"For readable comment, I feel the current implementation is better than the combination.","commit_id":"f2b87f80ac4308764ba37b8a50530bf59f4b439c"}],"nova/api/openstack/wsgi.py":[{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"b5fbfbdf51c51dae26bdaf82d8ae198ec0a3ca08","unresolved":false,"context_lines":[{"line_number":929,"context_line":"        action_args.update(contents)"},{"line_number":930,"context_line":""},{"line_number":931,"context_line":"        if hasattr(meth, \u0027validator_schema\u0027):"},{"line_number":932,"context_line":"            schema \u003d getattr(meth, \u0027validator_schema\u0027)"},{"line_number":933,"context_line":"            validator \u003d jsonschema.Draft3Validator(schema, types\u003dva.types)"},{"line_number":934,"context_line":"            try:"},{"line_number":935,"context_line":"                validator.validate(action_args[\u0027body\u0027])"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2Fzo8%3D","line":932,"updated":"2013-03-26 20:05:49.000000000","message":"Try:\n\n    schema \u003d getattr(meth, \u0027validator_schema\u0027, None)\n    if schema:\n        …","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"85577b270f32105901f1b2f9e828d59ae612dad7","unresolved":false,"context_lines":[{"line_number":929,"context_line":"        action_args.update(contents)"},{"line_number":930,"context_line":""},{"line_number":931,"context_line":"        if hasattr(meth, \u0027validator_schema\u0027):"},{"line_number":932,"context_line":"            schema \u003d getattr(meth, \u0027validator_schema\u0027)"},{"line_number":933,"context_line":"            validator \u003d jsonschema.Draft3Validator(schema, types\u003dva.types)"},{"line_number":934,"context_line":"            try:"},{"line_number":935,"context_line":"                validator.validate(action_args[\u0027body\u0027])"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzPQ%3D","line":932,"in_reply_to":"AAAAOH%2F%2Fzo8%3D","updated":"2013-03-27 02:44:31.000000000","message":"Thanks, I will apply the above code.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"93b7724a3d3ebd4b5d72d3e285324090b377fb43","unresolved":false,"context_lines":[{"line_number":942,"context_line":"            # and the path is corresponding to API method. For example, the"},{"line_number":943,"context_line":"            # API schema of nova/api/openstack/compute/contrib/aggregates.py"},{"line_number":944,"context_line":"            # is defined in nova/api/schema/openstack/compute/contrib/aggre-"},{"line_number":945,"context_line":"            # gates.py."},{"line_number":946,"context_line":"            mod_path \u003d meth.im_class.__module__.replace(\u0027nova.api\u0027,"},{"line_number":947,"context_line":"                                                        \u0027nova.api.schema\u0027)"},{"line_number":948,"context_line":"            cls_name \u003d meth.im_class.__name__"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAOn%2F%2Fr08%3D","line":945,"updated":"2013-04-29 08:27:30.000000000","message":"For a new API(nova v3 API, etc), developers will be able to use this framework only by creating API schema in nova/api/schema/...\n\nIs there the other API schema path for implementing a new API schema?","commit_id":"c67ef38de3e174efe12dd052e1efffe82c1b1928"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"3d75f966da8b41499b59fb1858d71daa73a35773","unresolved":false,"context_lines":[{"line_number":953,"context_line":"                schema \u003d getattr(cls, meth_name)"},{"line_number":954,"context_line":"            except (ImportError, AttributeError):"},{"line_number":955,"context_line":"                schema \u003d False"},{"line_number":956,"context_line":"            setattr(meth.__func__, \u0027validator_schema\u0027, schema)"},{"line_number":957,"context_line":""},{"line_number":958,"context_line":"        if schema:"},{"line_number":959,"context_line":"            validator \u003d api_validator.APIValidator(schema)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAOn%2F%2Fnw0%3D","line":956,"updated":"2013-05-01 16:17:22.000000000","message":"I\u0027m not sure what to suggest as an alternative, but there\u0027s far too much magic here\n\nAt the very least, this schema locating magic should be moved into its own toplevel function or something","commit_id":"a69f6f8040b3aa45759df8e8d197c5ada1a57dd6"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"2a3b4cb071df9fcc4f4f343b4364acfa3ea72203","unresolved":false,"context_lines":[{"line_number":953,"context_line":"                schema \u003d getattr(cls, meth_name)"},{"line_number":954,"context_line":"            except (ImportError, AttributeError):"},{"line_number":955,"context_line":"                schema \u003d False"},{"line_number":956,"context_line":"            setattr(meth.__func__, \u0027validator_schema\u0027, schema)"},{"line_number":957,"context_line":""},{"line_number":958,"context_line":"        if schema:"},{"line_number":959,"context_line":"            validator \u003d api_validator.APIValidator(schema)"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAOn%2F%2FmD4%3D","line":956,"in_reply_to":"AAAAOn%2F%2Fnw0%3D","updated":"2013-05-02 15:05:49.000000000","message":"Here is just one idea, and now I feel \u0027magic\u0027 is right word.\nI will define schema into its own function.","commit_id":"a69f6f8040b3aa45759df8e8d197c5ada1a57dd6"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"3d75f966da8b41499b59fb1858d71daa73a35773","unresolved":false,"context_lines":[{"line_number":959,"context_line":"            validator \u003d api_validator.APIValidator(schema)"},{"line_number":960,"context_line":"            try:"},{"line_number":961,"context_line":"                validator.validate(action_args[\u0027body\u0027])"},{"line_number":962,"context_line":"            except exception.ValidationError as ex:"},{"line_number":963,"context_line":"                msg \u003d _(\"Request validation failure: %s\") % ex.args[0]"},{"line_number":964,"context_line":"                return Fault(webob.exc.HTTPBadRequest(explanation\u003dmsg))"},{"line_number":965,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAOn%2F%2Fnwo%3D","line":962,"updated":"2013-05-01 16:17:22.000000000","message":"Hmm, will the validator raise a nova.exception.ValidationError or a nova.openstack.common.exception.ValidationError?","commit_id":"a69f6f8040b3aa45759df8e8d197c5ada1a57dd6"},{"author":{"_account_id":7203,"name":"yuuichi fujioka","email":"fujioka.yuuichi@gmail.com","username":"FujiokaYuuichi"},"change_message_id":"3eb3f0097b68ab8b376646ae80379d66d7329a2a","unresolved":false,"context_lines":[{"line_number":1278,"context_line":""},{"line_number":1279,"context_line":""},{"line_number":1280,"context_line":"def validator(request_body_schema):"},{"line_number":1281,"context_line":"    def decorator(func, **kwargs):"},{"line_number":1282,"context_line":"        func.request_body_schema \u003d request_body_schema"},{"line_number":1283,"context_line":"        return func"},{"line_number":1284,"context_line":"    return decorator"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAPn%2F%2Fy7o%3D","line":1281,"updated":"2013-06-21 04:28:00.000000000","message":"I think kwargs is not necessary.","commit_id":"761b291e06aef14885dc89b2f2b4e636da38131d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"c59189fc66deac525aba0f66e85aadd41f44849c","unresolved":false,"context_lines":[{"line_number":1278,"context_line":""},{"line_number":1279,"context_line":""},{"line_number":1280,"context_line":"def validator(request_body_schema):"},{"line_number":1281,"context_line":"    def decorator(func, **kwargs):"},{"line_number":1282,"context_line":"        func.request_body_schema \u003d request_body_schema"},{"line_number":1283,"context_line":"        return func"},{"line_number":1284,"context_line":"    return decorator"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAPn%2F%2Fy0U%3D","line":1281,"in_reply_to":"AAAAPn%2F%2Fy7o%3D","updated":"2013-06-21 04:52:19.000000000","message":"I see, thanks.","commit_id":"761b291e06aef14885dc89b2f2b4e636da38131d"},{"author":{"_account_id":7203,"name":"yuuichi fujioka","email":"fujioka.yuuichi@gmail.com","username":"FujiokaYuuichi"},"change_message_id":"3eb3f0097b68ab8b376646ae80379d66d7329a2a","unresolved":false,"context_lines":[{"line_number":1279,"context_line":""},{"line_number":1280,"context_line":"def validator(request_body_schema):"},{"line_number":1281,"context_line":"    def decorator(func, **kwargs):"},{"line_number":1282,"context_line":"        func.request_body_schema \u003d request_body_schema"},{"line_number":1283,"context_line":"        return func"},{"line_number":1284,"context_line":"    return decorator"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAPn%2F%2Fy64%3D","line":1282,"updated":"2013-06-21 04:28:00.000000000","message":"How about creating api_validator.APIValidator instance here?\nIf doing it, we don\u0027t need to create the instance per request.","commit_id":"761b291e06aef14885dc89b2f2b4e636da38131d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"c59189fc66deac525aba0f66e85aadd41f44849c","unresolved":false,"context_lines":[{"line_number":1279,"context_line":""},{"line_number":1280,"context_line":"def validator(request_body_schema):"},{"line_number":1281,"context_line":"    def decorator(func, **kwargs):"},{"line_number":1282,"context_line":"        func.request_body_schema \u003d request_body_schema"},{"line_number":1283,"context_line":"        return func"},{"line_number":1284,"context_line":"    return decorator"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAPn%2F%2Fy0Q%3D","line":1282,"in_reply_to":"AAAAPn%2F%2Fy64%3D","updated":"2013-06-21 04:52:19.000000000","message":"Good idea, I will apply it also to next patch.","commit_id":"761b291e06aef14885dc89b2f2b4e636da38131d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0130ecff5ed466d48dc2bda4ffd7d0341485eef3","unresolved":false,"context_lines":[{"line_number":959,"context_line":"                    action_result \u003d self.dispatch(meth, request, action_args)"},{"line_number":960,"context_line":"            except jsonschema.ValidationError as ex:"},{"line_number":961,"context_line":"                msg \u003d _(\"Request validation failure: %s\") % ex.message"},{"line_number":962,"context_line":"                return Fault(webob.exc.HTTPBadRequest(explanation\u003dmsg))"},{"line_number":963,"context_line":"            except Fault as ex:"},{"line_number":964,"context_line":"                response \u003d ex"},{"line_number":965,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2Fnmc%3D","line":962,"updated":"2013-06-26 17:35:19.000000000","message":"this feels bad, should your validator not just return the appropriate Fault exception with the correct response code?","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"3df9e6178ce0815d23b8f72404e90060464daa17","unresolved":false,"context_lines":[{"line_number":959,"context_line":"                    action_result \u003d self.dispatch(meth, request, action_args)"},{"line_number":960,"context_line":"            except jsonschema.ValidationError as ex:"},{"line_number":961,"context_line":"                msg \u003d _(\"Request validation failure: %s\") % ex.message"},{"line_number":962,"context_line":"                return Fault(webob.exc.HTTPBadRequest(explanation\u003dmsg))"},{"line_number":963,"context_line":"            except Fault as ex:"},{"line_number":964,"context_line":"                response \u003d ex"},{"line_number":965,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FlTA%3D","line":962,"in_reply_to":"AAAAPn%2F%2Fldw%3D","updated":"2013-06-27 10:52:21.000000000","message":"Awesome! so we don\u0027t need any changes of wsgi.py.\nThat is very very good for me, because this patch does not depend on WSGI.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"91e9ca883d8f50b78a8a415e81d753964f123763","unresolved":false,"context_lines":[{"line_number":959,"context_line":"                    action_result \u003d self.dispatch(meth, request, action_args)"},{"line_number":960,"context_line":"            except jsonschema.ValidationError as ex:"},{"line_number":961,"context_line":"                msg \u003d _(\"Request validation failure: %s\") % ex.message"},{"line_number":962,"context_line":"                return Fault(webob.exc.HTTPBadRequest(explanation\u003dmsg))"},{"line_number":963,"context_line":"            except Fault as ex:"},{"line_number":964,"context_line":"                response \u003d ex"},{"line_number":965,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2Fldw%3D","line":962,"in_reply_to":"AAAAPn%2F%2FmLQ%3D","updated":"2013-06-27 09:31:35.000000000","message":"I think exception.ValidationException would just inherit from Fault, and stuff will work without any special code here.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"6291c2869979617ca2aa6bfc5af651d176b933e5","unresolved":false,"context_lines":[{"line_number":959,"context_line":"                    action_result \u003d self.dispatch(meth, request, action_args)"},{"line_number":960,"context_line":"            except jsonschema.ValidationError as ex:"},{"line_number":961,"context_line":"                msg \u003d _(\"Request validation failure: %s\") % ex.message"},{"line_number":962,"context_line":"                return Fault(webob.exc.HTTPBadRequest(explanation\u003dmsg))"},{"line_number":963,"context_line":"            except Fault as ex:"},{"line_number":964,"context_line":"                response \u003d ex"},{"line_number":965,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FmLQ%3D","line":962,"in_reply_to":"AAAAPn%2F%2Fnmc%3D","updated":"2013-06-27 03:49:27.000000000","message":"I feel webob exception should be returned here as I say at api_validator.py.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"}],"nova/api/schema/__init__.py":[{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"c08457243de239ffb7de78fa8918726b22b50868","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Copyright 2013 NEC Corporation.  All rights reserved."},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAPX%2F%2F6qg%3D","line":1,"updated":"2013-06-06 01:51:14.000000000","message":"very minor nit - I don\u0027t think we need copyright or licence headers in completely empty files :-)","commit_id":"be2b849a0e26d5601815c50215cd88adde25d6fa"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"e5e8aeef79de67f5856d51a8d6178d1ffc080b92","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Copyright 2013 NEC Corporation.  All rights reserved."},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAPX%2F%2F6cA%3D","line":1,"in_reply_to":"AAAAPX%2F%2F6qg%3D","updated":"2013-06-06 04:54:23.000000000","message":"Nice catch, thanks.\nI will make this file empty.","commit_id":"be2b849a0e26d5601815c50215cd88adde25d6fa"}],"nova/api/validation/__init__.py":[{"author":{"_account_id":5652,"name":"David Ripton","email":"dripton@redhat.com","username":"dripton"},"change_message_id":"ae66b48b52593a6f395488f6f3fae0fa4b75dc60","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"\"\"\""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"import functools"},{"line_number":22,"context_line":"from validators import _SchemaValidator"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"AAAATn%2F%2B0n4%3D","line":21,"updated":"2013-11-19 17:48:28.000000000","message":"newline between these, as functools is builtin and validators is not","commit_id":"569b691d52ff1e574e7b7fb224767bb9a779971f"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"250254f2cb94b1db48436d16d852380f4bead933","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"\"\"\""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"import functools"},{"line_number":22,"context_line":"from validators import _SchemaValidator"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""}],"source_content_type":"text/x-python","patch_set":44,"id":"AAAATn%2F%2BzX8%3D","line":21,"in_reply_to":"AAAATn%2F%2B0n4%3D","updated":"2013-11-19 23:39:04.000000000","message":"You are right, thanks.\nI will add it.","commit_id":"569b691d52ff1e574e7b7fb224767bb9a779971f"}],"nova/api/validation/validators.py":[{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"c60f74d84587780aa685748fca979681ac13f86e","unresolved":false,"context_lines":[{"line_number":25,"context_line":"from nova.openstack.common import uuidutils"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"@jsonschema.FormatChecker.cls_checks(\u0027integer\u0027)"},{"line_number":29,"context_line":"def _validate_integer_format(instance):"},{"line_number":30,"context_line":"    try:"},{"line_number":31,"context_line":"        int(instance)"}],"source_content_type":"text/x-python","patch_set":46,"id":"AAAATn%2F%2Bjd4%3D","line":28,"updated":"2013-11-23 21:36:10.000000000","message":"better to use a pattern [0-9] instead of implementing original checker.","commit_id":"9e7a3708d26a70a1e471416bab9aacc27498c4ec"}],"nova/api/validator.py":[{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"b5fbfbdf51c51dae26bdaf82d8ae198ec0a3ca08","unresolved":false,"context_lines":[{"line_number":138,"context_line":"    return True"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"class stringIntegerMeta(type):"},{"line_number":142,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":143,"context_line":"        try:"},{"line_number":144,"context_line":"            int(instance)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2Fzoo%3D","line":141,"updated":"2013-03-26 20:05:49.000000000","message":"Why are all these classes defined with a leading lower-cased letter?  Is there some reason we can\u0027t be consistent with the rest of nova and capitalize the first letter on class names, e.g., StringIntegerMeta?  For that matter, is there a reason these have to be classes with metaclasses; is it possible to just use functions?  Just trying to understand the rationale…","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"093bd873416cbbc62eff0276c6de7718c283fa77","unresolved":false,"context_lines":[{"line_number":138,"context_line":"    return True"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"class stringIntegerMeta(type):"},{"line_number":142,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":143,"context_line":"        try:"},{"line_number":144,"context_line":"            int(instance)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FyQs%3D","line":141,"in_reply_to":"AAAAOH%2F%2FySU%3D","updated":"2013-03-27 15:59:59.000000000","message":"ABCMeta does override __instancecheck__(), but I\u0027ll readily admit I haven\u0027t looked closely enough to know if it really would be useful here, as that might be a moot point.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"0bca8fcc9f72a6d5a37a3dc869caef1943ecd265","unresolved":false,"context_lines":[{"line_number":138,"context_line":"    return True"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"class stringIntegerMeta(type):"},{"line_number":142,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":143,"context_line":"        try:"},{"line_number":144,"context_line":"            int(instance)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FySU%3D","line":141,"in_reply_to":"AAAAOH%2F%2FyUs%3D","updated":"2013-03-27 15:50:31.000000000","message":"abc is good for flexible issubclass checking, not isinstance. We\u0027re verifying not types but values here.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"4493d3b0062efa4d8f5e98f60397c69561713b3c","unresolved":false,"context_lines":[{"line_number":138,"context_line":"    return True"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"class stringIntegerMeta(type):"},{"line_number":142,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":143,"context_line":"        try:"},{"line_number":144,"context_line":"            int(instance)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FyUs%3D","line":141,"in_reply_to":"AAAAOH%2F%2FzIY%3D","updated":"2013-03-27 15:37:42.000000000","message":"OK.  I\u0027ll also point out the abc module, which may or may not be helpful for this kind of thing…you can register types to be subclasses of other classes without inheritance relationships.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"57781c729d4289a029ce0054b571559f5bb00939","unresolved":false,"context_lines":[{"line_number":138,"context_line":"    return True"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"class stringIntegerMeta(type):"},{"line_number":142,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":143,"context_line":"        try:"},{"line_number":144,"context_line":"            int(instance)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzIY%3D","line":141,"in_reply_to":"AAAAOH%2F%2FzJY%3D","updated":"2013-03-27 02:55:16.000000000","message":"\u003e\u003e is there a reason these have to be classes with metaclasses.\n\nNow I find the first Yuriy\u0027s comment, and I understand the above comment maybe.\nSorry for my noise, and I will try to implement without class.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"85577b270f32105901f1b2f9e828d59ae612dad7","unresolved":false,"context_lines":[{"line_number":138,"context_line":"    return True"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"class stringIntegerMeta(type):"},{"line_number":142,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":143,"context_line":"        try:"},{"line_number":144,"context_line":"            int(instance)"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzJY%3D","line":141,"in_reply_to":"AAAAOH%2F%2Fzoo%3D","updated":"2013-03-27 02:44:31.000000000","message":"OK, I will change class names to a leading big-cased letter.\n\n\u003e  is there a reason these have to be classes with metaclasses.\n\nIn the JSON Schema library, the type validation is implemented by the isinstance() method.\nisinstance() calls the meta class\u0027s __instancecheck__() method.\nSo we definined both the meta class and type class.\nhttps://wiki.openstack.org/wiki/NovaApiValidationFramework#API_parameter_type\n\nSorry if I misunderstand your comment.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"49a559c31e899d5463700e202458f033381fac16","unresolved":false,"context_lines":[{"line_number":142,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":143,"context_line":"        try:"},{"line_number":144,"context_line":"            int(instance)"},{"line_number":145,"context_line":"        except Exception:"},{"line_number":146,"context_line":"            return False"},{"line_number":147,"context_line":"        return True"},{"line_number":148,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FziM%3D","line":145,"updated":"2013-03-26 20:47:08.000000000","message":"Catch specific ValueError exception not the generic Exception.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"85577b270f32105901f1b2f9e828d59ae612dad7","unresolved":false,"context_lines":[{"line_number":142,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":143,"context_line":"        try:"},{"line_number":144,"context_line":"            int(instance)"},{"line_number":145,"context_line":"        except Exception:"},{"line_number":146,"context_line":"            return False"},{"line_number":147,"context_line":"        return True"},{"line_number":148,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzOc%3D","line":145,"in_reply_to":"AAAAOH%2F%2FziM%3D","updated":"2013-03-27 02:44:31.000000000","message":"Thanks, I will apply the above comment to other code also.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"49a559c31e899d5463700e202458f033381fac16","unresolved":false,"context_lines":[{"line_number":153,"context_line":"            #NOTE(oomichi): To support a string integer such as \"10\", use"},{"line_number":154,"context_line":"            #               int(instance) instead of isinstance(instance, int)."},{"line_number":155,"context_line":"            int(instance)"},{"line_number":156,"context_line":"            return True"},{"line_number":157,"context_line":"        except Exception:"},{"line_number":158,"context_line":"            pass"},{"line_number":159,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2Fziw%3D","line":156,"updated":"2013-03-26 20:47:08.000000000","message":"Minimize try: block, move \"return True\" to else: branch.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"85577b270f32105901f1b2f9e828d59ae612dad7","unresolved":false,"context_lines":[{"line_number":153,"context_line":"            #NOTE(oomichi): To support a string integer such as \"10\", use"},{"line_number":154,"context_line":"            #               int(instance) instead of isinstance(instance, int)."},{"line_number":155,"context_line":"            int(instance)"},{"line_number":156,"context_line":"            return True"},{"line_number":157,"context_line":"        except Exception:"},{"line_number":158,"context_line":"            pass"},{"line_number":159,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzNU%3D","line":156,"in_reply_to":"AAAAOH%2F%2Fziw%3D","updated":"2013-03-27 02:44:31.000000000","message":"OK, I will move \"return True\" to else: branch. also other code.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"49a559c31e899d5463700e202458f033381fac16","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        if validate_image_path(instance):"},{"line_number":167,"context_line":"            return True"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        return False"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"class boolOrStringMeta(type):"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FziY%3D","line":169,"updated":"2013-03-26 20:47:08.000000000","message":"Make this a simple\n\n    return validate_image_path(instance)","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"85577b270f32105901f1b2f9e828d59ae612dad7","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        if validate_image_path(instance):"},{"line_number":167,"context_line":"            return True"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        return False"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"class boolOrStringMeta(type):"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzO4%3D","line":169,"in_reply_to":"AAAAOH%2F%2FziY%3D","updated":"2013-03-27 02:44:31.000000000","message":"Thanks. will apply.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"49a559c31e899d5463700e202458f033381fac16","unresolved":false,"context_lines":[{"line_number":171,"context_line":""},{"line_number":172,"context_line":"class boolOrStringMeta(type):"},{"line_number":173,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":174,"context_line":"        if isinstance(instance, bool) or isinstance(instance, str):"},{"line_number":175,"context_line":"            return True"},{"line_number":176,"context_line":"        return False"},{"line_number":177,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzjA%3D","line":174,"updated":"2013-03-26 20:47:08.000000000","message":"Unite these to\n\n    return isinstance(instance, (bool, str))","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"85577b270f32105901f1b2f9e828d59ae612dad7","unresolved":false,"context_lines":[{"line_number":171,"context_line":""},{"line_number":172,"context_line":"class boolOrStringMeta(type):"},{"line_number":173,"context_line":"    def __instancecheck__(self, instance):"},{"line_number":174,"context_line":"        if isinstance(instance, bool) or isinstance(instance, str):"},{"line_number":175,"context_line":"            return True"},{"line_number":176,"context_line":"        return False"},{"line_number":177,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2FzPA%3D","line":174,"in_reply_to":"AAAAOH%2F%2FzjA%3D","updated":"2013-03-27 02:44:31.000000000","message":"will apply.","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"b5fbfbdf51c51dae26bdaf82d8ae198ec0a3ca08","unresolved":false,"context_lines":[{"line_number":269,"context_line":"    \u0027uuidWithHyphen\u0027: uuidWithHyphen,"},{"line_number":270,"context_line":"    \u0027networkUuid\u0027: networkUuid"},{"line_number":271,"context_line":"}"},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAOH%2F%2Fzok%3D","line":272,"updated":"2013-03-26 20:05:49.000000000","message":"You have a blank line at the end of this file…","commit_id":"db72adba38196724ddded1a3aa616d9b5bc23933"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"358be038d37272a9f0da6b574b95e4b89dc04cb4","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        int(instance)"},{"line_number":154,"context_line":"    except ValueError:"},{"line_number":155,"context_line":"        return False"},{"line_number":156,"context_line":"    return True"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"@validated_type"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAOH%2F%2Fw%2Bg%3D","line":156,"updated":"2013-03-28 13:28:36.000000000","message":"I personally see else: branch more readable than this.","commit_id":"a130dcf6ad50337fdf0fd7fee1de19260fa05b55"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4d459682f16c8a88f607a15053cad1b5b0659097","unresolved":false,"context_lines":[{"line_number":153,"context_line":"        int(instance)"},{"line_number":154,"context_line":"    except ValueError:"},{"line_number":155,"context_line":"        return False"},{"line_number":156,"context_line":"    return True"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"@validated_type"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAOH%2F%2Fw9M%3D","line":156,"in_reply_to":"AAAAOH%2F%2Fw%2Bg%3D","updated":"2013-03-28 14:08:31.000000000","message":"Thanks, I will apply it to hear and other place.","commit_id":"a130dcf6ad50337fdf0fd7fee1de19260fa05b55"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"358be038d37272a9f0da6b574b95e4b89dc04cb4","unresolved":false,"context_lines":[{"line_number":160,"context_line":"def validate_uuid(instance):"},{"line_number":161,"context_line":"    try:"},{"line_number":162,"context_line":"        uuid.UUID(instance)"},{"line_number":163,"context_line":"    except (ValueError, AttributeError):"},{"line_number":164,"context_line":"        return False"},{"line_number":165,"context_line":"    return True"},{"line_number":166,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAOH%2F%2Fw%2Bk%3D","line":163,"updated":"2013-03-28 13:28:36.000000000","message":"Why catching AttributeError here?","commit_id":"a130dcf6ad50337fdf0fd7fee1de19260fa05b55"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4d459682f16c8a88f607a15053cad1b5b0659097","unresolved":false,"context_lines":[{"line_number":160,"context_line":"def validate_uuid(instance):"},{"line_number":161,"context_line":"    try:"},{"line_number":162,"context_line":"        uuid.UUID(instance)"},{"line_number":163,"context_line":"    except (ValueError, AttributeError):"},{"line_number":164,"context_line":"        return False"},{"line_number":165,"context_line":"    return True"},{"line_number":166,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAOH%2F%2Fw9Y%3D","line":163,"in_reply_to":"AAAAOH%2F%2Fw%2Bk%3D","updated":"2013-03-28 14:08:31.000000000","message":"For \u0027int\u0027 instance.","commit_id":"a130dcf6ad50337fdf0fd7fee1de19260fa05b55"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"358be038d37272a9f0da6b574b95e4b89dc04cb4","unresolved":false,"context_lines":[{"line_number":180,"context_line":""},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"@validated_type"},{"line_number":183,"context_line":"def validate_network_uuid(self, instance):"},{"line_number":184,"context_line":"    if uuidutils.is_uuid_like(instance):"},{"line_number":185,"context_line":"        return True"},{"line_number":186,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAOH%2F%2Fw%2Bo%3D","line":183,"updated":"2013-03-28 13:28:36.000000000","message":"I guess, self is not needed here.","commit_id":"a130dcf6ad50337fdf0fd7fee1de19260fa05b55"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4d459682f16c8a88f607a15053cad1b5b0659097","unresolved":false,"context_lines":[{"line_number":180,"context_line":""},{"line_number":181,"context_line":""},{"line_number":182,"context_line":"@validated_type"},{"line_number":183,"context_line":"def validate_network_uuid(self, instance):"},{"line_number":184,"context_line":"    if uuidutils.is_uuid_like(instance):"},{"line_number":185,"context_line":"        return True"},{"line_number":186,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAOH%2F%2Fw9Q%3D","line":183,"in_reply_to":"AAAAOH%2F%2Fw%2Bo%3D","updated":"2013-03-28 14:08:31.000000000","message":"nice catch, thanks!","commit_id":"a130dcf6ad50337fdf0fd7fee1de19260fa05b55"}],"nova/openstack/common/api_validator.py":[{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"3d75f966da8b41499b59fb1858d71daa73a35773","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import jsonschema"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from nova import exception"},{"line_number":21,"context_line":"from nova.openstack.common import uuidutils"},{"line_number":22,"context_line":"from nova import utils"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAOn%2F%2FnwU%3D","line":20,"updated":"2013-05-01 16:17:22.000000000","message":"Ah, I see :-)\n\nCode imported from oslo-incubator should be imported by doing:\n\n  $\u003e python update.py --base nova --dest-dir ../nova --module api_validator\n\nPlease don\u0027t make manual changes to the files","commit_id":"a69f6f8040b3aa45759df8e8d197c5ada1a57dd6"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"2a3b4cb071df9fcc4f4f343b4364acfa3ea72203","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import jsonschema"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from nova import exception"},{"line_number":21,"context_line":"from nova.openstack.common import uuidutils"},{"line_number":22,"context_line":"from nova import utils"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAOn%2F%2FmCk%3D","line":20,"in_reply_to":"AAAAOn%2F%2FnwU%3D","updated":"2013-05-02 15:05:49.000000000","message":"Thanks for your advice.\nI will do it next time;-)","commit_id":"a69f6f8040b3aa45759df8e8d197c5ada1a57dd6"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"c5a716de2d81bbeb91b68d65999fbb59ead163dc","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        #                string number."},{"line_number":48,"context_line":"        try:"},{"line_number":49,"context_line":"            value \u003d int(instance)"},{"line_number":50,"context_line":"        except ValueError:"},{"line_number":51,"context_line":"            value \u003d float(instance)"},{"line_number":52,"context_line":"        return value"},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAOn%2F%2FV9g%3D","line":50,"updated":"2013-05-14 04:47:37.000000000","message":"Missing TypeError: \n\n    except (ValueError, TypeError):","commit_id":"b3988d0d5c0b8626e980033ed7b9402a8bf8ecd2"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4322790474f50ddba952c3ca7ceb008a10b40e73","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        #                string number."},{"line_number":48,"context_line":"        try:"},{"line_number":49,"context_line":"            value \u003d int(instance)"},{"line_number":50,"context_line":"        except ValueError:"},{"line_number":51,"context_line":"            value \u003d float(instance)"},{"line_number":52,"context_line":"        return value"},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAOn%2F%2FV8g%3D","line":50,"in_reply_to":"AAAAOn%2F%2FV9g%3D","updated":"2013-05-14 05:08:13.000000000","message":"Nice catch, thanks.","commit_id":"b3988d0d5c0b8626e980033ed7b9402a8bf8ecd2"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"c66ecc282aa55abc51e075c2ca4b0af7b881be92","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        try:"},{"line_number":49,"context_line":"            value \u003d int(instance)"},{"line_number":50,"context_line":"        except (ValueError, TypeError):"},{"line_number":51,"context_line":"            value \u003d float(instance)"},{"line_number":52,"context_line":"        return value"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FV6Q%3D","line":51,"updated":"2013-05-14 05:31:10.000000000","message":"float() can also raise the same error as int().","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"c66ecc282aa55abc51e075c2ca4b0af7b881be92","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":55,"context_line":"        try:"},{"line_number":56,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            return"},{"line_number":59,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":60,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FV6E%3D","line":57,"updated":"2013-05-14 05:31:10.000000000","message":"already done on line 50 unless your trying to catch the exception that it\u0027s a float :) ..","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"fd5605529f65bf502d7083729eff0950adbb15e9","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":55,"context_line":"        try:"},{"line_number":56,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            return"},{"line_number":59,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":60,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FVzA%3D","line":57,"in_reply_to":"AAAAOn%2F%2FV0A%3D","updated":"2013-05-14 06:31:15.000000000","message":"Is the following OK?\n\ndef _number_from_str(self, instance):\n    try:\n        value \u003d int(instance)\n    except (ValueError, TypeError):\n        try:\n            value \u003d float(instance)\n        except (ValueError, TypeError):\n            return None\n    return value\n\ndef validate_minimum(self, minimum, instance, schema):\n    value \u003d self._number_from_str(instance)\n    if value is None:\n        return\n    return super(APIValidator, self).validate_minimum(minimum, value, schema)","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"ac7d1a65665382e90486d6d737e73443417fe70b","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":55,"context_line":"        try:"},{"line_number":56,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            return"},{"line_number":59,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":60,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FV0A%3D","line":57,"in_reply_to":"AAAAOn%2F%2FV4c%3D","updated":"2013-05-14 06:05:20.000000000","message":"It\u0027s odd that _num_from_str() raises an exception. Line 57 makes more sense after line 51 (followed by a return).","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"21962857ff1cd79c370aa3cb75568cce37371104","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":55,"context_line":"        try:"},{"line_number":56,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            return"},{"line_number":59,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":60,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FV4c%3D","line":57,"in_reply_to":"AAAAOn%2F%2FV6E%3D","updated":"2013-05-14 05:45:05.000000000","message":"I added this except for catching float() error.\nI\u0027m sorry if I misunderstand your point.","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"3671074b75fb26c9f434349c99bf2d885f10d045","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":55,"context_line":"        try:"},{"line_number":56,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            return"},{"line_number":59,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":60,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAO3%2F%2F89U%3D","line":57,"in_reply_to":"AAAAOn%2F%2FVw8%3D","updated":"2013-05-16 09:31:15.000000000","message":"if a value is 0, validate_minimum() is not operated.\n\n    if value:\n        return super(APIValidator, self).validate_minimum(minimum, value, schema)","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"15075c06dcbcb5a9b57d2bf54ab6db9c0cc09dd1","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":55,"context_line":"        try:"},{"line_number":56,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            return"},{"line_number":59,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":60,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FVw8%3D","line":57,"in_reply_to":"AAAAOn%2F%2FVxk%3D","updated":"2013-05-15 22:39:18.000000000","message":"http://codepad.org/v7DsoGDQ","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"20c0cf8c2ec7a178fff8cd0b021c0565d98515cb","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":55,"context_line":"        try:"},{"line_number":56,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            return"},{"line_number":59,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":60,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FVxk%3D","line":57,"in_reply_to":"AAAAOn%2F%2FVyE%3D","updated":"2013-05-14 06:40:50.000000000","message":"In the above code, we cannot check value \u00270\u0027.","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"b0f102122223827ee478464f9e3ae7d78fb0e95e","unresolved":false,"context_lines":[{"line_number":54,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":55,"context_line":"        try:"},{"line_number":56,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":57,"context_line":"        except (ValueError, TypeError):"},{"line_number":58,"context_line":"            return"},{"line_number":59,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":60,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FVyE%3D","line":57,"in_reply_to":"AAAAOn%2F%2FVzA%3D","updated":"2013-05-14 06:35:13.000000000","message":"def _number_from_str(self, instance):\n    try:\n        value \u003d int(instance)\n    except (ValueError, TypeError):\n        try:\n            value \u003d float(instance)\n        except (ValueError, TypeError):\n            return\n    return value\n\ndef validate_minimum(self, minimum, instance, schema):\n    value \u003d self._number_from_str(instance)\n    if value:\n        return super(APIValidator, self).validate_minimum(minimum, value, schema)","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"c66ecc282aa55abc51e075c2ca4b0af7b881be92","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def validate_maximum(self, maximum, instance, schema):"},{"line_number":63,"context_line":"        try:"},{"line_number":64,"context_line":"            value \u003d self._number_from_str(instance)"},{"line_number":65,"context_line":"        except (ValueError, TypeError):"},{"line_number":66,"context_line":"            return"},{"line_number":67,"context_line":"        return super(APIValidator, self).validate_maximum(maximum,"},{"line_number":68,"context_line":"                                                          value, schema)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAOn%2F%2FV54%3D","line":65,"updated":"2013-05-14 05:31:10.000000000","message":"ditto.","commit_id":"94fa0b53041e76f5a38492f24776ad30263c7be4"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"18099b6246f82a157256155d8700ae233b457e9e","unresolved":false,"context_lines":[{"line_number":24,"context_line":"def validate_integer_format(instance):"},{"line_number":25,"context_line":"    try:"},{"line_number":26,"context_line":"        int(instance)"},{"line_number":27,"context_line":"    except ValueError:"},{"line_number":28,"context_line":"        return False"},{"line_number":29,"context_line":"    else:"},{"line_number":30,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAO3%2F%2F93c%3D","line":27,"updated":"2013-05-15 22:44:11.000000000","message":"again... except (ValueError, TypeError):","commit_id":"5213acc3f5bfbd2defba4754864ba3631adbb4eb"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"5a4c7e1150cfab65c8bb36dae752eacfa8d7ca59","unresolved":false,"context_lines":[{"line_number":24,"context_line":"def validate_integer_format(instance):"},{"line_number":25,"context_line":"    try:"},{"line_number":26,"context_line":"        int(instance)"},{"line_number":27,"context_line":"    except ValueError:"},{"line_number":28,"context_line":"        return False"},{"line_number":29,"context_line":"    else:"},{"line_number":30,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAO3%2F%2F9s0%3D","line":27,"in_reply_to":"AAAAO3%2F%2F93c%3D","updated":"2013-05-15 23:50:30.000000000","message":"Oops, nice catch. Thanks.","commit_id":"5213acc3f5bfbd2defba4754864ba3631adbb4eb"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"18099b6246f82a157256155d8700ae233b457e9e","unresolved":false,"context_lines":[{"line_number":26,"context_line":"        int(instance)"},{"line_number":27,"context_line":"    except ValueError:"},{"line_number":28,"context_line":"        return False"},{"line_number":29,"context_line":"    else:"},{"line_number":30,"context_line":"        return True"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAO3%2F%2F93w%3D","line":29,"updated":"2013-05-15 22:44:11.000000000","message":"you don\u0027t need this else.","commit_id":"5213acc3f5bfbd2defba4754864ba3631adbb4eb"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"5a4c7e1150cfab65c8bb36dae752eacfa8d7ca59","unresolved":false,"context_lines":[{"line_number":26,"context_line":"        int(instance)"},{"line_number":27,"context_line":"    except ValueError:"},{"line_number":28,"context_line":"        return False"},{"line_number":29,"context_line":"    else:"},{"line_number":30,"context_line":"        return True"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAO3%2F%2F9sw%3D","line":29,"in_reply_to":"AAAAO3%2F%2F93w%3D","updated":"2013-05-15 23:50:30.000000000","message":"OK, I see.","commit_id":"5213acc3f5bfbd2defba4754864ba3631adbb4eb"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"18099b6246f82a157256155d8700ae233b457e9e","unresolved":false,"context_lines":[{"line_number":51,"context_line":"            try:"},{"line_number":52,"context_line":"                value \u003d float(instance)"},{"line_number":53,"context_line":"            except (ValueError, TypeError):"},{"line_number":54,"context_line":"                return None"},{"line_number":55,"context_line":"        return value"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def validate_minimum(self, minimum, instance, schema):"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAO3%2F%2F93Q%3D","line":54,"updated":"2013-05-15 22:44:11.000000000","message":"nit: None is implied: return","commit_id":"5213acc3f5bfbd2defba4754864ba3631adbb4eb"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"5a4c7e1150cfab65c8bb36dae752eacfa8d7ca59","unresolved":false,"context_lines":[{"line_number":51,"context_line":"            try:"},{"line_number":52,"context_line":"                value \u003d float(instance)"},{"line_number":53,"context_line":"            except (ValueError, TypeError):"},{"line_number":54,"context_line":"                return None"},{"line_number":55,"context_line":"        return value"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def validate_minimum(self, minimum, instance, schema):"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAO3%2F%2F9sA%3D","line":54,"in_reply_to":"AAAAO3%2F%2F93Q%3D","updated":"2013-05-15 23:50:30.000000000","message":"I see, thanks.","commit_id":"5213acc3f5bfbd2defba4754864ba3631adbb4eb"},{"author":{"_account_id":5652,"name":"David Ripton","email":"dripton@redhat.com","username":"dripton"},"change_message_id":"323e8cc0dcc706c2dccb7cff1cc4cde39c42c320","unresolved":false,"context_lines":[{"line_number":41,"context_line":"                                           format_checker\u003dformat_checker)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def _number_from_str(self, instance):"},{"line_number":44,"context_line":"        # NOTE(oomichi): Orignal validate_minimum() doesn\u0027t allow a string"},{"line_number":45,"context_line":"        #                number such as \"10\", so we need here to support a"},{"line_number":46,"context_line":"        #                string number."},{"line_number":47,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAPX%2F%2F5Jk%3D","line":44,"updated":"2013-06-06 16:10:46.000000000","message":"s/Orignal/Original/","commit_id":"a99302bf2ec27887c66c34b2ac7d3908d9234fe4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"917fb3887fc95bc6bdb7fce809ee6c9f3bfbdf81","unresolved":false,"context_lines":[{"line_number":41,"context_line":"                                           format_checker\u003dformat_checker)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def _number_from_str(self, instance):"},{"line_number":44,"context_line":"        # NOTE(oomichi): Orignal validate_minimum() doesn\u0027t allow a string"},{"line_number":45,"context_line":"        #                number such as \"10\", so we need here to support a"},{"line_number":46,"context_line":"        #                string number."},{"line_number":47,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAPX%2F%2F4Zw%3D","line":44,"in_reply_to":"AAAAPX%2F%2F5Jk%3D","updated":"2013-06-06 19:58:32.000000000","message":"I see, thanks.\nwill fix it.","commit_id":"a99302bf2ec27887c66c34b2ac7d3908d9234fe4"},{"author":{"_account_id":5652,"name":"David Ripton","email":"dripton@redhat.com","username":"dripton"},"change_message_id":"323e8cc0dcc706c2dccb7cff1cc4cde39c42c320","unresolved":false,"context_lines":[{"line_number":50,"context_line":"            try:"},{"line_number":51,"context_line":"                value \u003d float(instance)"},{"line_number":52,"context_line":"            except (ValueError, TypeError):"},{"line_number":53,"context_line":"                return"},{"line_number":54,"context_line":"        return value"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    def validate_minimum(self, minimum, instance, schema):"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAPX%2F%2F5JY%3D","line":53,"updated":"2013-06-06 16:10:46.000000000","message":"I think this should be an explicit return None, since the callers check for None.","commit_id":"a99302bf2ec27887c66c34b2ac7d3908d9234fe4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"af574d6b781168907f63954333587d5122c4180a","unresolved":false,"context_lines":[{"line_number":50,"context_line":"            try:"},{"line_number":51,"context_line":"                value \u003d float(instance)"},{"line_number":52,"context_line":"            except (ValueError, TypeError):"},{"line_number":53,"context_line":"                return"},{"line_number":54,"context_line":"        return value"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    def validate_minimum(self, minimum, instance, schema):"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAPX%2F%2FzmE%3D","line":53,"in_reply_to":"AAAAPX%2F%2F2ZY%3D","updated":"2013-06-10 07:59:11.000000000","message":"Hi Kevin, thanks for your polite explanation.\nI understand the preferred style and will change here to \"return None\".","commit_id":"a99302bf2ec27887c66c34b2ac7d3908d9234fe4"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"3cdc082f7e0e6cde04129ac957f79231deb7a6fa","unresolved":false,"context_lines":[{"line_number":50,"context_line":"            try:"},{"line_number":51,"context_line":"                value \u003d float(instance)"},{"line_number":52,"context_line":"            except (ValueError, TypeError):"},{"line_number":53,"context_line":"                return"},{"line_number":54,"context_line":"        return value"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    def validate_minimum(self, minimum, instance, schema):"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAPX%2F%2F2ZY%3D","line":53,"in_reply_to":"AAAAPX%2F%2F3zQ%3D","updated":"2013-06-07 15:55:21.000000000","message":"Not really.  What matters is how the function is used.  If the function is always called in a context where the return value is being discarded, the preferred style is simply \"return\" to interrupt execution of the function.  On the other hand, if the function is used in a context where the return value is captured—as this one is—the preference is to use an explicit \"return None\".","commit_id":"a99302bf2ec27887c66c34b2ac7d3908d9234fe4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"8e892c8e802f508dd73864e1e16f1f24d7135e6f","unresolved":false,"context_lines":[{"line_number":50,"context_line":"            try:"},{"line_number":51,"context_line":"                value \u003d float(instance)"},{"line_number":52,"context_line":"            except (ValueError, TypeError):"},{"line_number":53,"context_line":"                return"},{"line_number":54,"context_line":"        return value"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    def validate_minimum(self, minimum, instance, schema):"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAPX%2F%2F3zQ%3D","line":53,"in_reply_to":"AAAAPX%2F%2F4ZY%3D","updated":"2013-06-07 00:13:51.000000000","message":"\"return\" without None is more.\n\n /opt/stack/nova$ grep \"    return$\" * -R | wc -l\n 345\n /opt/stack/nova$ grep \"    return None$\" * -R | wc -l\n 206\n /opt/stack/nova$\n\nDoes this comparison make sense?","commit_id":"a99302bf2ec27887c66c34b2ac7d3908d9234fe4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"917fb3887fc95bc6bdb7fce809ee6c9f3bfbdf81","unresolved":false,"context_lines":[{"line_number":50,"context_line":"            try:"},{"line_number":51,"context_line":"                value \u003d float(instance)"},{"line_number":52,"context_line":"            except (ValueError, TypeError):"},{"line_number":53,"context_line":"                return"},{"line_number":54,"context_line":"        return value"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    def validate_minimum(self, minimum, instance, schema):"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAPX%2F%2F4ZY%3D","line":53,"in_reply_to":"AAAAPX%2F%2F5JY%3D","updated":"2013-06-06 19:58:32.000000000","message":"conflict..\nhttps://review.openstack.org/#/c/25358/11/nova/openstack/common/api_validator.py\n\nWhich is popular in python or openstack?","commit_id":"a99302bf2ec27887c66c34b2ac7d3908d9234fe4"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"d1bf18a8ba4620845fa129401e1c4a6b46ea7b0d","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    def validate_minimum(self, minimum, instance, schema):"},{"line_number":57,"context_line":"        value \u003d self._number_from_str(instance)"},{"line_number":58,"context_line":"        if value is None:"},{"line_number":59,"context_line":"            return"},{"line_number":60,"context_line":"        return super(APIValidator, self).validate_minimum(minimum,"},{"line_number":61,"context_line":"                                                          value, schema)"},{"line_number":62,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAPX%2F%2F3QA%3D","line":59,"updated":"2013-06-07 07:24:31.000000000","message":"I found a problem related to jsonschema library version.\n\nThe latest version is 2.0.0, and it does not have validate_minimum() and validate_maximum().\nso this operation does not work and it cannot support a string number.\n\nI feel it is a good way to add \"jsonschema\u003e\u003d1.0.0,\u003c2\" to requirements.txt, because we will be able to control the behavior of jsonschema library in the future.\nIs that wrong idea?","commit_id":"a99302bf2ec27887c66c34b2ac7d3908d9234fe4"}],"nova/tests/api/openstack/compute/plugins/v3/test_fixed_ips.py":[{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"c0faf06ab81c93f680f356263d60fbe38757edee","unresolved":false,"context_lines":[{"line_number":189,"context_line":"                          \u002710.0.0.2\u0027, body)"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def test_fixed_ip_validation_reserve(self):"},{"line_number":192,"context_line":"        resource \u003d wsgi.Resource(self.controller)"},{"line_number":193,"context_line":"        request \u003d fakes.HTTPRequest.blank("},{"line_number":194,"context_line":"            \u0027/v3/fake/os-fixed-ips/192.168.1.1/action\u0027,"},{"line_number":195,"context_line":"            body\u003d\u0027{\"reserve\": \"None\"}\u0027, method\u003d\u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAPn%2F%2Fzz0%3D","line":192,"updated":"2013-06-20 18:09:23.000000000","message":"do we really need to create the resource? I mean why not just get the response the way the others tests do like: result \u003d self.controller.action (**params**)??","commit_id":"761b291e06aef14885dc89b2f2b4e636da38131d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"914ed2f5d5d223d4d304bb4966c76d4e8992d619","unresolved":false,"context_lines":[{"line_number":189,"context_line":"                          \u002710.0.0.2\u0027, body)"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def test_fixed_ip_validation_reserve(self):"},{"line_number":192,"context_line":"        resource \u003d wsgi.Resource(self.controller)"},{"line_number":193,"context_line":"        request \u003d fakes.HTTPRequest.blank("},{"line_number":194,"context_line":"            \u0027/v3/fake/os-fixed-ips/192.168.1.1/action\u0027,"},{"line_number":195,"context_line":"            body\u003d\u0027{\"reserve\": \"None\"}\u0027, method\u003d\u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAPn%2F%2Fy2w%3D","line":192,"in_reply_to":"AAAAPn%2F%2Fzz0%3D","updated":"2013-06-21 04:29:30.000000000","message":"Unfortunately API validation does not work if \"result \u003d self.controller.action (**params**)\" because the validation code, means validator.validate(action_args[\u0027body\u0027]), exists in class Resource() at wsgi.py.","commit_id":"761b291e06aef14885dc89b2f2b4e636da38131d"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"c0faf06ab81c93f680f356263d60fbe38757edee","unresolved":false,"context_lines":[{"line_number":204,"context_line":"        request \u003d fakes.HTTPRequest.blank("},{"line_number":205,"context_line":"            \u0027/v3/fake/os-fixed-ips/192.168.1.1/action\u0027,"},{"line_number":206,"context_line":"            body\u003d\u0027{\"unreserve\": \"None\"}\u0027, method\u003d\u0027POST\u0027,"},{"line_number":207,"context_line":"            headers\u003d{\u0027Content-Type\u0027: \u0027application/json\u0027},"},{"line_number":208,"context_line":"            environ\u003d{\u0027wsgiorg.routing_args\u0027: [None, {\u0027action\u0027: \u0027action\u0027,"},{"line_number":209,"context_line":"                                                     \u0027id\u0027: \u0027192.168.1.1\u0027}]})"},{"line_number":210,"context_line":"        response \u003d resource(request)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAPn%2F%2Fzzk%3D","line":207,"updated":"2013-06-20 18:09:23.000000000","message":"nit if you are going to submit a new version: can we just move the common parts (the request, resource instantiation) into a method? Anyway, just if you had to submit another version.","commit_id":"761b291e06aef14885dc89b2f2b4e636da38131d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"914ed2f5d5d223d4d304bb4966c76d4e8992d619","unresolved":false,"context_lines":[{"line_number":204,"context_line":"        request \u003d fakes.HTTPRequest.blank("},{"line_number":205,"context_line":"            \u0027/v3/fake/os-fixed-ips/192.168.1.1/action\u0027,"},{"line_number":206,"context_line":"            body\u003d\u0027{\"unreserve\": \"None\"}\u0027, method\u003d\u0027POST\u0027,"},{"line_number":207,"context_line":"            headers\u003d{\u0027Content-Type\u0027: \u0027application/json\u0027},"},{"line_number":208,"context_line":"            environ\u003d{\u0027wsgiorg.routing_args\u0027: [None, {\u0027action\u0027: \u0027action\u0027,"},{"line_number":209,"context_line":"                                                     \u0027id\u0027: \u0027192.168.1.1\u0027}]})"},{"line_number":210,"context_line":"        response \u003d resource(request)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAAPn%2F%2Fy2Q%3D","line":207,"in_reply_to":"AAAAPn%2F%2Fzzk%3D","updated":"2013-06-21 04:29:30.000000000","message":"Good idea, it will make the test purposes clear.\nThanks, I will apply it to next version.","commit_id":"761b291e06aef14885dc89b2f2b4e636da38131d"},{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"0255986c94b0a26fc721dfe4b1ca9bf4716d350d","unresolved":false,"context_lines":[{"line_number":188,"context_line":"        self.assertRaises(webob.exc.HTTPNotFound, self.controller.action, req,"},{"line_number":189,"context_line":"                          \u002710.0.0.2\u0027, body)"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def _test_fixed_ip_validation(self, body):"},{"line_number":192,"context_line":"        resource \u003d wsgi.Resource(self.controller)"},{"line_number":193,"context_line":"        request \u003d fakes.HTTPRequest.blank("},{"line_number":194,"context_line":"            \u0027/v3/fake/os-fixed-ips/192.168.1.1/action\u0027,"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAPn%2F%2Fyn8%3D","line":191,"updated":"2013-06-21 06:59:43.000000000","message":"I think the name of this method does not represent this function of its responsibility.\nHow about \u0027_fake_request()\u0027 or something?","commit_id":"86e9cea2c84bfd89e765bc27e26835f1f49c9f35"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"40d8c4c77e5564f73cc660f96443c85439713b8d","unresolved":false,"context_lines":[{"line_number":188,"context_line":"        self.assertRaises(webob.exc.HTTPNotFound, self.controller.action, req,"},{"line_number":189,"context_line":"                          \u002710.0.0.2\u0027, body)"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def _test_fixed_ip_validation(self, body):"},{"line_number":192,"context_line":"        resource \u003d wsgi.Resource(self.controller)"},{"line_number":193,"context_line":"        request \u003d fakes.HTTPRequest.blank("},{"line_number":194,"context_line":"            \u0027/v3/fake/os-fixed-ips/192.168.1.1/action\u0027,"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAPn%2F%2Fyh8%3D","line":191,"in_reply_to":"AAAAPn%2F%2FyjA%3D","updated":"2013-06-21 07:57:37.000000000","message":"I see, will change.","commit_id":"86e9cea2c84bfd89e765bc27e26835f1f49c9f35"},{"author":{"_account_id":5689,"name":"Masayuki Igawa","email":"masayuki@igawa.io","username":"igawa"},"change_message_id":"a5e2c5ca21f4dac0553adda2abf02095f3f47cf6","unresolved":false,"context_lines":[{"line_number":188,"context_line":"        self.assertRaises(webob.exc.HTTPNotFound, self.controller.action, req,"},{"line_number":189,"context_line":"                          \u002710.0.0.2\u0027, body)"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def _test_fixed_ip_validation(self, body):"},{"line_number":192,"context_line":"        resource \u003d wsgi.Resource(self.controller)"},{"line_number":193,"context_line":"        request \u003d fakes.HTTPRequest.blank("},{"line_number":194,"context_line":"            \u0027/v3/fake/os-fixed-ips/192.168.1.1/action\u0027,"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAPn%2F%2FyjA%3D","line":191,"in_reply_to":"AAAAPn%2F%2Fyls%3D","updated":"2013-06-21 07:46:02.000000000","message":"If you want to know what will return, How about \u0027_get_fake_response()\u0027?","commit_id":"86e9cea2c84bfd89e765bc27e26835f1f49c9f35"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"92551214fa7f49151d66a3ffe0fcb675130fa78f","unresolved":false,"context_lines":[{"line_number":188,"context_line":"        self.assertRaises(webob.exc.HTTPNotFound, self.controller.action, req,"},{"line_number":189,"context_line":"                          \u002710.0.0.2\u0027, body)"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"    def _test_fixed_ip_validation(self, body):"},{"line_number":192,"context_line":"        resource \u003d wsgi.Resource(self.controller)"},{"line_number":193,"context_line":"        request \u003d fakes.HTTPRequest.blank("},{"line_number":194,"context_line":"            \u0027/v3/fake/os-fixed-ips/192.168.1.1/action\u0027,"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAAPn%2F%2Fyls%3D","line":191,"in_reply_to":"AAAAPn%2F%2Fyn8%3D","updated":"2013-06-21 07:24:23.000000000","message":"OK, how about \u0027_fake_response()\u0027? because this method returns a response.","commit_id":"86e9cea2c84bfd89e765bc27e26835f1f49c9f35"}],"nova/tests/api/openstack/test_wsgi.py":[{"author":{"_account_id":7203,"name":"yuuichi fujioka","email":"fujioka.yuuichi@gmail.com","username":"FujiokaYuuichi"},"change_message_id":"9fe9224fc746d337d1ad1912c9c70187cafc7eb9","unresolved":false,"context_lines":[{"line_number":1024,"context_line":""},{"line_number":1025,"context_line":"    def _get_response(self, body, headers):"},{"line_number":1026,"context_line":"        class Controller(object):"},{"line_number":1027,"context_line":"            @api_validator.validator(request_body_schema\u003d{"},{"line_number":1028,"context_line":"                \u0027type\u0027: \u0027object\u0027,"},{"line_number":1029,"context_line":"                \u0027properties\u0027: {"},{"line_number":1030,"context_line":"                    \u0027foo\u0027: {"}],"source_content_type":"text/x-python","patch_set":26,"id":"AAAAPn%2F%2Fsgg%3D","line":1027,"updated":"2013-06-25 03:25:35.000000000","message":"How about removing \"request_body_schema\u003d\"?","commit_id":"edaaa41c3772aac6f9396d62ee9cd21421f40200"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4520c5124537f73fd4b0a48fc41755b51246a122","unresolved":false,"context_lines":[{"line_number":1024,"context_line":""},{"line_number":1025,"context_line":"    def _get_response(self, body, headers):"},{"line_number":1026,"context_line":"        class Controller(object):"},{"line_number":1027,"context_line":"            @api_validator.validator(request_body_schema\u003d{"},{"line_number":1028,"context_line":"                \u0027type\u0027: \u0027object\u0027,"},{"line_number":1029,"context_line":"                \u0027properties\u0027: {"},{"line_number":1030,"context_line":"                    \u0027foo\u0027: {"}],"source_content_type":"text/x-python","patch_set":26,"id":"AAAAPn%2F%2Fsbc%3D","line":1027,"in_reply_to":"AAAAPn%2F%2Fsgg%3D","updated":"2013-06-25 04:29:45.000000000","message":"For considering that we need response_body_schema (please see comments for patch#14 of I36a1f26afb3c9619c96979599e355b7982248ce4) in the future, it is better to specify *request_body_schema*.","commit_id":"edaaa41c3772aac6f9396d62ee9cd21421f40200"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0130ecff5ed466d48dc2bda4ffd7d0341485eef3","unresolved":false,"context_lines":[{"line_number":1041,"context_line":"            environ\u003d{\u0027wsgiorg.routing_args\u0027: [None, {\u0027action\u0027: \u0027index\u0027}]})"},{"line_number":1042,"context_line":"        return resource(request)"},{"line_number":1043,"context_line":""},{"line_number":1044,"context_line":"    def test_api_validation_json(self):"},{"line_number":1045,"context_line":"        headers \u003d {\"Content-Type\": \"application/json\"}"},{"line_number":1046,"context_line":""},{"line_number":1047,"context_line":"        body \u003d \u0027{\"foo\": \"abc\"}\u0027"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2Fnmw%3D","line":1044,"updated":"2013-06-26 17:35:19.000000000","message":"Feels like these should be in a separate TestCase maybe?","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"6291c2869979617ca2aa6bfc5af651d176b933e5","unresolved":false,"context_lines":[{"line_number":1041,"context_line":"            environ\u003d{\u0027wsgiorg.routing_args\u0027: [None, {\u0027action\u0027: \u0027index\u0027}]})"},{"line_number":1042,"context_line":"        return resource(request)"},{"line_number":1043,"context_line":""},{"line_number":1044,"context_line":"    def test_api_validation_json(self):"},{"line_number":1045,"context_line":"        headers \u003d {\"Content-Type\": \"application/json\"}"},{"line_number":1046,"context_line":""},{"line_number":1047,"context_line":"        body \u003d \u0027{\"foo\": \"abc\"}\u0027"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FmLE%3D","line":1044,"in_reply_to":"AAAAPn%2F%2Fnmw%3D","updated":"2013-06-27 03:49:27.000000000","message":"I see, thanks.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"c4dded95e4956ad9c104947d1eb499b50435ca36","unresolved":false,"context_lines":[{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"        body \u003d \u0027{\"foo\": \"abc\"}\u0027"},{"line_number":1051,"context_line":"        response \u003d self._get_response(body, headers)"},{"line_number":1052,"context_line":"        self.assertEqual(response, \u0027abc\u0027)"},{"line_number":1053,"context_line":""},{"line_number":1054,"context_line":"        body \u003d \u0027{\"foo\": \"0123456789a\"}\u0027"},{"line_number":1055,"context_line":"        response \u003d self._get_response(body, headers)"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FlDY%3D","line":1052,"updated":"2013-06-27 13:13:25.000000000","message":"I would make this into two tests ..._json and ..._json_fails or something like that.","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4f14cebbae373387e6626d76bf222e1b3c067c1b","unresolved":false,"context_lines":[{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"        body \u003d \u0027{\"foo\": \"abc\"}\u0027"},{"line_number":1051,"context_line":"        response \u003d self._get_response(body, headers)"},{"line_number":1052,"context_line":"        self.assertEqual(response, \u0027abc\u0027)"},{"line_number":1053,"context_line":""},{"line_number":1054,"context_line":"        body \u003d \u0027{\"foo\": \"0123456789a\"}\u0027"},{"line_number":1055,"context_line":"        response \u003d self._get_response(body, headers)"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2Fk1U%3D","line":1052,"in_reply_to":"AAAAPn%2F%2FlDY%3D","updated":"2013-06-27 15:06:36.000000000","message":"OK, will fix.","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"}],"nova/tests/api/test_api_validator.py":[{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"3d75f966da8b41499b59fb1858d71daa73a35773","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from nova import test"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class APIValidatorTestCase(test.TestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def test_validate_required(self):"},{"line_number":26,"context_line":"        schema \u003d {"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAOn%2F%2FnwI%3D","line":23,"updated":"2013-05-01 16:17:22.000000000","message":"These tests will be in oslo-incubator - there is no need to add them to Nova too","commit_id":"a69f6f8040b3aa45759df8e8d197c5ada1a57dd6"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"2a3b4cb071df9fcc4f4f343b4364acfa3ea72203","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from nova import test"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class APIValidatorTestCase(test.TestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def test_validate_required(self):"},{"line_number":26,"context_line":"        schema \u003d {"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAOn%2F%2FmCU%3D","line":23,"in_reply_to":"AAAAOn%2F%2FnwI%3D","updated":"2013-05-02 15:05:49.000000000","message":"I see, thanks.","commit_id":"a69f6f8040b3aa45759df8e8d197c5ada1a57dd6"}],"nova/tests/test_api_validation.py":[{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"6b8f5a8efea9d256e2d6f17ac4854e1976111d25","unresolved":false,"context_lines":[{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def test_validate_required_disable(self):"},{"line_number":59,"context_line":"        self.assertEquals(self.post(body\u003d{\u0027foo\u0027: 1}), \u0027Validation succeeded.\u0027)"},{"line_number":60,"context_line":"        self.assertEquals(self.post(body\u003d{\u0027abc\u0027: 1}), \u0027Validation succeeded.\u0027)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"class RequiredEnableTestCase(APIValidationTestCase):"}],"source_content_type":"text/x-python","patch_set":45,"id":"AAAATn%2F%2BlTk%3D","line":60,"updated":"2013-11-22 20:13:00.000000000","message":"assertEquals() is deprecated; please use assertEqual() (notice the \u0027s\u0027 is dropped).","commit_id":"f2b87f80ac4308764ba37b8a50530bf59f4b439c"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"b41189067bc56e6b803eaf21e5eda77adca35f95","unresolved":false,"context_lines":[{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def test_validate_required_disable(self):"},{"line_number":59,"context_line":"        self.assertEquals(self.post(body\u003d{\u0027foo\u0027: 1}), \u0027Validation succeeded.\u0027)"},{"line_number":60,"context_line":"        self.assertEquals(self.post(body\u003d{\u0027abc\u0027: 1}), \u0027Validation succeeded.\u0027)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"class RequiredEnableTestCase(APIValidationTestCase):"}],"source_content_type":"text/x-python","patch_set":45,"id":"AAAATn%2F%2Bj4E%3D","line":60,"in_reply_to":"AAAATn%2F%2BlTk%3D","updated":"2013-11-23 12:17:48.000000000","message":"Thanks, will change all them.","commit_id":"f2b87f80ac4308764ba37b8a50530bf59f4b439c"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"707016949e98d8fa1fd80f5a2f22d290d5b87c3a","unresolved":false,"context_lines":[{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    def test_validate_string_fails(self):"},{"line_number":176,"context_line":"        detail \u003d \"Invalid input for field/attribute foo. Value: 1.\"\\"},{"line_number":177,"context_line":"                 \" 1 is not of type \u0027string\u0027\""},{"line_number":178,"context_line":"        self.check_validation_error(self.post, body\u003d{\u0027foo\u0027: 1},"},{"line_number":179,"context_line":"                                    expected_datail\u003ddetail)"},{"line_number":180,"context_line":""}],"source_content_type":"text/x-python","patch_set":50,"id":"AAAATn%2F%2BdS4%3D","line":177,"updated":"2013-11-25 20:44:49.000000000","message":"I would prefer parentheses rather than backslash line continuation.  (femtonit)","commit_id":"f25fbaa2f72030dec48eee30c354b34356cd6808"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"cc71ef9e40931f35f64cdf5d73a8af8651cc4d93","unresolved":false,"context_lines":[{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    def test_validate_string_fails(self):"},{"line_number":176,"context_line":"        detail \u003d \"Invalid input for field/attribute foo. Value: 1.\"\\"},{"line_number":177,"context_line":"                 \" 1 is not of type \u0027string\u0027\""},{"line_number":178,"context_line":"        self.check_validation_error(self.post, body\u003d{\u0027foo\u0027: 1},"},{"line_number":179,"context_line":"                                    expected_datail\u003ddetail)"},{"line_number":180,"context_line":""}],"source_content_type":"text/x-python","patch_set":50,"id":"AAAATn%2F%2BdJE%3D","line":177,"in_reply_to":"AAAATn%2F%2BdS4%3D","updated":"2013-11-25 21:19:21.000000000","message":"I see, will change them.","commit_id":"f25fbaa2f72030dec48eee30c354b34356cd6808"},{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"e4925c7ec18ac91496d2651c5eb2b15f9df048d7","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class APIValidationTestCase(test.TestCase):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def check_validation_error(self, method, body, expected_datail):"},{"line_number":25,"context_line":"        try:"},{"line_number":26,"context_line":"            method(body\u003dbody)"},{"line_number":27,"context_line":"        except exception.ValidationError as ex:"}],"source_content_type":"text/x-python","patch_set":51,"id":"AAAATn%2F%2BY1A%3D","line":24,"updated":"2013-11-26 16:25:16.000000000","message":"nit, spelling error in variable.","commit_id":"3c01aca6b1a95393dfb4d404156e62c91da4e845"},{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"e4925c7ec18ac91496d2651c5eb2b15f9df048d7","unresolved":false,"context_lines":[{"line_number":139,"context_line":"    def test_validate_additionalProperties_disable(self):"},{"line_number":140,"context_line":"        self.assertEqual(self.post(body\u003d{\u0027foo\u0027: 1}), \u0027Validation succeeded.\u0027)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def test_validate_additionalProperties_disable_failes(self):"},{"line_number":143,"context_line":"        detail \u003d \"Additional properties are not allowed (\u0027ext\u0027 was unexpected)\""},{"line_number":144,"context_line":"        self.check_validation_error(self.post, body\u003d{\u0027foo\u0027: 1, \u0027ext\u0027: 1},"},{"line_number":145,"context_line":"                                    expected_datail\u003ddetail)"}],"source_content_type":"text/x-python","patch_set":51,"id":"AAAATn%2F%2BY0g%3D","line":142,"updated":"2013-11-26 16:25:16.000000000","message":"s/failes/fails/","commit_id":"3c01aca6b1a95393dfb4d404156e62c91da4e845"},{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"e4925c7ec18ac91496d2651c5eb2b15f9df048d7","unresolved":false,"context_lines":[{"line_number":142,"context_line":"    def test_validate_additionalProperties_disable_failes(self):"},{"line_number":143,"context_line":"        detail \u003d \"Additional properties are not allowed (\u0027ext\u0027 was unexpected)\""},{"line_number":144,"context_line":"        self.check_validation_error(self.post, body\u003d{\u0027foo\u0027: 1, \u0027ext\u0027: 1},"},{"line_number":145,"context_line":"                                    expected_datail\u003ddetail)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"class StringTestCase(APIValidationTestCase):"}],"source_content_type":"text/x-python","patch_set":51,"id":"AAAATn%2F%2BY0I%3D","line":145,"updated":"2013-11-26 16:25:16.000000000","message":"s/datail/detail/","commit_id":"3c01aca6b1a95393dfb4d404156e62c91da4e845"}],"nova/tests/test_api_validator.py":[{"author":{"_account_id":7203,"name":"yuuichi fujioka","email":"fujioka.yuuichi@gmail.com","username":"FujiokaYuuichi"},"change_message_id":"9fe9224fc746d337d1ad1912c9c70187cafc7eb9","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        validator \u003d api_validator.APIValidator(schema)"},{"line_number":37,"context_line":"        validator.validate({\u0027foo\u0027: 1})"},{"line_number":38,"context_line":"        self.assertRaises(jsonschema.ValidationError,"},{"line_number":39,"context_line":"                          validator.validate, {\u0027abc\u0027: 1})"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def test_validate_additionalProperties(self):"},{"line_number":42,"context_line":"        schema \u003d {"}],"source_content_type":"text/x-python","patch_set":26,"id":"AAAAPn%2F%2Fsd4%3D","line":39,"updated":"2013-06-25 03:25:35.000000000","message":"How about adding a test case without *required* paramater?","commit_id":"edaaa41c3772aac6f9396d62ee9cd21421f40200"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4520c5124537f73fd4b0a48fc41755b51246a122","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        validator \u003d api_validator.APIValidator(schema)"},{"line_number":37,"context_line":"        validator.validate({\u0027foo\u0027: 1})"},{"line_number":38,"context_line":"        self.assertRaises(jsonschema.ValidationError,"},{"line_number":39,"context_line":"                          validator.validate, {\u0027abc\u0027: 1})"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def test_validate_additionalProperties(self):"},{"line_number":42,"context_line":"        schema \u003d {"}],"source_content_type":"text/x-python","patch_set":26,"id":"AAAAPn%2F%2Fscc%3D","line":39,"in_reply_to":"AAAAPn%2F%2Fsd4%3D","updated":"2013-06-25 04:29:45.000000000","message":"will fix","commit_id":"edaaa41c3772aac6f9396d62ee9cd21421f40200"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0130ecff5ed466d48dc2bda4ffd7d0341485eef3","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":14,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":15,"context_line":"#    under the License."},{"line_number":16,"context_line":"# @author: Ken\u0027ichi Ohmichi"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import jsonschema"},{"line_number":19,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2Fnpw%3D","line":16,"updated":"2013-06-26 17:35:19.000000000","message":"not sure we usually bother with this bit, git tracks that for us.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"6291c2869979617ca2aa6bfc5af651d176b933e5","unresolved":false,"context_lines":[{"line_number":13,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":14,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":15,"context_line":"#    under the License."},{"line_number":16,"context_line":"# @author: Ken\u0027ichi Ohmichi"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import jsonschema"},{"line_number":19,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FmK8%3D","line":16,"in_reply_to":"AAAAPn%2F%2Fnpw%3D","updated":"2013-06-27 03:49:27.000000000","message":"I see, will remove.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0130ecff5ed466d48dc2bda4ffd7d0341485eef3","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        schema[\u0027required\u0027] \u003d [\u0027foo\u0027]"},{"line_number":40,"context_line":"        validator \u003d api_validator.APIValidator(schema)"},{"line_number":41,"context_line":"        validator.validate({\u0027foo\u0027: 1})"},{"line_number":42,"context_line":"        self.assertRaises(jsonschema.ValidationError,"},{"line_number":43,"context_line":"                          validator.validate, {\u0027abc\u0027: 1})"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def test_validate_additionalProperties(self):"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FnpI%3D","line":42,"updated":"2013-06-26 17:35:19.000000000","message":"Clumping the tests like this make it hard to debug, and maintain. is there a nicer way to structure this so its closer to one \"test\" per test function? Maybe a TestCase per validation thing you are testing, and create the scheme in the setUp()?\n\nNo is a valid answer, just wondering if we can do better.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"6291c2869979617ca2aa6bfc5af651d176b933e5","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        schema[\u0027required\u0027] \u003d [\u0027foo\u0027]"},{"line_number":40,"context_line":"        validator \u003d api_validator.APIValidator(schema)"},{"line_number":41,"context_line":"        validator.validate({\u0027foo\u0027: 1})"},{"line_number":42,"context_line":"        self.assertRaises(jsonschema.ValidationError,"},{"line_number":43,"context_line":"                          validator.validate, {\u0027abc\u0027: 1})"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def test_validate_additionalProperties(self):"}],"source_content_type":"text/x-python","patch_set":27,"id":"AAAAPn%2F%2FmGU%3D","line":42,"in_reply_to":"AAAAPn%2F%2FnpI%3D","updated":"2013-06-27 03:49:27.000000000","message":"OK, I will try making better test structure.","commit_id":"afd4e1f15a67ff12e030024b0489c90d5d07d60d"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"c4dded95e4956ad9c104947d1eb499b50435ca36","unresolved":false,"context_lines":[{"line_number":154,"context_line":"        validator.validate({\u0027foo\u0027: \u00271\u0027})"},{"line_number":155,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":156,"context_line":"                          validator.validate, {\u0027foo\u0027: 0})"},{"line_number":157,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":158,"context_line":"                          validator.validate, {\u0027foo\u0027: 11})"},{"line_number":159,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":160,"context_line":"                          validator.validate, {\u0027foo\u0027: \u00270\u0027})"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FlDI%3D","line":157,"updated":"2013-06-27 13:13:25.000000000","message":"I would still separate some of these out a bit myself, but this does look lots better than before :)","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4f14cebbae373387e6626d76bf222e1b3c067c1b","unresolved":false,"context_lines":[{"line_number":154,"context_line":"        validator.validate({\u0027foo\u0027: \u00271\u0027})"},{"line_number":155,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":156,"context_line":"                          validator.validate, {\u0027foo\u0027: 0})"},{"line_number":157,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":158,"context_line":"                          validator.validate, {\u0027foo\u0027: 11})"},{"line_number":159,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":160,"context_line":"                          validator.validate, {\u0027foo\u0027: \u00270\u0027})"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FkxA%3D","line":157,"in_reply_to":"AAAAPn%2F%2FlDI%3D","updated":"2013-06-27 15:06:36.000000000","message":"OK, I will try more.","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"c4dded95e4956ad9c104947d1eb499b50435ca36","unresolved":false,"context_lines":[{"line_number":157,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":158,"context_line":"                          validator.validate, {\u0027foo\u0027: 11})"},{"line_number":159,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":160,"context_line":"                          validator.validate, {\u0027foo\u0027: \u00270\u0027})"},{"line_number":161,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":162,"context_line":"                          validator.validate, {\u0027foo\u0027: \u002711\u0027})"},{"line_number":163,"context_line":"        self.assertRaises(exception.ValidationError,"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FlDA%3D","line":160,"updated":"2013-06-27 13:13:25.000000000","message":"These few here I don\u0027t think we need, but I guess its no bad thing","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4f14cebbae373387e6626d76bf222e1b3c067c1b","unresolved":false,"context_lines":[{"line_number":157,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":158,"context_line":"                          validator.validate, {\u0027foo\u0027: 11})"},{"line_number":159,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":160,"context_line":"                          validator.validate, {\u0027foo\u0027: \u00270\u0027})"},{"line_number":161,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":162,"context_line":"                          validator.validate, {\u0027foo\u0027: \u002711\u0027})"},{"line_number":163,"context_line":"        self.assertRaises(exception.ValidationError,"}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FkwU%3D","line":160,"in_reply_to":"AAAAPn%2F%2FlDA%3D","updated":"2013-06-27 15:06:36.000000000","message":"I\u0027d like to keep them for testing _number_from_str() in APIValidator class.","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"c4dded95e4956ad9c104947d1eb499b50435ca36","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                          validator.validate, {\u0027foo\u0027: \u00270\u0027})"},{"line_number":161,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":162,"context_line":"                          validator.validate, {\u0027foo\u0027: \u002711\u0027})"},{"line_number":163,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":164,"context_line":"                          validator.validate, {\u0027foo\u0027: \u00270x01\u0027})"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FlDE%3D","line":163,"updated":"2013-06-27 13:13:25.000000000","message":"maybe test that a float fails too?","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"4f14cebbae373387e6626d76bf222e1b3c067c1b","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                          validator.validate, {\u0027foo\u0027: \u00270\u0027})"},{"line_number":161,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":162,"context_line":"                          validator.validate, {\u0027foo\u0027: \u002711\u0027})"},{"line_number":163,"context_line":"        self.assertRaises(exception.ValidationError,"},{"line_number":164,"context_line":"                          validator.validate, {\u0027foo\u0027: \u00270x01\u0027})"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"AAAAPn%2F%2FkwA%3D","line":163,"in_reply_to":"AAAAPn%2F%2FlDE%3D","updated":"2013-06-27 15:06:36.000000000","message":"nice catch, I will add it.","commit_id":"8db36993c1849253035ee15e95ce0b5d2ba9b982"},{"author":{"_account_id":7996,"name":"Luis A. Garcia","email":"luis@linux.vnet.ibm.com","username":"luisg"},"change_message_id":"10b1d3478fc6444af8597b79577e9b06e79b438b","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova import test"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class RequiredDisableTestCase(test.TestCase):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def setUp(self):"},{"line_number":25,"context_line":"        super(RequiredDisableTestCase, self).setUp()"}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FUXk%3D","line":22,"updated":"2013-08-02 01:58:40.000000000","message":"I think these test cases are mostly testing functionality from jsonschema.Draft4Validator. Testing whether required attributes are included, or that additional properties are included when the schema says that they are not allowed, seems like tests for the actual parent validator, not tests for the validation framework being implemented. \n\nI think tests should focus more on ensuring that when validation fails the expected exception is thrown or the response returned, but in a more general way.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"09d454c17998ca1669b8a66ec7f374e03b7f475c","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from nova import test"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class RequiredDisableTestCase(test.TestCase):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def setUp(self):"},{"line_number":25,"context_line":"        super(RequiredDisableTestCase, self).setUp()"}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FTYk%3D","line":22,"in_reply_to":"AAAAQn%2F%2FUXk%3D","updated":"2013-08-02 08:30:34.000000000","message":"Do you mean the test cases only for Draft4Validator should be removed?\nI feel test cases for Draft4Validator is useful for this framework, because the feature quality of Draft4Validator is important and the test cases would be good samples for defining API schema.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":7996,"name":"Luis A. Garcia","email":"luis@linux.vnet.ibm.com","username":"luisg"},"change_message_id":"10b1d3478fc6444af8597b79577e9b06e79b438b","unresolved":false,"context_lines":[{"line_number":196,"context_line":"                          self.post, body\u003d{\u0027foo\u0027: \u00270123456789a\u0027})"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"class IntegerTestCase(test.TestCase):"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def setUp(self):"},{"line_number":202,"context_line":"        super(IntegerTestCase, self).setUp()"}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FUT0%3D","line":199,"updated":"2013-08-02 01:58:40.000000000","message":"The name of this test case should indicate that its testing the FormatChecker","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"09d454c17998ca1669b8a66ec7f374e03b7f475c","unresolved":false,"context_lines":[{"line_number":196,"context_line":"                          self.post, body\u003d{\u0027foo\u0027: \u00270123456789a\u0027})"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"class IntegerTestCase(test.TestCase):"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def setUp(self):"},{"line_number":202,"context_line":"        super(IntegerTestCase, self).setUp()"}],"source_content_type":"text/x-python","patch_set":35,"id":"AAAAQn%2F%2FTxM%3D","line":199,"in_reply_to":"AAAAQn%2F%2FUT0%3D","updated":"2013-08-02 08:30:34.000000000","message":"This test case checks not only FormatChecker but also type \u0027integer\u0027. The type \u0027integer\u0027 is specified at line 207, and it tests an integer value at line 220. so I don\u0027t feel the name is so wrong.","commit_id":"808c1e3141329b3dd2381387fbb2725ad49b0553"}],"requirements.txt":[{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"80a875f5e3aa9103ea17a7e4837f505358b8f4c4","unresolved":false,"context_lines":[{"line_number":31,"context_line":"stevedore\u003e\u003d0.7"},{"line_number":32,"context_line":"websockify\u003c0.4"},{"line_number":33,"context_line":"oslo.config\u003e\u003d1.1.0"},{"line_number":34,"context_line":"jsonschema\u003e\u003d1.0.0,\u003c2"}],"source_content_type":"text/plain","patch_set":18,"id":"AAAAPX%2F%2FqnM%3D","line":34,"updated":"2013-06-13 07:04:22.000000000","message":"\"\u003c2\" is unnecessary now because this patch supports jsonschema v2.0.0.","commit_id":"02696465e44847d4de85a8ea7e37c33b8579cc5a"}]}
