)]}'
{"heat/engine/service.py":[{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"33844d0c821f69b57b3f6a1779571f4b7a43e1bb","unresolved":false,"context_lines":[{"line_number":602,"context_line":"            return err"},{"line_number":603,"context_line":""},{"line_number":604,"context_line":"        # validate resource classes"},{"line_number":605,"context_line":"        tmpl_resources \u003d tmpl.get(tmpl.RESOURCES, [])"},{"line_number":606,"context_line":""},{"line_number":607,"context_line":"        for res in tmpl_resources.values():"},{"line_number":608,"context_line":"            ResourceClass \u003d resource.get_class(res[\u0027Type\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F93Hg%3D","line":605,"updated":"2014-04-01 15:40:18.000000000","message":"Default should be an empty dict here (a list has no values() method to call on line 607), but in any event using get() is not necessary because a Template object will never raise KeyError for a valid template key.","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"},{"author":{"_account_id":7193,"name":"Thomas Spatzier","email":"thomas.spatzier@icloud.com","username":"thomasspatzier"},"change_message_id":"f18bfaa0b3e47d530101edfcdf623fc9ef05e214","unresolved":false,"context_lines":[{"line_number":602,"context_line":"            return err"},{"line_number":603,"context_line":""},{"line_number":604,"context_line":"        # validate resource classes"},{"line_number":605,"context_line":"        tmpl_resources \u003d tmpl.get(tmpl.RESOURCES, [])"},{"line_number":606,"context_line":""},{"line_number":607,"context_line":"        for res in tmpl_resources.values():"},{"line_number":608,"context_line":"            ResourceClass \u003d resource.get_class(res[\u0027Type\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9SGk%3D","line":605,"in_reply_to":"AAAAWH%2F93Hg%3D","updated":"2014-04-07 16:02:42.000000000","message":"Done","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"}],"heat/engine/template.py":[{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"33844d0c821f69b57b3f6a1779571f4b7a43e1bb","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"        # check resources"},{"line_number":183,"context_line":"        try:"},{"line_number":184,"context_line":"            tmpl_resources \u003d self[self.RESOURCES]"},{"line_number":185,"context_line":"        except KeyError as ex:"},{"line_number":186,"context_line":"            return {\u0027Error\u0027: str(ex)}"},{"line_number":187,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F93GY%3D","line":184,"updated":"2014-04-01 15:40:18.000000000","message":"I\u0027d marginally prefer\n\n  tmpl_resources \u003d self.t.get(self.RESOURCES)\n\nbecause we want to eventually deprecate __getitem__ access to templates.","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"},{"author":{"_account_id":7193,"name":"Thomas Spatzier","email":"thomas.spatzier@icloud.com","username":"thomasspatzier"},"change_message_id":"f18bfaa0b3e47d530101edfcdf623fc9ef05e214","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"        # check resources"},{"line_number":183,"context_line":"        try:"},{"line_number":184,"context_line":"            tmpl_resources \u003d self[self.RESOURCES]"},{"line_number":185,"context_line":"        except KeyError as ex:"},{"line_number":186,"context_line":"            return {\u0027Error\u0027: str(ex)}"},{"line_number":187,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9R%2Bk%3D","line":184,"in_reply_to":"AAAAWH%2F93GY%3D","updated":"2014-04-07 16:02:42.000000000","message":"I don\u0027t think this will work at the moment, since that code would return un-translated template snippets. I.e. we would not be able to do the \u0027Type\u0027 key compare below. Unfortunately, we do not have the nice internal CFN/HOT split in the resources class as we have it in the template class.\n\nTherefore, I would opt to keep it as is for now. Ok?","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"df9e9b1209ba1dd7b94b3237a89648dcd7ebc5a5","unresolved":false,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"        # check resources"},{"line_number":183,"context_line":"        try:"},{"line_number":184,"context_line":"            tmpl_resources \u003d self[self.RESOURCES]"},{"line_number":185,"context_line":"        except KeyError as ex:"},{"line_number":186,"context_line":"            return {\u0027Error\u0027: str(ex)}"},{"line_number":187,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F2ZU%3D","line":184,"in_reply_to":"AAAAWH%2F9R%2Bk%3D","updated":"2014-04-09 23:32:48.000000000","message":"Quite right. I got confused with the stuff in my local tree ;)","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"33844d0c821f69b57b3f6a1779571f4b7a43e1bb","unresolved":false,"context_lines":[{"line_number":183,"context_line":"        try:"},{"line_number":184,"context_line":"            tmpl_resources \u003d self[self.RESOURCES]"},{"line_number":185,"context_line":"        except KeyError as ex:"},{"line_number":186,"context_line":"            return {\u0027Error\u0027: str(ex)}"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"        if not tmpl_resources:"},{"line_number":189,"context_line":"            return {\u0027Error\u0027: \u0027At least one Resources member must be defined.\u0027}"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F93EY%3D","line":186,"updated":"2014-04-01 15:40:18.000000000","message":"This whole {\u0027Error\u0027: } thing is a (not very good) part of the RPC \u0026 ReST API definitions, I feel like a Template should not know anything about that. Can we just raise exceptions for these? That will make it easier for subclasses too.","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"},{"author":{"_account_id":7193,"name":"Thomas Spatzier","email":"thomas.spatzier@icloud.com","username":"thomasspatzier"},"change_message_id":"f18bfaa0b3e47d530101edfcdf623fc9ef05e214","unresolved":false,"context_lines":[{"line_number":183,"context_line":"        try:"},{"line_number":184,"context_line":"            tmpl_resources \u003d self[self.RESOURCES]"},{"line_number":185,"context_line":"        except KeyError as ex:"},{"line_number":186,"context_line":"            return {\u0027Error\u0027: str(ex)}"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"        if not tmpl_resources:"},{"line_number":189,"context_line":"            return {\u0027Error\u0027: \u0027At least one Resources member must be defined.\u0027}"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9R%2Bg%3D","line":186,"in_reply_to":"AAAAWH%2F9064%3D","updated":"2014-04-07 16:02:42.000000000","message":"Done","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"13e50ee7a173b8b17946ca8e0b54d66194ab2b0e","unresolved":false,"context_lines":[{"line_number":183,"context_line":"        try:"},{"line_number":184,"context_line":"            tmpl_resources \u003d self[self.RESOURCES]"},{"line_number":185,"context_line":"        except KeyError as ex:"},{"line_number":186,"context_line":"            return {\u0027Error\u0027: str(ex)}"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"        if not tmpl_resources:"},{"line_number":189,"context_line":"            return {\u0027Error\u0027: \u0027At least one Resources member must be defined.\u0027}"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F9064%3D","line":186,"in_reply_to":"AAAAWH%2F92uc%3D","updated":"2014-04-01 20:51:40.000000000","message":"Back in the day we used to handle all errors like this, and we gradually switched over to exceptions. This may be one of the last places to be fixed.\n\nI agree about not breaking the API. We should probably continue to catch exceptions at the service.py level and return {\u0027Error\u0027: str(exc)} or whatever, but we can raise (or just not handle) exceptions from in here.","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"},{"author":{"_account_id":7193,"name":"Thomas Spatzier","email":"thomas.spatzier@icloud.com","username":"thomasspatzier"},"change_message_id":"04e0836d2db0e28172939065a5bcb80382a17569","unresolved":false,"context_lines":[{"line_number":183,"context_line":"        try:"},{"line_number":184,"context_line":"            tmpl_resources \u003d self[self.RESOURCES]"},{"line_number":185,"context_line":"        except KeyError as ex:"},{"line_number":186,"context_line":"            return {\u0027Error\u0027: str(ex)}"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"        if not tmpl_resources:"},{"line_number":189,"context_line":"            return {\u0027Error\u0027: \u0027At least one Resources member must be defined.\u0027}"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAWH%2F92uc%3D","line":186,"in_reply_to":"AAAAWH%2F93EY%3D","updated":"2014-04-01 16:19:22.000000000","message":"I actually agree on raising exceptions instead of this Error thing. I have not seen this anywhere else, and it just looks odd.\n\nHowever, this is how the current API is designed so wouldn\u0027t we break clients? If we accept slight changes of returned data and want to clean up, fine we me, but I wanted to raise the question.","commit_id":"689809c6db5e7594b861193dcf01272538554a6d"},{"author":{"_account_id":8289,"name":"huangtianhua","email":"tiantian223@163.com","username":"huangtianhua"},"change_message_id":"85f00f2a4d93f630bc3509df7f72029eb3fe6f0c","unresolved":false,"context_lines":[{"line_number":165,"context_line":"    def parse(self, stack, snippet):"},{"line_number":166,"context_line":"        return parse(self.functions(), stack, snippet)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    def validate(self, allow_empty\u003dTrue):"},{"line_number":169,"context_line":"        \u0027\u0027\u0027Validate the template."},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        Validates the top-level sections of the template as well as syntax"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWn%2F%2F%2BME%3D","line":168,"updated":"2014-04-08 07:07:54.000000000","message":"Why the default value of \u0027allow_empty\u0027 is True? Before you modify it\u0027s not allow empty resources in template. And if you note that in what situations allow the resources section empty is useful.\n\nThanks.","commit_id":"838949e169bc3bab6f566498b2c49325dc384a91"},{"author":{"_account_id":7193,"name":"Thomas Spatzier","email":"thomas.spatzier@icloud.com","username":"thomasspatzier"},"change_message_id":"1d457a8fa23e23d1b89278da83526b24563e366e","unresolved":false,"context_lines":[{"line_number":165,"context_line":"    def parse(self, stack, snippet):"},{"line_number":166,"context_line":"        return parse(self.functions(), stack, snippet)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    def validate(self, allow_empty\u003dTrue):"},{"line_number":169,"context_line":"        \u0027\u0027\u0027Validate the template."},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        Validates the top-level sections of the template as well as syntax"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWn%2F%2F9jk%3D","line":168,"in_reply_to":"AAAAWn%2F%2F%2BME%3D","updated":"2014-04-08 08:25:36.000000000","message":"When moving this validation here I found that there is code, e.g. in autoscaling.py that creates templates (it is called initial_template there) that has an empty resources section. Then while autoscaling works, they fill the resources section or remove resources from it.\n\nThat code invokes Template.validate thru parser.validate() and it looks like other such use cases go thru the same code path. So in order to not break all that code, and to not have adapt all that code I decided to make the default lax.\n\nThe only place so far where we checked for a non-empty resource section was EngineService.validate_template() so I decided to explicitly set allow_empty\u003dFalse there.","commit_id":"838949e169bc3bab6f566498b2c49325dc384a91"},{"author":{"_account_id":8289,"name":"huangtianhua","email":"tiantian223@163.com","username":"huangtianhua"},"change_message_id":"6a79d649e5a4da74d9cb726339ca0f6c2be42c52","unresolved":false,"context_lines":[{"line_number":165,"context_line":"    def parse(self, stack, snippet):"},{"line_number":166,"context_line":"        return parse(self.functions(), stack, snippet)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    def validate(self, allow_empty\u003dTrue):"},{"line_number":169,"context_line":"        \u0027\u0027\u0027Validate the template."},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        Validates the top-level sections of the template as well as syntax"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWn%2F%2F87A%3D","line":168,"in_reply_to":"AAAAWn%2F%2F9jk%3D","updated":"2014-04-08 09:35:24.000000000","message":"Understand.\nThanks for the explain.","commit_id":"838949e169bc3bab6f566498b2c49325dc384a91"},{"author":{"_account_id":8289,"name":"huangtianhua","email":"tiantian223@163.com","username":"huangtianhua"},"change_message_id":"85f00f2a4d93f630bc3509df7f72029eb3fe6f0c","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        \u0027\u0027\u0027Validate the template."},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        Validates the top-level sections of the template as well as syntax"},{"line_number":172,"context_line":"        inside select sections. Some section are not checked here but in"},{"line_number":173,"context_line":"        code parts that are responsible for working with the respective"},{"line_number":174,"context_line":"        sections (e.g. parameters are check by parameters schema class)."},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWn%2F%2F%2BNs%3D","line":172,"updated":"2014-04-08 07:07:54.000000000","message":"S/Some section /Some sections","commit_id":"838949e169bc3bab6f566498b2c49325dc384a91"},{"author":{"_account_id":7193,"name":"Thomas Spatzier","email":"thomas.spatzier@icloud.com","username":"thomasspatzier"},"change_message_id":"1d457a8fa23e23d1b89278da83526b24563e366e","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        \u0027\u0027\u0027Validate the template."},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        Validates the top-level sections of the template as well as syntax"},{"line_number":172,"context_line":"        inside select sections. Some section are not checked here but in"},{"line_number":173,"context_line":"        code parts that are responsible for working with the respective"},{"line_number":174,"context_line":"        sections (e.g. parameters are check by parameters schema class)."},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWn%2F%2F9jM%3D","line":172,"in_reply_to":"AAAAWn%2F%2F%2BNs%3D","updated":"2014-04-08 08:25:36.000000000","message":"Good spotting. I will fix it in the next patch set - have to do a rebase anyway.","commit_id":"838949e169bc3bab6f566498b2c49325dc384a91"},{"author":{"_account_id":8289,"name":"huangtianhua","email":"tiantian223@163.com","username":"huangtianhua"},"change_message_id":"6a79d649e5a4da74d9cb726339ca0f6c2be42c52","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        \u0027\u0027\u0027Validate the template."},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        Validates the top-level sections of the template as well as syntax"},{"line_number":172,"context_line":"        inside select sections. Some section are not checked here but in"},{"line_number":173,"context_line":"        code parts that are responsible for working with the respective"},{"line_number":174,"context_line":"        sections (e.g. parameters are check by parameters schema class)."},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWn%2F%2F86I%3D","line":172,"in_reply_to":"AAAAWn%2F%2F9jM%3D","updated":"2014-04-08 09:35:24.000000000","message":"I check it out because you need to rebase:)","commit_id":"838949e169bc3bab6f566498b2c49325dc384a91"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"965d6df39141a62411ff9da23cbdfb5dbe5f8dc7","unresolved":false,"context_lines":[{"line_number":184,"context_line":"        tmpl_resources \u003d self[self.RESOURCES]"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"        if not allow_empty and not tmpl_resources:"},{"line_number":187,"context_line":"            message \u003d _(\u0027The template is invalid. A Resources section with at \u0027"},{"line_number":188,"context_line":"                        \u0027least one resource must be defined.\u0027)"},{"line_number":189,"context_line":"            raise exception.StackValidationFailed(message\u003dmessage)"},{"line_number":190,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAAW3%2F%2F2YY%3D","line":187,"updated":"2014-04-09 23:30:59.000000000","message":"Bonus points for using string formatting and self.RESOURCES to insert the section name.","commit_id":"b6e7e9d18b59ee662412157c2b083ced8110b839"}]}
