)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":19985,"name":"Ryosuke Mizuno","email":"r-mizuno@rs.jp.nec.com","username":"r-mizuno"},"change_message_id":"30db558fb75a55d96c1b7edd654d64621dd51368","unresolved":false,"context_lines":[{"line_number":10,"context_line":"This operation is done in atomic operation, with just one delete request"},{"line_number":11,"context_line":"to the backend. It keeps the normal delete behavior that requires the"},{"line_number":12,"context_line":"whole subtree disabled. Otherwise, no project is deleted."},{"line_number":13,"context_line":"A new parameter \"parent_project_id\" was also added to the test helper method"},{"line_number":14,"context_line":"_create_projects_hierarchy to ease the creation of sub-hierarchies."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Co-Authored-By: Henrique Truta \u003chenrique@lsd.ufcg.edu.br\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"5a5ae5dd_dbd0db21","line":13,"range":{"start_line":13,"start_character":0,"end_line":13,"end_character":76},"updated":"2016-02-05 02:21:22.000000000","message":"new line at 72 characters","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"024e782d76a14b6aa84198d0848ac9d0368b4112","unresolved":false,"context_lines":[{"line_number":10,"context_line":"This operation is done in atomic operation, with just one delete request"},{"line_number":11,"context_line":"to the backend. It keeps the normal delete behavior that requires the"},{"line_number":12,"context_line":"whole subtree disabled. Otherwise, no project is deleted."},{"line_number":13,"context_line":"A new parameter \"parent_project_id\" was also added to the test helper method"},{"line_number":14,"context_line":"_create_projects_hierarchy to ease the creation of sub-hierarchies."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Co-Authored-By: Henrique Truta \u003chenrique@lsd.ufcg.edu.br\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"5a5ae5dd_282dff94","line":13,"range":{"start_line":13,"start_character":0,"end_line":13,"end_character":76},"in_reply_to":"5a5ae5dd_dbd0db21","updated":"2016-02-10 19:49:50.000000000","message":"Done","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"}],"keystone/resource/core.py":[{"author":{"_account_id":11428,"name":"Ajaya Agrawal","email":"ajku.agr@gmail.com","username":"ajayaa"},"change_message_id":"df43d68df615df638605e5a9bdd512ae7e7ea151","unresolved":false,"context_lines":[{"line_number":240,"context_line":"            self.delete_project(child_id)"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"        if cascade:"},{"line_number":243,"context_line":"            self._assert_whole_subtree_is_disabled(tenant_id)"},{"line_number":244,"context_line":"            subtree \u003d self.get_projects_in_subtree_as_ids(tenant_id)"},{"line_number":245,"context_line":"            for child_id in subtree:"},{"line_number":246,"context_line":"                child_subtree \u003d subtree[child_id]"}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_b904237e","line":243,"updated":"2015-11-16 10:30:18.000000000","message":"The message in exception raised in _assert_whole_subtree_is_disabled says \"cannot disable project...\" which is not appropriate for this case. So please change the message.\n\nI would not have made _delete_projects_cascade inner so that it can be tested independently.","commit_id":"eff72930f6086f9a1d266aebf5e421fa91df08b4"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"af798b82a149d1f8449e9608bffb4210cbb095e7","unresolved":false,"context_lines":[{"line_number":240,"context_line":"            self.delete_project(child_id)"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"        if cascade:"},{"line_number":243,"context_line":"            self._assert_whole_subtree_is_disabled(tenant_id)"},{"line_number":244,"context_line":"            subtree \u003d self.get_projects_in_subtree_as_ids(tenant_id)"},{"line_number":245,"context_line":"            for child_id in subtree:"},{"line_number":246,"context_line":"                child_subtree \u003d subtree[child_id]"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba8a016a_a2544054","line":243,"in_reply_to":"da85f559_b904237e","updated":"2015-11-16 14:31:58.000000000","message":"just changed the message. We are testing it by deleting the whole subtree of projects, as it is done in the delete_domain_contents method.","commit_id":"eff72930f6086f9a1d266aebf5e421fa91df08b4"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"b4850f41c3503d48b0cbe33c2cfac6358e548aa4","unresolved":false,"context_lines":[{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        project \u003d self.driver.get_project(tenant_id)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"        def _delete_projects_cascade(child_id, child_subtree):"},{"line_number":236,"context_line":"            if child_subtree:"},{"line_number":237,"context_line":"                for project_id in child_subtree:"},{"line_number":238,"context_line":"                    project_subtree \u003d child_subtree[project_id]"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba8a016a_e8f22906","line":235,"updated":"2015-11-16 14:53:09.000000000","message":"this is unsafe, you should first get all the IDs in the subtree and perform a single DB operation (the DB will then take care of ACID related issues for you)\n\n(not related to this patch) btw, the way projects are deleted in the domain deletion should be fixed too.","commit_id":"9cfe8eb0bfc8760204436e3ddeb6728afd7bce73"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"749df7afc2aa2fec71f7197bad5fca2fb9eba723","unresolved":false,"context_lines":[{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        project \u003d self.driver.get_project(tenant_id)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"        def _delete_projects_cascade(child_id, child_subtree):"},{"line_number":236,"context_line":"            if child_subtree:"},{"line_number":237,"context_line":"                for project_id in child_subtree:"},{"line_number":238,"context_line":"                    project_subtree \u003d child_subtree[project_id]"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba8a016a_ebd3b836","line":235,"in_reply_to":"ba8a016a_e8f22906","updated":"2015-11-17 18:29:23.000000000","message":"Done.\n\nI\u0027ll make delete_domain_contents use that in another patch. Thanks","commit_id":"9cfe8eb0bfc8760204436e3ddeb6728afd7bce73"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"dc743edc3ce2b5ee5957feb0abe211e4adbd61f5","unresolved":false,"context_lines":[{"line_number":350,"context_line":"            self._assert_whole_subtree_is_disabled(tenant_id, action\u003d\u0027delete\u0027,"},{"line_number":351,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"            # From now on, we\u0027ll use the subtree in two different structure"},{"line_number":354,"context_line":"            # forms: first, the subtree_ids dict, that hierarchically"},{"line_number":355,"context_line":"            # stores the children\u0027s id of each project, and the second is"},{"line_number":356,"context_line":"            # the unstructured dict of the subtree, which we\u0027ll use to get a"}],"source_content_type":"text/x-python","patch_set":6,"id":"7a740942_3faaa81a","line":353,"updated":"2015-12-03 18:32:16.000000000","message":"please change this for a NOTE(name)","commit_id":"4cd75b16f69f3b60e602b5be9d89d6a0ff5f7d8c"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"dc743edc3ce2b5ee5957feb0abe211e4adbd61f5","unresolved":false,"context_lines":[{"line_number":362,"context_line":""},{"line_number":363,"context_line":"            # Recursively traverse the subtree, and create a list that starts"},{"line_number":364,"context_line":"            # on the leaf nodes and ends with the subtree root (the target"},{"line_number":365,"context_line":"            # project), not breaking the parent_id FK."},{"line_number":366,"context_line":"            projects_id_list \u003d []"},{"line_number":367,"context_line":"            for child_id in subtree_ids:"},{"line_number":368,"context_line":"                child_subtree \u003d subtree_ids[child_id]"}],"source_content_type":"text/x-python","patch_set":6,"id":"7a740942_1f680cf5","line":365,"updated":"2015-12-03 18:32:16.000000000","message":"change FK for foreign key","commit_id":"4cd75b16f69f3b60e602b5be9d89d6a0ff5f7d8c"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"664561859b14dbbe533242aa91e4536b483c3cf5","unresolved":false,"context_lines":[{"line_number":389,"context_line":"        # role assignments where the target is the specified project"},{"line_number":390,"context_line":"        assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate()"},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"        project \u003d self.driver.get_project(tenant_id)"},{"line_number":393,"context_line":""},{"line_number":394,"context_line":"        def _get_subtree_ids_ordered(child_id, child_subtree, subtree_dict):"},{"line_number":395,"context_line":"            projects_id_list \u003d []"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a5de9d1_ac9dc35a","line":392,"range":{"start_line":392,"start_character":8,"end_line":392,"end_character":52},"updated":"2016-01-28 22:17:20.000000000","message":"why are do get project instead of using it from L362","commit_id":"35b29b670e1c414df6dcdc2b1481a01962b7b055"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"664561859b14dbbe533242aa91e4536b483c3cf5","unresolved":false,"context_lines":[{"line_number":391,"context_line":""},{"line_number":392,"context_line":"        project \u003d self.driver.get_project(tenant_id)"},{"line_number":393,"context_line":""},{"line_number":394,"context_line":"        def _get_subtree_ids_ordered(child_id, child_subtree, subtree_dict):"},{"line_number":395,"context_line":"            projects_id_list \u003d []"},{"line_number":396,"context_line":"            if child_subtree:"},{"line_number":397,"context_line":"                for project_id in child_subtree:"},{"line_number":398,"context_line":"                    project_subtree \u003d child_subtree[project_id]"},{"line_number":399,"context_line":"                    projects_id_list +\u003d _get_subtree_ids_ordered("},{"line_number":400,"context_line":"                        project_id, project_subtree, subtree_dict)"},{"line_number":401,"context_line":"            self._cleanup_project(child_id, subtree_dict[child_id])"},{"line_number":402,"context_line":"            projects_id_list.append(child_id)"},{"line_number":403,"context_line":"            return projects_id_list"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":"        if cascade:"},{"line_number":406,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(tenant_id)"},{"line_number":407,"context_line":"            self._assert_whole_subtree_is_disabled(tenant_id, action\u003d\u0027delete\u0027,"},{"line_number":408,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":409,"context_line":""},{"line_number":410,"context_line":"            # From now on, we\u0027ll use the subtree in two different structure"},{"line_number":411,"context_line":"            # forms: first, the subtree_ids dict, that hierarchically"},{"line_number":412,"context_line":"            # stores the children\u0027s id of each project, and the second is"},{"line_number":413,"context_line":"            # the unstructured dict of the subtree, which we\u0027ll use to get a"},{"line_number":414,"context_line":"            # project ref from its id without needing to access the backend or"},{"line_number":415,"context_line":"            # to iterate in the subtree_list. This project ref will be used in"},{"line_number":416,"context_line":"            # the cleanup method."},{"line_number":417,"context_line":"            subtree_ids \u003d self.get_projects_in_subtree_as_ids(tenant_id)"},{"line_number":418,"context_line":"            subtree_dict \u003d {p[\u0027id\u0027]: p for p in subtree_list}"},{"line_number":419,"context_line":""},{"line_number":420,"context_line":"            # Recursively traverse the subtree, and create a list that starts"},{"line_number":421,"context_line":"            # on the leaf nodes and ends with the subtree root (the target"},{"line_number":422,"context_line":"            # project), not breaking the parent_id FK."},{"line_number":423,"context_line":"            projects_id_list \u003d []"},{"line_number":424,"context_line":"            for child_id in subtree_ids:"},{"line_number":425,"context_line":"                child_subtree \u003d subtree_ids[child_id]"},{"line_number":426,"context_line":"                projects_id_list +\u003d _get_subtree_ids_ordered("},{"line_number":427,"context_line":"                    child_id, child_subtree, subtree_dict)"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"            self._cleanup_project(tenant_id, project, initiator)"},{"line_number":430,"context_line":"            projects_id_list.append(tenant_id)"},{"line_number":431,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_id_list)"},{"line_number":432,"context_line":""},{"line_number":433,"context_line":"        else:"},{"line_number":434,"context_line":"            self._cleanup_project(tenant_id, project, initiator)"},{"line_number":435,"context_line":"            ret \u003d self.driver.delete_project(tenant_id)"},{"line_number":436,"context_line":"        return ret"},{"line_number":437,"context_line":""},{"line_number":438,"context_line":"    def _filter_projects_list(self, projects_list, user_id):"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a5de9d1_8cb1e7e3","line":435,"range":{"start_line":394,"start_character":8,"end_line":435,"end_character":55},"updated":"2016-01-28 22:17:20.000000000","message":"http://paste.openstack.org/show/485333/\n\nSo me and Samuel looked at your code and were able to optimize it.  We still are concerned that the role assignments are removed before the projects are deleted, since there is a chance that when you are deleting the projects the operation fails then you are left with projects with no role assignments.","commit_id":"35b29b670e1c414df6dcdc2b1481a01962b7b055"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"47af3b147f713a442e3f437440963f9d2fe7fc6c","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":383,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"            for prj in project_list:"},{"line_number":386,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":387,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":388,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a5ae5dd_1917cd55","line":385,"range":{"start_line":385,"start_character":16,"end_line":385,"end_character":19},"updated":"2016-02-09 05:01:36.000000000","message":"use project not prj","commit_id":"e9aa810075b4687b270a4fb835e0a0ea13357d88"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"47af3b147f713a442e3f437440963f9d2fe7fc6c","unresolved":false,"context_lines":[{"line_number":386,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":387,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":388,"context_line":"        else:"},{"line_number":389,"context_line":"            project_user_ids \u003d ("},{"line_number":390,"context_line":"                self.assignment_api.list_user_ids_for_project(project_id))"},{"line_number":391,"context_line":"            for user_id in project_user_ids:"},{"line_number":392,"context_line":"                payload \u003d {\u0027user_id\u0027: user_id, \u0027project_id\u0027: project_id}"},{"line_number":393,"context_line":"                self._emit_invalidate_user_project_tokens_notification(payload)"},{"line_number":394,"context_line":"            ret \u003d self.driver.delete_project(project_id)"},{"line_number":395,"context_line":"            self.assignment_api.delete_project_assignments(project_id)"},{"line_number":396,"context_line":"            self.get_project.invalidate(self, project_id)"},{"line_number":397,"context_line":"            self.get_project_by_name.invalidate(self, project[\u0027name\u0027],"},{"line_number":398,"context_line":"                                                project[\u0027domain_id\u0027])"},{"line_number":399,"context_line":"            self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":400,"context_line":"            notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"            # Invalidate user role assignments cache region, as it may"},{"line_number":403,"context_line":"            # be caching role assignments where the target is"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a5ae5dd_3935e9f6","line":400,"range":{"start_line":389,"start_character":12,"end_line":400,"end_character":77},"updated":"2016-02-09 05:01:36.000000000","message":"why not just call _cleanup_project and issue the delete last?","commit_id":"e9aa810075b4687b270a4fb835e0a0ea13357d88"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"47af3b147f713a442e3f437440963f9d2fe7fc6c","unresolved":false,"context_lines":[{"line_number":399,"context_line":"            self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":400,"context_line":"            notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"            # Invalidate user role assignments cache region, as it may"},{"line_number":403,"context_line":"            # be caching role assignments where the target is"},{"line_number":404,"context_line":"            # the specified project"},{"line_number":405,"context_line":"            assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate()"},{"line_number":406,"context_line":"        return ret"},{"line_number":407,"context_line":""},{"line_number":408,"context_line":"    def _filter_projects_list(self, projects_list, user_id):"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a5ae5dd_1904adc4","line":405,"range":{"start_line":402,"start_character":12,"end_line":405,"end_character":63},"updated":"2016-02-09 05:01:36.000000000","message":"should this be in cleanup too?","commit_id":"e9aa810075b4687b270a4fb835e0a0ea13357d88"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"963e37620420206ce5bb57e769eaeeaa8b53c805","unresolved":false,"context_lines":[{"line_number":372,"context_line":"            raise exception.ForbiddenAction("},{"line_number":373,"context_line":"                action\u003d_(\u0027cannot delete the project %s since it is not \u0027"},{"line_number":374,"context_line":"                         \u0027a leaf in the hierarchy. Use the cascade option \u0027"},{"line_number":375,"context_line":"                         \u0027if you want to delete a whole subtree.\u0027) % project_id)"},{"line_number":376,"context_line":""},{"line_number":377,"context_line":"        if cascade:"},{"line_number":378,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)[::-1]"}],"source_content_type":"text/x-python","patch_set":19,"id":"7a5de9d1_f3edacb7","line":375,"range":{"start_line":375,"start_character":0,"end_line":375,"end_character":80},"updated":"2016-01-29 17:53:43.000000000","message":"sorry i did a rebase on your project because you had merge conflicts.... i didn\u0027t run the linter after i did a rebase:/ and this line is too long.  80 \u003e 79","commit_id":"dd23c8bca3f8f665b69346d878da6c640e39aa36"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c0e830098646d819a015a134f140e4cc79b6f392","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                    action\u003d_(\u0027cannot enable project %s since it has \u0027"},{"line_number":277,"context_line":"                             \u0027disabled parents\u0027) % project_id)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_a2c35088","line":279,"range":{"start_line":279,"start_character":60,"end_line":279,"end_character":76},"updated":"2016-02-05 16:43:15.000000000","message":"What is the point of passing in the action?  If someone passes in the action\u003d\u0027enabled\u0027  the error is going to be confusing since it will read:\n\n\u0027cannot enable project 23544356 since its subtree contains enabled projects\u0027","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"7da371e13afa4b121f347092684bf8432878a54f","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                    action\u003d_(\u0027cannot enable project %s since it has \u0027"},{"line_number":277,"context_line":"                             \u0027disabled parents\u0027) % project_id)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_75ba6fc2","line":279,"range":{"start_line":279,"start_character":60,"end_line":279,"end_character":76},"in_reply_to":"5a5ae5dd_1c049bc4","updated":"2016-02-09 14:08:47.000000000","message":"Ahh i didn\u0027t see it on L380 (and i commented a line above it lol).  Thanks steve. That makes sense that you are passing in the action of `delete`.","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"2b2ddc6d4487ff32e1ddf39d8b68101945d1847d","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                    action\u003d_(\u0027cannot enable project %s since it has \u0027"},{"line_number":277,"context_line":"                             \u0027disabled parents\u0027) % project_id)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_1c049bc4","line":279,"range":{"start_line":279,"start_character":60,"end_line":279,"end_character":76},"in_reply_to":"5a5ae5dd_a2c35088","updated":"2016-02-09 05:05:19.000000000","message":"tom, other functions were calling this with, and expected the message to be disabled; by making this change, we are allowing for the change on line 380, to pass in delete, and not affect the methods that don\u0027t have this argument defined.","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c0e830098646d819a015a134f140e4cc79b6f392","unresolved":false,"context_lines":[{"line_number":347,"context_line":"        return ret"},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"    def _cleanup_project(self, project_id, project, initiator\u003dNone):"},{"line_number":350,"context_line":"        project_user_ids \u003d ("},{"line_number":351,"context_line":"            self.assignment_api.list_user_ids_for_project(project_id))"},{"line_number":352,"context_line":"        for user_id in project_user_ids:"},{"line_number":353,"context_line":"            payload \u003d {\u0027user_id\u0027: user_id, \u0027project_id\u0027: project_id}"},{"line_number":354,"context_line":"            self._emit_invalidate_user_project_tokens_notification(payload)"},{"line_number":355,"context_line":"        self.assignment_api.delete_project_assignments(project_id)"},{"line_number":356,"context_line":"        self.get_project.invalidate(self, project_id)"},{"line_number":357,"context_line":"        self.get_project_by_name.invalidate(self, project[\u0027name\u0027],"},{"line_number":358,"context_line":"                                            project[\u0027domain_id\u0027])"},{"line_number":359,"context_line":"        self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":360,"context_line":"        notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"    def delete_project(self, project_id, initiator\u003dNone, cascade\u003dFalse):"},{"line_number":363,"context_line":"        # Use the driver directly to prevent using old cached value."}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_a24a7024","line":360,"range":{"start_line":350,"start_character":8,"end_line":360,"end_character":73},"updated":"2016-02-05 16:43:15.000000000","message":"Maybe add some comments in here on everything that is going on.","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"2b2ddc6d4487ff32e1ddf39d8b68101945d1847d","unresolved":false,"context_lines":[{"line_number":347,"context_line":"        return ret"},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"    def _cleanup_project(self, project_id, project, initiator\u003dNone):"},{"line_number":350,"context_line":"        project_user_ids \u003d ("},{"line_number":351,"context_line":"            self.assignment_api.list_user_ids_for_project(project_id))"},{"line_number":352,"context_line":"        for user_id in project_user_ids:"},{"line_number":353,"context_line":"            payload \u003d {\u0027user_id\u0027: user_id, \u0027project_id\u0027: project_id}"},{"line_number":354,"context_line":"            self._emit_invalidate_user_project_tokens_notification(payload)"},{"line_number":355,"context_line":"        self.assignment_api.delete_project_assignments(project_id)"},{"line_number":356,"context_line":"        self.get_project.invalidate(self, project_id)"},{"line_number":357,"context_line":"        self.get_project_by_name.invalidate(self, project[\u0027name\u0027],"},{"line_number":358,"context_line":"                                            project[\u0027domain_id\u0027])"},{"line_number":359,"context_line":"        self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":360,"context_line":"        notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"    def delete_project(self, project_id, initiator\u003dNone, cascade\u003dFalse):"},{"line_number":363,"context_line":"        # Use the driver directly to prevent using old cached value."}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_9cf88bc6","line":360,"range":{"start_line":350,"start_character":8,"end_line":360,"end_character":73},"in_reply_to":"5a5ae5dd_a24a7024","updated":"2016-02-09 05:05:19.000000000","message":"this is copy and paste of what was going on before, and it\u0027s pretty self explanatory","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c0e830098646d819a015a134f140e4cc79b6f392","unresolved":false,"context_lines":[{"line_number":376,"context_line":"                % project_id)"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"        if cascade:"},{"line_number":379,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)[::-1]"},{"line_number":380,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":381,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":382,"context_line":"            project_list \u003d subtree_list + [project]"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_c20c4cee","line":379,"range":{"start_line":379,"start_character":12,"end_line":379,"end_character":74},"updated":"2016-02-05 16:43:15.000000000","message":"comment: get reversed list of project subtree","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"024e782d76a14b6aa84198d0848ac9d0368b4112","unresolved":false,"context_lines":[{"line_number":376,"context_line":"                % project_id)"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"        if cascade:"},{"line_number":379,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)[::-1]"},{"line_number":380,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":381,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":382,"context_line":"            project_list \u003d subtree_list + [project]"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_1bbd4f68","line":379,"range":{"start_line":379,"start_character":12,"end_line":379,"end_character":74},"in_reply_to":"5a5ae5dd_c20c4cee","updated":"2016-02-10 19:49:50.000000000","message":"Done","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"2b2ddc6d4487ff32e1ddf39d8b68101945d1847d","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":383,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"            for prj in project_list:"},{"line_number":386,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":387,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":388,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_fce09ffc","line":385,"range":{"start_line":385,"start_character":16,"end_line":385,"end_character":19},"updated":"2016-02-09 05:05:19.000000000","message":"use project, no need to shorten","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"024e782d76a14b6aa84198d0848ac9d0368b4112","unresolved":false,"context_lines":[{"line_number":382,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":383,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"},{"line_number":384,"context_line":""},{"line_number":385,"context_line":"            for prj in project_list:"},{"line_number":386,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":387,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":388,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_3b35abf6","line":385,"range":{"start_line":385,"start_character":16,"end_line":385,"end_character":19},"in_reply_to":"5a5ae5dd_fce09ffc","updated":"2016-02-10 19:49:50.000000000","message":"we already have a \"project\" variable in this method.","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"2b2ddc6d4487ff32e1ddf39d8b68101945d1847d","unresolved":false,"context_lines":[{"line_number":386,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":387,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":388,"context_line":"        else:"},{"line_number":389,"context_line":"            project_user_ids \u003d ("},{"line_number":390,"context_line":"                self.assignment_api.list_user_ids_for_project(project_id))"},{"line_number":391,"context_line":"            for user_id in project_user_ids:"},{"line_number":392,"context_line":"                payload \u003d {\u0027user_id\u0027: user_id, \u0027project_id\u0027: project_id}"},{"line_number":393,"context_line":"                self._emit_invalidate_user_project_tokens_notification(payload)"},{"line_number":394,"context_line":"            ret \u003d self.driver.delete_project(project_id)"},{"line_number":395,"context_line":"            self.assignment_api.delete_project_assignments(project_id)"},{"line_number":396,"context_line":"            self.get_project.invalidate(self, project_id)"},{"line_number":397,"context_line":"            self.get_project_by_name.invalidate(self, project[\u0027name\u0027],"},{"line_number":398,"context_line":"                                                project[\u0027domain_id\u0027])"},{"line_number":399,"context_line":"            self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":400,"context_line":"            notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"            # Invalidate user role assignments cache region, as it may"},{"line_number":403,"context_line":"            # be caching role assignments where the target is"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_bc1c6714","line":400,"range":{"start_line":389,"start_character":12,"end_line":400,"end_character":77},"updated":"2016-02-09 05:05:19.000000000","message":"same comment as ps18, use _cleanup and call \nself.driver.delete after it","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"024e782d76a14b6aa84198d0848ac9d0368b4112","unresolved":false,"context_lines":[{"line_number":386,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":387,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":388,"context_line":"        else:"},{"line_number":389,"context_line":"            project_user_ids \u003d ("},{"line_number":390,"context_line":"                self.assignment_api.list_user_ids_for_project(project_id))"},{"line_number":391,"context_line":"            for user_id in project_user_ids:"},{"line_number":392,"context_line":"                payload \u003d {\u0027user_id\u0027: user_id, \u0027project_id\u0027: project_id}"},{"line_number":393,"context_line":"                self._emit_invalidate_user_project_tokens_notification(payload)"},{"line_number":394,"context_line":"            ret \u003d self.driver.delete_project(project_id)"},{"line_number":395,"context_line":"            self.assignment_api.delete_project_assignments(project_id)"},{"line_number":396,"context_line":"            self.get_project.invalidate(self, project_id)"},{"line_number":397,"context_line":"            self.get_project_by_name.invalidate(self, project[\u0027name\u0027],"},{"line_number":398,"context_line":"                                                project[\u0027domain_id\u0027])"},{"line_number":399,"context_line":"            self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":400,"context_line":"            notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"            # Invalidate user role assignments cache region, as it may"},{"line_number":403,"context_line":"            # be caching role assignments where the target is"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_a678a2c5","line":400,"range":{"start_line":389,"start_character":12,"end_line":400,"end_character":77},"in_reply_to":"5a5ae5dd_bc1c6714","updated":"2016-02-10 19:49:50.000000000","message":"Done","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"2b2ddc6d4487ff32e1ddf39d8b68101945d1847d","unresolved":false,"context_lines":[{"line_number":399,"context_line":"            self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":400,"context_line":"            notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"            # Invalidate user role assignments cache region, as it may"},{"line_number":403,"context_line":"            # be caching role assignments where the target is"},{"line_number":404,"context_line":"            # the specified project"},{"line_number":405,"context_line":"            assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate()"},{"line_number":406,"context_line":"        return ret"},{"line_number":407,"context_line":""},{"line_number":408,"context_line":"    def _filter_projects_list(self, projects_list, user_id):"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_1cd25b35","line":405,"range":{"start_line":402,"start_character":12,"end_line":405,"end_character":63},"updated":"2016-02-09 05:05:19.000000000","message":"shouldn\u0027t this be in the cleanup?","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"024e782d76a14b6aa84198d0848ac9d0368b4112","unresolved":false,"context_lines":[{"line_number":399,"context_line":"            self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":400,"context_line":"            notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"            # Invalidate user role assignments cache region, as it may"},{"line_number":403,"context_line":"            # be caching role assignments where the target is"},{"line_number":404,"context_line":"            # the specified project"},{"line_number":405,"context_line":"            assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate()"},{"line_number":406,"context_line":"        return ret"},{"line_number":407,"context_line":""},{"line_number":408,"context_line":"    def _filter_projects_list(self, projects_list, user_id):"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_c6735ee6","line":405,"range":{"start_line":402,"start_character":12,"end_line":405,"end_character":63},"in_reply_to":"5a5ae5dd_1cd25b35","updated":"2016-02-10 19:49:50.000000000","message":"Done","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c0e830098646d819a015a134f140e4cc79b6f392","unresolved":false,"context_lines":[{"line_number":980,"context_line":"            raise exception.DomainNotFound(domain_id\u003ddomain_id)"},{"line_number":981,"context_line":""},{"line_number":982,"context_line":""},{"line_number":983,"context_line":"class ResourceDriverV8(ResourceDriverBase):"},{"line_number":984,"context_line":"    \"\"\"Removed or redefined methods from V8."},{"line_number":985,"context_line":""},{"line_number":986,"context_line":"    Move the abstract methods of any methods removed or modified in later"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_62feb8af","line":983,"range":{"start_line":983,"start_character":6,"end_line":983,"end_character":22},"updated":"2016-02-05 16:43:15.000000000","message":"shouldn\u0027t we add the abstract delete_project() here since you are redefining the method?","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"024e782d76a14b6aa84198d0848ac9d0368b4112","unresolved":false,"context_lines":[{"line_number":980,"context_line":"            raise exception.DomainNotFound(domain_id\u003ddomain_id)"},{"line_number":981,"context_line":""},{"line_number":982,"context_line":""},{"line_number":983,"context_line":"class ResourceDriverV8(ResourceDriverBase):"},{"line_number":984,"context_line":"    \"\"\"Removed or redefined methods from V8."},{"line_number":985,"context_line":""},{"line_number":986,"context_line":"    Move the abstract methods of any methods removed or modified in later"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_46352ef5","line":983,"range":{"start_line":983,"start_character":6,"end_line":983,"end_character":22},"in_reply_to":"5a5ae5dd_62feb8af","updated":"2016-02-10 19:49:50.000000000","message":"this method was only changed in the manager layer. Versioning here only applies for driver changes. The delete_method on the driver layer was not changed.","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c0e830098646d819a015a134f140e4cc79b6f392","unresolved":false,"context_lines":[{"line_number":1002,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":1003,"context_line":""},{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"class ResourceDriverV9(ResourceDriverBase):"},{"line_number":1006,"context_line":"    \"\"\"New or redefined methods from V8."},{"line_number":1007,"context_line":""},{"line_number":1008,"context_line":"    Add any new V9 abstract methods (or those with modified signatures) to"}],"source_content_type":"text/x-python","patch_set":21,"id":"5a5ae5dd_c223ec56","line":1005,"range":{"start_line":1005,"start_character":6,"end_line":1005,"end_character":22},"updated":"2016-02-05 16:43:15.000000000","message":"ditto","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"024e782d76a14b6aa84198d0848ac9d0368b4112","unresolved":false,"context_lines":[{"line_number":1002,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":1003,"context_line":""},{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"class ResourceDriverV9(ResourceDriverBase):"},{"line_number":1006,"context_line":"    \"\"\"New or redefined methods from V8."},{"line_number":1007,"context_line":""},{"line_number":1008,"context_line":"    Add any new V9 abstract methods (or those with modified signatures) to"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a57f1b5_e63bfae9","line":1005,"range":{"start_line":1005,"start_character":6,"end_line":1005,"end_character":22},"in_reply_to":"5a5ae5dd_c223ec56","updated":"2016-02-10 19:49:50.000000000","message":"ditto","commit_id":"05c8ee86f3e15567201592d7c6b5ed5aca734a90"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"348ee0ae542e6351e9df420e27f249a5e0122626","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        if cascade:"},{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the roots."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)[::-1]"},{"line_number":386,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":387,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":388,"context_line":"            project_list \u003d subtree_list + [project]"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a57f1b5_2c19f088","line":385,"range":{"start_line":385,"start_character":68,"end_line":385,"end_character":74},"updated":"2016-02-10 21:28:14.000000000","message":"o_O","commit_id":"a31fe2a675fdd13d5b4e2cc6e7e2fe2fc58a1c04"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"0c429b952a4d89e4bb5cb9abaeb8a1b779015ffc","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        if cascade:"},{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the roots."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)[::-1]"},{"line_number":386,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":387,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":388,"context_line":"            project_list \u003d subtree_list + [project]"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a57f1b5_a7ff39a9","line":385,"range":{"start_line":385,"start_character":68,"end_line":385,"end_character":74},"in_reply_to":"3a57f1b5_2c19f088","updated":"2016-02-10 21:32:35.000000000","message":"that\u0027s just how crazy python slices are :P","commit_id":"a31fe2a675fdd13d5b4e2cc6e7e2fe2fc58a1c04"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"acaf60d65b5fb7eac3d721df5af8d8c936de32ab","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        if cascade:"},{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the roots."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)[::-1]"},{"line_number":386,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":387,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":388,"context_line":"            project_list \u003d subtree_list + [project]"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a57f1b5_a71659ef","line":385,"range":{"start_line":385,"start_character":68,"end_line":385,"end_character":74},"in_reply_to":"3a57f1b5_2c19f088","updated":"2016-02-10 21:32:54.000000000","message":"we can use list.reverse() instead of this.\n\nhttps://docs.python.org/2/tutorial/datastructures.html","commit_id":"a31fe2a675fdd13d5b4e2cc6e7e2fe2fc58a1c04"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"25bc8d07e89d6d5139e32f8eaa262fb94e4d987d","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        if cascade:"},{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the roots."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)[::-1]"},{"line_number":386,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":387,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":388,"context_line":"            project_list \u003d subtree_list + [project]"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a57f1b5_e278bf2d","line":385,"range":{"start_line":385,"start_character":68,"end_line":385,"end_character":74},"in_reply_to":"3a57f1b5_a71659ef","updated":"2016-02-10 21:51:11.000000000","message":"++","commit_id":"a31fe2a675fdd13d5b4e2cc6e7e2fe2fc58a1c04"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"5553d0603e6174c57149de160710bf330ba9fa03","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        if cascade:"},{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the roots."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)[::-1]"},{"line_number":386,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":387,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":388,"context_line":"            project_list \u003d subtree_list + [project]"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a57f1b5_b2152e4a","line":385,"range":{"start_line":385,"start_character":68,"end_line":385,"end_character":74},"in_reply_to":"3a57f1b5_e278bf2d","updated":"2016-02-11 00:41:44.000000000","message":"Done","commit_id":"a31fe2a675fdd13d5b4e2cc6e7e2fe2fc58a1c04"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"348ee0ae542e6351e9df420e27f249a5e0122626","unresolved":false,"context_lines":[{"line_number":390,"context_line":""},{"line_number":391,"context_line":"            for prj in project_list:"},{"line_number":392,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":393,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":394,"context_line":"        else:"},{"line_number":395,"context_line":"            self._cleanup_project(project_id, project, initiator)"},{"line_number":396,"context_line":"            ret \u003d self.driver.delete_project(project_id)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a57f1b5_2c4b3089","line":393,"range":{"start_line":393,"start_character":12,"end_line":393,"end_character":68},"updated":"2016-02-10 21:28:14.000000000","message":"now i wonder why we even implemented this function, we could have just called delete N times.","commit_id":"a31fe2a675fdd13d5b4e2cc6e7e2fe2fc58a1c04"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"0c429b952a4d89e4bb5cb9abaeb8a1b779015ffc","unresolved":false,"context_lines":[{"line_number":390,"context_line":""},{"line_number":391,"context_line":"            for prj in project_list:"},{"line_number":392,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"},{"line_number":393,"context_line":"            ret \u003d self.driver.delete_projects_from_ids(projects_ids)"},{"line_number":394,"context_line":"        else:"},{"line_number":395,"context_line":"            self._cleanup_project(project_id, project, initiator)"},{"line_number":396,"context_line":"            ret \u003d self.driver.delete_project(project_id)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a57f1b5_07f40df0","line":393,"range":{"start_line":393,"start_character":12,"end_line":393,"end_character":68},"in_reply_to":"3a57f1b5_2c4b3089","updated":"2016-02-10 21:32:35.000000000","message":"one of the premise of the spec was to make this deletion in an atomic way. calling it N times wouldn\u0027t guarantee that","commit_id":"a31fe2a675fdd13d5b4e2cc6e7e2fe2fc58a1c04"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"74503d9cbcbaf630a64a5479a55c2da27528e741","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                    action\u003d_(\u0027cannot enable project %s since it has \u0027"},{"line_number":277,"context_line":"                             \u0027disabled parents\u0027) % project_id)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_98d133d0","line":279,"range":{"start_line":279,"start_character":60,"end_line":279,"end_character":76},"updated":"2016-02-11 01:37:59.000000000","message":"Is there any other way to re-use this method without the need of a string parameter to only be put in the error message ?\n\nWhat about changing the error message to:\n\n    \"Project %(project_id)s contains enabled projects in its subtree\"\n\nThe action is obvious from the API being used:\n\n    DELETE /projects/x\n    Forbidden: Project X contains enabled projects in its subtree\n\n    UPDATE /projects/x (disable)\n    Forbidden: Project X contains enabled projects in its subtree\n\nWhat do you think ?","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"218d527005d78b2456002bff56329dcfc704b800","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                    action\u003d_(\u0027cannot enable project %s since it has \u0027"},{"line_number":277,"context_line":"                             \u0027disabled parents\u0027) % project_id)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_1cc75746","line":279,"range":{"start_line":279,"start_character":60,"end_line":279,"end_character":76},"in_reply_to":"3a57f1b5_058b82c4","updated":"2016-02-11 14:07:54.000000000","message":"Done","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"612d93919b1a4666c00009dbbee2b6a5b9ee0919","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                    action\u003d_(\u0027cannot enable project %s since it has \u0027"},{"line_number":277,"context_line":"                             \u0027disabled parents\u0027) % project_id)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_c541030d","line":279,"range":{"start_line":279,"start_character":60,"end_line":279,"end_character":76},"in_reply_to":"3a57f1b5_98d133d0","updated":"2016-02-11 02:31:33.000000000","message":"Actually, I\u0027d rather have this information in the log message. If one wants, for example, a procedure that automatically disables and then deletes it, he\u0027ll be able to specifically know which operation failed. Let\u0027s put information on the logs :)","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ef1914956c56d6afa211542d314f348ac46993c7","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                    action\u003d_(\u0027cannot enable project %s since it has \u0027"},{"line_number":277,"context_line":"                             \u0027disabled parents\u0027) % project_id)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_058b82c4","line":279,"range":{"start_line":279,"start_character":60,"end_line":279,"end_character":76},"in_reply_to":"3a57f1b5_a24e2494","updated":"2016-02-11 13:02:34.000000000","message":"I think an alternative would be to have this method just do the check and not worry about the messaging. Let the caller, that knows the operation to perform, deal with the messaging.","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"631edb7fbac927b7fb9bfab1e51c89ed54647120","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                    action\u003d_(\u0027cannot enable project %s since it has \u0027"},{"line_number":277,"context_line":"                             \u0027disabled parents\u0027) % project_id)"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_a24e2494","line":279,"range":{"start_line":279,"start_character":60,"end_line":279,"end_character":76},"in_reply_to":"3a57f1b5_c541030d","updated":"2016-02-11 12:44:31.000000000","message":"it is good to have more details in the logs, but adding a parameter just for that seems like an overkill here. The HTTP method should be enough to figure out what went wrong.","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ef1914956c56d6afa211542d314f348ac46993c7","unresolved":false,"context_lines":[{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"},{"line_number":283,"context_line":"        for ref in subtree_list:"},{"line_number":284,"context_line":"            if ref.get(\u0027enabled\u0027, True):"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_a54e2e94","line":281,"updated":"2016-02-11 13:02:34.000000000","message":"Why would you ever not pass a subtree_list? I think it should always be passed in.","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"218d527005d78b2456002bff56329dcfc704b800","unresolved":false,"context_lines":[{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _assert_whole_subtree_is_disabled(self, project_id, action\u003d\u0027disable\u0027,"},{"line_number":280,"context_line":"                                          subtree_list\u003dNone):"},{"line_number":281,"context_line":"        if not subtree_list:"},{"line_number":282,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"},{"line_number":283,"context_line":"        for ref in subtree_list:"},{"line_number":284,"context_line":"            if ref.get(\u0027enabled\u0027, True):"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_3c7d736e","line":281,"in_reply_to":"3a57f1b5_a54e2e94","updated":"2016-02-11 14:07:54.000000000","message":"in case the caller didn\u0027t need the subtree yet (like in the update), we can keep this variable local","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"74503d9cbcbaf630a64a5479a55c2da27528e741","unresolved":false,"context_lines":[{"line_number":381,"context_line":""},{"line_number":382,"context_line":"        if cascade:"},{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the roots."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"},{"line_number":386,"context_line":"            subtree_list.reverse()"},{"line_number":387,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_98b053df","line":384,"range":{"start_line":384,"start_character":21,"end_line":384,"end_character":26},"updated":"2016-02-11 01:37:59.000000000","message":"root (singular) in this case","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"612d93919b1a4666c00009dbbee2b6a5b9ee0919","unresolved":false,"context_lines":[{"line_number":381,"context_line":""},{"line_number":382,"context_line":"        if cascade:"},{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the roots."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"},{"line_number":386,"context_line":"            subtree_list.reverse()"},{"line_number":387,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_c55823fd","line":384,"range":{"start_line":384,"start_character":21,"end_line":384,"end_character":26},"in_reply_to":"3a57f1b5_98b053df","updated":"2016-02-11 02:31:33.000000000","message":"Done","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ef1914956c56d6afa211542d314f348ac46993c7","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":388,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":389,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":390,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"            for prj in project_list:"},{"line_number":393,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_283775e4","line":390,"updated":"2016-02-11 13:02:34.000000000","message":"Can this be a generator expression instead of a list comprehension? It seems like a waste to build a new list here.","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"218d527005d78b2456002bff56329dcfc704b800","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            self._assert_whole_subtree_is_disabled(project_id, action\u003d\u0027delete\u0027,"},{"line_number":388,"context_line":"                                                   subtree_list\u003dsubtree_list)"},{"line_number":389,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":390,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"            for prj in project_list:"},{"line_number":393,"context_line":"                self._cleanup_project(prj[\u0027id\u0027], prj, initiator)"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_1c3757e4","line":390,"in_reply_to":"3a57f1b5_283775e4","updated":"2016-02-11 14:07:54.000000000","message":"actually, it can\u0027t... we use both lists in the code below. One only with the ids, and other with the project refs themselves","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"3fbfba574d86a6616279fe9434499d494567dc41","unresolved":false,"context_lines":[{"line_number":326,"context_line":"            if (not original_project.get(\u0027is_domain\u0027) and not"},{"line_number":327,"context_line":"                    self._check_whole_subtree_is_disabled(project_id)):"},{"line_number":328,"context_line":"                raise exception.ForbiddenAction("},{"line_number":329,"context_line":"                    action\u003d_(\u0027cannot delete project %(project_id)s since its \u0027"},{"line_number":330,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":331,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":332,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"3a57f1b5_71bb14e6","line":329,"range":{"start_line":329,"start_character":37,"end_line":329,"end_character":43},"updated":"2016-02-11 13:51:00.000000000","message":"s/delete/disable","commit_id":"6e03a1ceccf0b10a789ac94d7fa67801be95c995"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"3fbfba574d86a6616279fe9434499d494567dc41","unresolved":false,"context_lines":[{"line_number":388,"context_line":"            if not self._check_whole_subtree_is_disabled("},{"line_number":389,"context_line":"                    project_id, subtree_list\u003dsubtree_list):"},{"line_number":390,"context_line":"                raise exception.ForbiddenAction("},{"line_number":391,"context_line":"                    action\u003d_(\u0027cannot disable project %(project_id)s since its \u0027"},{"line_number":392,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":393,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":394,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"3a57f1b5_91a570b6","line":391,"updated":"2016-02-11 13:51:00.000000000","message":"s/disable/delete","commit_id":"6e03a1ceccf0b10a789ac94d7fa67801be95c995"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"a60809c16fb38dea0845363aa585ae7dac3e0cd8","unresolved":false,"context_lines":[{"line_number":280,"context_line":"        if not subtree_list:"},{"line_number":281,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"},{"line_number":282,"context_line":"        subtree_enabled \u003d [ref.get(\u0027enabled\u0027, True) for ref in subtree_list]"},{"line_number":283,"context_line":"        # Checks if any project in the subtree is enabled."},{"line_number":284,"context_line":"        return (not any(subtree_enabled))"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"    def update_project(self, project_id, project, initiator\u003dNone):"}],"source_content_type":"text/x-python","patch_set":28,"id":"3a57f1b5_64cc7b6a","line":283,"range":{"start_line":283,"start_character":8,"end_line":283,"end_character":58},"updated":"2016-02-12 13:16:37.000000000","message":"(nit) IMO this comment is not necessary, it\u0027s clear by the method name","commit_id":"4b9a7ada27cd0fe2fe0754b9f6464c6a97198f04"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"229c600827478d7010e49cea239b1c85c0e1d6b9","unresolved":false,"context_lines":[{"line_number":280,"context_line":"        if not subtree_list:"},{"line_number":281,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"},{"line_number":282,"context_line":"        subtree_enabled \u003d [ref.get(\u0027enabled\u0027, True) for ref in subtree_list]"},{"line_number":283,"context_line":"        # Checks if any project in the subtree is enabled."},{"line_number":284,"context_line":"        return (not any(subtree_enabled))"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"    def update_project(self, project_id, project, initiator\u003dNone):"}],"source_content_type":"text/x-python","patch_set":28,"id":"3a57f1b5_0a9d9109","line":283,"range":{"start_line":283,"start_character":8,"end_line":283,"end_character":58},"in_reply_to":"3a57f1b5_64cc7b6a","updated":"2016-02-12 13:35:53.000000000","message":"I\u0027ll remove it","commit_id":"4b9a7ada27cd0fe2fe0754b9f6464c6a97198f04"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"a60809c16fb38dea0845363aa585ae7dac3e0cd8","unresolved":false,"context_lines":[{"line_number":323,"context_line":"            # project acting as a domain to be disabled irrespective of the"},{"line_number":324,"context_line":"            # state of its children. Disabling a project acting as domain"},{"line_number":325,"context_line":"            # effectively disables its children."},{"line_number":326,"context_line":"            if (not original_project.get(\u0027is_domain\u0027) and not"},{"line_number":327,"context_line":"                    self._check_whole_subtree_is_disabled(project_id)):"},{"line_number":328,"context_line":"                raise exception.ForbiddenAction("},{"line_number":329,"context_line":"                    action\u003d_(\u0027cannot delete project %(project_id)s since its \u0027"},{"line_number":330,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":331,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"            self._disable_project(project_id)"},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"        ret \u003d self.driver.update_project(project_id, project)"}],"source_content_type":"text/x-python","patch_set":28,"id":"3a57f1b5_041907d7","line":332,"range":{"start_line":326,"start_character":0,"end_line":332,"end_character":0},"updated":"2016-02-12 13:16:37.000000000","message":"What is this code doing here ? Isn\u0027t this patch for recursive deletion ? This method is update_project","commit_id":"4b9a7ada27cd0fe2fe0754b9f6464c6a97198f04"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"229c600827478d7010e49cea239b1c85c0e1d6b9","unresolved":false,"context_lines":[{"line_number":323,"context_line":"            # project acting as a domain to be disabled irrespective of the"},{"line_number":324,"context_line":"            # state of its children. Disabling a project acting as domain"},{"line_number":325,"context_line":"            # effectively disables its children."},{"line_number":326,"context_line":"            if (not original_project.get(\u0027is_domain\u0027) and not"},{"line_number":327,"context_line":"                    self._check_whole_subtree_is_disabled(project_id)):"},{"line_number":328,"context_line":"                raise exception.ForbiddenAction("},{"line_number":329,"context_line":"                    action\u003d_(\u0027cannot delete project %(project_id)s since its \u0027"},{"line_number":330,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":331,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"            self._disable_project(project_id)"},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"        ret \u003d self.driver.update_project(project_id, project)"}],"source_content_type":"text/x-python","patch_set":28,"id":"3a57f1b5_4ac94925","line":332,"range":{"start_line":326,"start_character":0,"end_line":332,"end_character":0},"in_reply_to":"3a57f1b5_041907d7","updated":"2016-02-12 13:35:53.000000000","message":"it\u0027s just that, as we changed the  _assert_whole_subtree_is_disabled method to  _check_whole_subtree_is_disabled, we needed to propagate its new usage here.","commit_id":"4b9a7ada27cd0fe2fe0754b9f6464c6a97198f04"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"9f797aa1ad6319d3e28b9dc8901213c7bfbdf491","unresolved":false,"context_lines":[{"line_number":325,"context_line":"            if (not original_project.get(\u0027is_domain\u0027) and not"},{"line_number":326,"context_line":"                    self._check_whole_subtree_is_disabled(project_id)):"},{"line_number":327,"context_line":"                raise exception.ForbiddenAction("},{"line_number":328,"context_line":"                    action\u003d_(\u0027cannot delete project %(project_id)s since its \u0027"},{"line_number":329,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":330,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":331,"context_line":""}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_1324e85d","line":328,"range":{"start_line":328,"start_character":37,"end_line":328,"end_character":51},"updated":"2016-02-12 14:24:17.000000000","message":"I don\u0027t think we are deleting a project....just marking it as disabled","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"baa35d813310b4516dd8a87133a08515e2d8ec7b","unresolved":false,"context_lines":[{"line_number":325,"context_line":"            if (not original_project.get(\u0027is_domain\u0027) and not"},{"line_number":326,"context_line":"                    self._check_whole_subtree_is_disabled(project_id)):"},{"line_number":327,"context_line":"                raise exception.ForbiddenAction("},{"line_number":328,"context_line":"                    action\u003d_(\u0027cannot delete project %(project_id)s since its \u0027"},{"line_number":329,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":330,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":331,"context_line":""}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_3e7bebf6","line":328,"range":{"start_line":328,"start_character":37,"end_line":328,"end_character":51},"in_reply_to":"3a57f1b5_1324e85d","updated":"2016-02-12 14:39:14.000000000","message":"Done","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"253e9bf2ce741fea21205743aef2aff36dd2984d","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        for user_id in project_user_ids:"},{"line_number":353,"context_line":"            payload \u003d {\u0027user_id\u0027: user_id, \u0027project_id\u0027: project_id}"},{"line_number":354,"context_line":"            self._emit_invalidate_user_project_tokens_notification(payload)"},{"line_number":355,"context_line":"        self.assignment_api.delete_project_assignments(project_id)"},{"line_number":356,"context_line":"        self.get_project.invalidate(self, project_id)"},{"line_number":357,"context_line":"        self.get_project_by_name.invalidate(self, project[\u0027name\u0027],"},{"line_number":358,"context_line":"                                            project[\u0027domain_id\u0027])"},{"line_number":359,"context_line":"        self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":360,"context_line":"        notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":361,"context_line":"        # Invalidate user role assignments cache region, as it may"},{"line_number":362,"context_line":"        # be caching role assignments where the target is"},{"line_number":363,"context_line":"        # the specified project"},{"line_number":364,"context_line":"        assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate()"},{"line_number":365,"context_line":""},{"line_number":366,"context_line":"    def delete_project(self, project_id, initiator\u003dNone, cascade\u003dFalse):"},{"line_number":367,"context_line":"        # Use the driver directly to prevent using old cached value."}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_0dc84ba7","line":364,"range":{"start_line":355,"start_character":8,"end_line":364,"end_character":59},"updated":"2016-02-12 13:42:58.000000000","message":"This was happening after the project deletion in the previous code, and now it\u0027s before\n\nI don\u0027t think we want to invalidate caches/remove all the stuff if the projects can\u0027t be removed for some reason?","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"9f797aa1ad6319d3e28b9dc8901213c7bfbdf491","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        for user_id in project_user_ids:"},{"line_number":353,"context_line":"            payload \u003d {\u0027user_id\u0027: user_id, \u0027project_id\u0027: project_id}"},{"line_number":354,"context_line":"            self._emit_invalidate_user_project_tokens_notification(payload)"},{"line_number":355,"context_line":"        self.assignment_api.delete_project_assignments(project_id)"},{"line_number":356,"context_line":"        self.get_project.invalidate(self, project_id)"},{"line_number":357,"context_line":"        self.get_project_by_name.invalidate(self, project[\u0027name\u0027],"},{"line_number":358,"context_line":"                                            project[\u0027domain_id\u0027])"},{"line_number":359,"context_line":"        self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":360,"context_line":"        notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":361,"context_line":"        # Invalidate user role assignments cache region, as it may"},{"line_number":362,"context_line":"        # be caching role assignments where the target is"},{"line_number":363,"context_line":"        # the specified project"},{"line_number":364,"context_line":"        assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate()"},{"line_number":365,"context_line":""},{"line_number":366,"context_line":"    def delete_project(self, project_id, initiator\u003dNone, cascade\u003dFalse):"},{"line_number":367,"context_line":"        # Use the driver directly to prevent using old cached value."}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_337fa467","line":364,"range":{"start_line":355,"start_character":8,"end_line":364,"end_character":59},"in_reply_to":"3a57f1b5_0dc84ba7","updated":"2016-02-12 14:24:17.000000000","message":"++","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"baa35d813310b4516dd8a87133a08515e2d8ec7b","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        for user_id in project_user_ids:"},{"line_number":353,"context_line":"            payload \u003d {\u0027user_id\u0027: user_id, \u0027project_id\u0027: project_id}"},{"line_number":354,"context_line":"            self._emit_invalidate_user_project_tokens_notification(payload)"},{"line_number":355,"context_line":"        self.assignment_api.delete_project_assignments(project_id)"},{"line_number":356,"context_line":"        self.get_project.invalidate(self, project_id)"},{"line_number":357,"context_line":"        self.get_project_by_name.invalidate(self, project[\u0027name\u0027],"},{"line_number":358,"context_line":"                                            project[\u0027domain_id\u0027])"},{"line_number":359,"context_line":"        self.credential_api.delete_credentials_for_project(project_id)"},{"line_number":360,"context_line":"        notifications.Audit.deleted(self._PROJECT, project_id, initiator)"},{"line_number":361,"context_line":"        # Invalidate user role assignments cache region, as it may"},{"line_number":362,"context_line":"        # be caching role assignments where the target is"},{"line_number":363,"context_line":"        # the specified project"},{"line_number":364,"context_line":"        assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate()"},{"line_number":365,"context_line":""},{"line_number":366,"context_line":"    def delete_project(self, project_id, initiator\u003dNone, cascade\u003dFalse):"},{"line_number":367,"context_line":"        # Use the driver directly to prevent using old cached value."}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_d9ae71e5","line":364,"range":{"start_line":355,"start_character":8,"end_line":364,"end_character":59},"in_reply_to":"3a57f1b5_337fa467","updated":"2016-02-12 14:39:14.000000000","message":"Done","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"9f797aa1ad6319d3e28b9dc8901213c7bfbdf491","unresolved":false,"context_lines":[{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the root."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"},{"line_number":386,"context_line":"            subtree_list.reverse()"},{"line_number":387,"context_line":"            if not self._check_whole_subtree_is_disabled("},{"line_number":388,"context_line":"                    project_id, subtree_list\u003dsubtree_list):"},{"line_number":389,"context_line":"                raise exception.ForbiddenAction("}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_be435b41","line":386,"range":{"start_line":386,"start_character":12,"end_line":386,"end_character":34},"updated":"2016-02-12 14:24:17.000000000","message":"why do we need the reverse?","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"baa35d813310b4516dd8a87133a08515e2d8ec7b","unresolved":false,"context_lines":[{"line_number":383,"context_line":"            # Getting reversed project\u0027s subtrees list, i.e. from the leaves"},{"line_number":384,"context_line":"            # to the root."},{"line_number":385,"context_line":"            subtree_list \u003d self.list_projects_in_subtree(project_id)"},{"line_number":386,"context_line":"            subtree_list.reverse()"},{"line_number":387,"context_line":"            if not self._check_whole_subtree_is_disabled("},{"line_number":388,"context_line":"                    project_id, subtree_list\u003dsubtree_list):"},{"line_number":389,"context_line":"                raise exception.ForbiddenAction("}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_5ef58754","line":386,"range":{"start_line":386,"start_character":12,"end_line":386,"end_character":34},"in_reply_to":"3a57f1b5_be435b41","updated":"2016-02-12 14:39:14.000000000","message":"because if we start from the root, we\u0027ll break FK of parent_id. I\u0027ll mention it in the comment","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"9f797aa1ad6319d3e28b9dc8901213c7bfbdf491","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            if not self._check_whole_subtree_is_disabled("},{"line_number":388,"context_line":"                    project_id, subtree_list\u003dsubtree_list):"},{"line_number":389,"context_line":"                raise exception.ForbiddenAction("},{"line_number":390,"context_line":"                    action\u003d_(\u0027cannot disable project %(project_id)s since its \u0027"},{"line_number":391,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":392,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":393,"context_line":""}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_b3015408","line":390,"range":{"start_line":390,"start_character":37,"end_line":390,"end_character":44},"updated":"2016-02-12 14:24:17.000000000","message":"I think this one is delete!","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"baa35d813310b4516dd8a87133a08515e2d8ec7b","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            if not self._check_whole_subtree_is_disabled("},{"line_number":388,"context_line":"                    project_id, subtree_list\u003dsubtree_list):"},{"line_number":389,"context_line":"                raise exception.ForbiddenAction("},{"line_number":390,"context_line":"                    action\u003d_(\u0027cannot disable project %(project_id)s since its \u0027"},{"line_number":391,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":392,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":393,"context_line":""}],"source_content_type":"text/x-python","patch_set":29,"id":"3a57f1b5_1e5dcf78","line":390,"range":{"start_line":390,"start_character":37,"end_line":390,"end_character":44},"in_reply_to":"3a57f1b5_b3015408","updated":"2016-02-12 14:39:14.000000000","message":"you\u0027re right, I mixed them","commit_id":"2f27986655eb59373a4f352ac69748a7e6cb5620"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"c3a78bebb504efb13795ca7738c87770f73157d3","unresolved":false,"context_lines":[{"line_number":324,"context_line":"            # effectively disables its children."},{"line_number":325,"context_line":"            if (not original_project.get(\u0027is_domain\u0027) and not"},{"line_number":326,"context_line":"                    self._check_whole_subtree_is_disabled(project_id)):"},{"line_number":327,"context_line":"                raise exception.ForbiddenAction("},{"line_number":328,"context_line":"                    action\u003d_(\u0027cannot disable project %(project_id)s since its \u0027"},{"line_number":329,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":330,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"            self._disable_project(project_id)"},{"line_number":333,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"3a57f1b5_700e60e6","line":330,"range":{"start_line":327,"start_character":16,"end_line":330,"end_character":49},"updated":"2016-02-12 18:56:40.000000000","message":"Is there a test for this?","commit_id":"c25786a50aab54048e34d73f97b46c16d079ac9e"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"7c6fdd792986fd70b7558d7a93c41b89870f63b3","unresolved":false,"context_lines":[{"line_number":324,"context_line":"            # effectively disables its children."},{"line_number":325,"context_line":"            if (not original_project.get(\u0027is_domain\u0027) and not"},{"line_number":326,"context_line":"                    self._check_whole_subtree_is_disabled(project_id)):"},{"line_number":327,"context_line":"                raise exception.ForbiddenAction("},{"line_number":328,"context_line":"                    action\u003d_(\u0027cannot disable project %(project_id)s since its \u0027"},{"line_number":329,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":330,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"            self._disable_project(project_id)"},{"line_number":333,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"3a57f1b5_70b3c00a","line":330,"range":{"start_line":327,"start_character":16,"end_line":330,"end_character":49},"in_reply_to":"3a57f1b5_700e60e6","updated":"2016-02-12 19:00:19.000000000","message":"Yes. Here it is: https://github.com/openstack/keystone/blob/master/keystone/tests/unit/test_backend.py#L3480","commit_id":"c25786a50aab54048e34d73f97b46c16d079ac9e"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"3a19cd9e280791a4949c030cf86cdfb9abed2858","unresolved":false,"context_lines":[{"line_number":324,"context_line":"            # effectively disables its children."},{"line_number":325,"context_line":"            if (not original_project.get(\u0027is_domain\u0027) and not"},{"line_number":326,"context_line":"                    self._check_whole_subtree_is_disabled(project_id)):"},{"line_number":327,"context_line":"                raise exception.ForbiddenAction("},{"line_number":328,"context_line":"                    action\u003d_(\u0027cannot disable project %(project_id)s since its \u0027"},{"line_number":329,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":330,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":331,"context_line":""},{"line_number":332,"context_line":"            self._disable_project(project_id)"},{"line_number":333,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"3a57f1b5_909bdc65","line":330,"range":{"start_line":327,"start_character":16,"end_line":330,"end_character":49},"in_reply_to":"3a57f1b5_70b3c00a","updated":"2016-02-12 19:04:24.000000000","message":"cool! i didn\u0027t realize it was a refactor of the above method.","commit_id":"c25786a50aab54048e34d73f97b46c16d079ac9e"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"0bd922f7c0784285798a50880b676aedd410ef19","unresolved":false,"context_lines":[{"line_number":389,"context_line":"            subtree_list.reverse()"},{"line_number":390,"context_line":"            if not self._check_whole_subtree_is_disabled("},{"line_number":391,"context_line":"                    project_id, subtree_list\u003dsubtree_list):"},{"line_number":392,"context_line":"                raise exception.ForbiddenAction("},{"line_number":393,"context_line":"                    action\u003d_(\u0027cannot delete project %(project_id)s since its \u0027"},{"line_number":394,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":395,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":398,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"}],"source_content_type":"text/x-python","patch_set":30,"id":"3a57f1b5_44eb7813","line":395,"range":{"start_line":392,"start_character":16,"end_line":395,"end_character":49},"updated":"2016-02-12 15:03:40.000000000","message":"This doesn\u0027t look like this is covered in your tests. you should add 1 more test to make sure this works correctly.","commit_id":"c25786a50aab54048e34d73f97b46c16d079ac9e"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"0f86e30c90fb25c7350d7747521eb8407f68fe37","unresolved":false,"context_lines":[{"line_number":389,"context_line":"            subtree_list.reverse()"},{"line_number":390,"context_line":"            if not self._check_whole_subtree_is_disabled("},{"line_number":391,"context_line":"                    project_id, subtree_list\u003dsubtree_list):"},{"line_number":392,"context_line":"                raise exception.ForbiddenAction("},{"line_number":393,"context_line":"                    action\u003d_(\u0027cannot delete project %(project_id)s since its \u0027"},{"line_number":394,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":395,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":398,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"}],"source_content_type":"text/x-python","patch_set":30,"id":"3a57f1b5_e580548d","line":395,"range":{"start_line":392,"start_character":16,"end_line":395,"end_character":49},"in_reply_to":"3a57f1b5_44eb7813","updated":"2016-02-12 18:46:26.000000000","message":"actually, we have. It is the \u0027test_cannot_delete_project_cascade_with_enabled_child\u0027 test","commit_id":"c25786a50aab54048e34d73f97b46c16d079ac9e"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"3a19cd9e280791a4949c030cf86cdfb9abed2858","unresolved":false,"context_lines":[{"line_number":389,"context_line":"            subtree_list.reverse()"},{"line_number":390,"context_line":"            if not self._check_whole_subtree_is_disabled("},{"line_number":391,"context_line":"                    project_id, subtree_list\u003dsubtree_list):"},{"line_number":392,"context_line":"                raise exception.ForbiddenAction("},{"line_number":393,"context_line":"                    action\u003d_(\u0027cannot delete project %(project_id)s since its \u0027"},{"line_number":394,"context_line":"                             \u0027subtree contains enabled projects.\u0027)"},{"line_number":395,"context_line":"                    % {\u0027project_id\u0027: project_id})"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"            project_list \u003d subtree_list + [project]"},{"line_number":398,"context_line":"            projects_ids \u003d [x[\u0027id\u0027] for x in project_list]"}],"source_content_type":"text/x-python","patch_set":30,"id":"3a57f1b5_10a84c76","line":395,"range":{"start_line":392,"start_character":16,"end_line":395,"end_character":49},"in_reply_to":"3a57f1b5_e580548d","updated":"2016-02-12 19:04:24.000000000","message":"thanks!","commit_id":"c25786a50aab54048e34d73f97b46c16d079ac9e"}],"keystone/tests/unit/test_backend.py":[{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"f7a6cd6d8c4ad4d74fd9f6204134bbc632f6ef9f","unresolved":false,"context_lines":[{"line_number":3289,"context_line":"        # Ensuring no project was deleted, not even project2"},{"line_number":3290,"context_line":"        self.resource_api.get_project(root_project[\u0027id\u0027])"},{"line_number":3291,"context_line":"        self.resource_api.get_project(project1[\u0027id\u0027])"},{"line_number":3292,"context_line":"        self.resource_api.get_project(project2[\u0027id\u0027])"},{"line_number":3293,"context_line":""},{"line_number":3294,"context_line":"    def test_hierarchical_projects_crud(self):"},{"line_number":3295,"context_line":"        # create a hierarchy with just a root project (which is a leaf as well)"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a5de9d1_6c6fcb92","line":3292,"updated":"2016-01-28 22:13:25.000000000","message":"I wonder if it wouldn\u0027t be useful to have a more robust test where the projects are in a large tree instead of just in a row.","commit_id":"35b29b670e1c414df6dcdc2b1481a01962b7b055"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"3a7545c8e271551d110ec061ce6d4b0fbe2fec95","unresolved":false,"context_lines":[{"line_number":3289,"context_line":"        # Ensuring no project was deleted, not even project2"},{"line_number":3290,"context_line":"        self.resource_api.get_project(root_project[\u0027id\u0027])"},{"line_number":3291,"context_line":"        self.resource_api.get_project(project1[\u0027id\u0027])"},{"line_number":3292,"context_line":"        self.resource_api.get_project(project2[\u0027id\u0027])"},{"line_number":3293,"context_line":""},{"line_number":3294,"context_line":"    def test_hierarchical_projects_crud(self):"},{"line_number":3295,"context_line":"        # create a hierarchy with just a root project (which is a leaf as well)"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a5de9d1_0ccad76d","line":3292,"in_reply_to":"7a5de9d1_6c6fcb92","updated":"2016-01-28 22:15:35.000000000","message":"Tom has an idea of a great test and he\u0027s going to implement it. He will be able to submit it in a couple of minutes, ok?","commit_id":"35b29b670e1c414df6dcdc2b1481a01962b7b055"},{"author":{"_account_id":8866,"name":"Raildo Mascena de Sousa Filho","email":"rmascena@redhat.com","username":"raildo"},"change_message_id":"4b12700b634a666393e770d128f81db3bbf51978","unresolved":false,"context_lines":[{"line_number":2525,"context_line":"    def _create_projects_hierarchy(self, hierarchy_size\u003d2,"},{"line_number":2526,"context_line":"                                   domain_id\u003dDEFAULT_DOMAIN_ID,"},{"line_number":2527,"context_line":"                                   is_domain\u003dFalse,"},{"line_number":2528,"context_line":"                                   parent_project_id\u003dNone):"},{"line_number":2529,"context_line":"        \"\"\"Creates a project hierarchy with specified size."},{"line_number":2530,"context_line":""},{"line_number":2531,"context_line":"        :param hierarchy_size: the desired hierarchy size, default is 2 -"}],"source_content_type":"text/x-python","patch_set":22,"id":"3a57f1b5_edba3dc0","line":2528,"range":{"start_line":2528,"start_character":35,"end_line":2528,"end_character":52},"updated":"2016-02-09 18:18:31.000000000","message":"This should be just \u0027parent_id\u0027 and not \u0027parent_project_id\u0027\nThe same comment apply for every other reference here.","commit_id":"cbd70a2638eb8c497c4f35739710ea1787738014"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ef1914956c56d6afa211542d314f348ac46993c7","unresolved":false,"context_lines":[{"line_number":2533,"context_line":"        :param domain_id: domain where the projects hierarchy will be created."},{"line_number":2534,"context_line":"        :param is_domain: if the hierarchy will have the is_domain flag active"},{"line_number":2535,"context_line":"                          or not."},{"line_number":2536,"context_line":"        :param parent_project_id (optional): if the intention is to create a"},{"line_number":2537,"context_line":"            sub-hierarchy, sets the sub-hierarchy root."},{"line_number":2538,"context_line":""},{"line_number":2539,"context_line":"        :returns projects: a list of the projects in the created hierarchy."}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_28ac55ec","line":2536,"updated":"2016-02-11 13:02:34.000000000","message":"Put \"(optional)\" is the description part, at the end. Event better than saying optional is to say what the default is.","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"218d527005d78b2456002bff56329dcfc704b800","unresolved":false,"context_lines":[{"line_number":2533,"context_line":"        :param domain_id: domain where the projects hierarchy will be created."},{"line_number":2534,"context_line":"        :param is_domain: if the hierarchy will have the is_domain flag active"},{"line_number":2535,"context_line":"                          or not."},{"line_number":2536,"context_line":"        :param parent_project_id (optional): if the intention is to create a"},{"line_number":2537,"context_line":"            sub-hierarchy, sets the sub-hierarchy root."},{"line_number":2538,"context_line":""},{"line_number":2539,"context_line":"        :returns projects: a list of the projects in the created hierarchy."}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_3cb1f3e1","line":2536,"in_reply_to":"3a57f1b5_28ac55ec","updated":"2016-02-11 14:07:54.000000000","message":"Done","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"ef1914956c56d6afa211542d314f348ac46993c7","unresolved":false,"context_lines":[{"line_number":3385,"context_line":""},{"line_number":3386,"context_line":"    def test_delete_large_project_cascade(self):"},{"line_number":3387,"context_line":"        \"\"\"Try delete a large project with cascade true"},{"line_number":3388,"context_line":"        Tree we will create::"},{"line_number":3389,"context_line":"               +-p1-+"},{"line_number":3390,"context_line":"               |    |"},{"line_number":3391,"context_line":"              p5    p2"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_48f431f1","line":3388,"updated":"2016-02-11 13:02:34.000000000","message":"Newline above this.","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"218d527005d78b2456002bff56329dcfc704b800","unresolved":false,"context_lines":[{"line_number":3385,"context_line":""},{"line_number":3386,"context_line":"    def test_delete_large_project_cascade(self):"},{"line_number":3387,"context_line":"        \"\"\"Try delete a large project with cascade true"},{"line_number":3388,"context_line":"        Tree we will create::"},{"line_number":3389,"context_line":"               +-p1-+"},{"line_number":3390,"context_line":"               |    |"},{"line_number":3391,"context_line":"              p5    p2"}],"source_content_type":"text/x-python","patch_set":24,"id":"3a57f1b5_1c6f5793","line":3388,"in_reply_to":"3a57f1b5_48f431f1","updated":"2016-02-11 14:07:54.000000000","message":"Done","commit_id":"f6e160a07154c2aa008e6c0639f8a8e57e785cc3"},{"author":{"_account_id":17123,"name":"Tom Cocozzello (tjcocozz)","email":"tjcocozz@us.ibm.com","username":"tcocozzello"},"change_message_id":"0bd922f7c0784285798a50880b676aedd410ef19","unresolved":false,"context_lines":[{"line_number":3421,"context_line":"                              self.resource_api.get_project,"},{"line_number":3422,"context_line":"                              project[\u0027id\u0027])"},{"line_number":3423,"context_line":""},{"line_number":3424,"context_line":"    def test_cannot_delete_project_cascade_with_enabled_child(self):"},{"line_number":3425,"context_line":"        # create a hierarchy with 3 levels"},{"line_number":3426,"context_line":"        projects_hierarchy \u003d self._create_projects_hierarchy(hierarchy_size\u003d3)"},{"line_number":3427,"context_line":"        root_project \u003d projects_hierarchy[0]"}],"source_content_type":"text/x-python","patch_set":30,"id":"3a57f1b5_846ad07f","line":3424,"range":{"start_line":3424,"start_character":20,"end_line":3424,"end_character":26},"updated":"2016-02-12 15:03:40.000000000","message":"this test looks like it is disabling a project and not deleting it","commit_id":"c25786a50aab54048e34d73f97b46c16d079ac9e"},{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"0f86e30c90fb25c7350d7747521eb8407f68fe37","unresolved":false,"context_lines":[{"line_number":3421,"context_line":"                              self.resource_api.get_project,"},{"line_number":3422,"context_line":"                              project[\u0027id\u0027])"},{"line_number":3423,"context_line":""},{"line_number":3424,"context_line":"    def test_cannot_delete_project_cascade_with_enabled_child(self):"},{"line_number":3425,"context_line":"        # create a hierarchy with 3 levels"},{"line_number":3426,"context_line":"        projects_hierarchy \u003d self._create_projects_hierarchy(hierarchy_size\u003d3)"},{"line_number":3427,"context_line":"        root_project \u003d projects_hierarchy[0]"}],"source_content_type":"text/x-python","patch_set":30,"id":"3a57f1b5_a566dc27","line":3424,"range":{"start_line":3424,"start_character":20,"end_line":3424,"end_character":26},"in_reply_to":"3a57f1b5_846ad07f","updated":"2016-02-12 18:46:26.000000000","message":"I disagree. We only disable part of the hierarchy to have an enabled project in the middle. The main part is trying to delete, and after it, ensuring no project was deleted.","commit_id":"c25786a50aab54048e34d73f97b46c16d079ac9e"}]}
