)]}'
{"keystone/resource/core.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":885,"context_line":"            if new_ref[\u0027domain_id\u0027] !\u003d orig_ref[\u0027domain_id\u0027]:"},{"line_number":886,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def list_projects_by_tags(self, tags, operator):"},{"line_number":889,"context_line":"        \"\"\"Filter projects based on tags.\"\"\""},{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_beb9b4cc","line":888,"range":{"start_line":888,"start_character":36,"end_line":888,"end_character":40},"updated":"2017-09-28 21:00:04.000000000","message":"What does this come in as? Something other than a list? Or a string of tags delimited by \u0027,\u0027?","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"732586d7b898b1eb4d5e7a3281781d2a37123899","unresolved":false,"context_lines":[{"line_number":885,"context_line":"            if new_ref[\u0027domain_id\u0027] !\u003d orig_ref[\u0027domain_id\u0027]:"},{"line_number":886,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def list_projects_by_tags(self, tags, operator):"},{"line_number":889,"context_line":"        \"\"\"Filter projects based on tags.\"\"\""},{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_79c916aa","line":888,"range":{"start_line":888,"start_character":36,"end_line":888,"end_character":40},"in_reply_to":"7f515b1d_beb9b4cc","updated":"2017-09-28 21:07:11.000000000","message":"This is a string, either a single tag or a list of tags separated by \u0027,\u0027.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":886,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def list_projects_by_tags(self, tags, operator):"},{"line_number":889,"context_line":"        \"\"\"Filter projects based on tags.\"\"\""},{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_debfd0a7","line":889,"range":{"start_line":889,"start_character":8,"end_line":889,"end_character":44},"updated":"2017-09-28 21:00:04.000000000","message":"We should add the parameters and return values here.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":886,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def list_projects_by_tags(self, tags, operator):"},{"line_number":889,"context_line":"        \"\"\"Filter projects based on tags.\"\"\""},{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_0aeff4b0","line":889,"range":{"start_line":889,"start_character":8,"end_line":889,"end_character":44},"in_reply_to":"7f515b1d_2a72bee4","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"5ed359f0f759a31661fcd7909d303d49ffaee8e5","unresolved":false,"context_lines":[{"line_number":886,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def list_projects_by_tags(self, tags, operator):"},{"line_number":889,"context_line":"        \"\"\"Filter projects based on tags.\"\"\""},{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_2a72bee4","line":889,"range":{"start_line":889,"start_character":8,"end_line":889,"end_character":44},"in_reply_to":"7f515b1d_debfd0a7","updated":"2017-10-04 12:41:29.000000000","message":"I\u0027d suggest either make thsi a list of tags or call it tags_string or something like that","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"732586d7b898b1eb4d5e7a3281781d2a37123899","unresolved":false,"context_lines":[{"line_number":886,"context_line":"                raise exception.ValidationError(_(\u0027Cannot change Domain ID\u0027))"},{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def list_projects_by_tags(self, tags, operator):"},{"line_number":889,"context_line":"        \"\"\"Filter projects based on tags.\"\"\""},{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_39c71e99","line":889,"range":{"start_line":889,"start_character":8,"end_line":889,"end_character":44},"in_reply_to":"7f515b1d_debfd0a7","updated":"2017-09-28 21:07:11.000000000","message":"will do","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"5ed359f0f759a31661fcd7909d303d49ffaee8e5","unresolved":false,"context_lines":[{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def list_projects_by_tags(self, tags, operator):"},{"line_number":889,"context_line":"        \"\"\"Filter projects based on tags.\"\"\""},{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"},{"line_number":893,"context_line":"        project_ids \u003d self.driver.list_projects_by_tags("},{"line_number":894,"context_line":"            tag_list, getattr(self.driver, operator))"},{"line_number":895,"context_line":"        return self.driver.list_projects_from_ids(project_ids)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_6a179653","line":892,"range":{"start_line":890,"start_character":0,"end_line":892,"end_character":38},"updated":"2017-10-04 12:41:29.000000000","message":"replace all this by\n\n    tag_list \u003d tags.split(\u0027,\u0027)\n\nit doesn\u0027t matter if a , is present","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":887,"context_line":""},{"line_number":888,"context_line":"    def list_projects_by_tags(self, tags, operator):"},{"line_number":889,"context_line":"        \"\"\"Filter projects based on tags.\"\"\""},{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"},{"line_number":893,"context_line":"        project_ids \u003d self.driver.list_projects_by_tags("},{"line_number":894,"context_line":"            tag_list, getattr(self.driver, operator))"},{"line_number":895,"context_line":"        return self.driver.list_projects_from_ids(project_ids)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_8a38843d","line":892,"range":{"start_line":890,"start_character":0,"end_line":892,"end_character":38},"in_reply_to":"7f515b1d_6a179653","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"},{"line_number":893,"context_line":"        project_ids \u003d self.driver.list_projects_by_tags("},{"line_number":894,"context_line":"            tag_list, getattr(self.driver, operator))"},{"line_number":895,"context_line":"        return self.driver.list_projects_from_ids(project_ids)"},{"line_number":896,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_7efd7c6c","line":893,"range":{"start_line":893,"start_character":34,"end_line":893,"end_character":55},"updated":"2017-09-28 21:00:04.000000000","message":"Would it be possible to just have this return a list of full project references? I suppose that might not make sense in the backend. I was thinking it might be suboptimal to have the backend return a list of ids only for us to turn around and ask for the full references.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"732586d7b898b1eb4d5e7a3281781d2a37123899","unresolved":false,"context_lines":[{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"},{"line_number":893,"context_line":"        project_ids \u003d self.driver.list_projects_by_tags("},{"line_number":894,"context_line":"            tag_list, getattr(self.driver, operator))"},{"line_number":895,"context_line":"        return self.driver.list_projects_from_ids(project_ids)"},{"line_number":896,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_d9b92a15","line":893,"range":{"start_line":893,"start_character":34,"end_line":893,"end_character":55},"in_reply_to":"7f515b1d_7efd7c6c","updated":"2017-09-28 21:07:11.000000000","message":"good point, will look into this","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":890,"context_line":"        tag_list \u003d [tags]"},{"line_number":891,"context_line":"        if \u0027,\u0027 in tags:"},{"line_number":892,"context_line":"            tag_list \u003d tags.split(\u0027,\u0027)"},{"line_number":893,"context_line":"        project_ids \u003d self.driver.list_projects_by_tags("},{"line_number":894,"context_line":"            tag_list, getattr(self.driver, operator))"},{"line_number":895,"context_line":"        return self.driver.list_projects_from_ids(project_ids)"},{"line_number":896,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_6a3d482b","line":893,"range":{"start_line":893,"start_character":34,"end_line":893,"end_character":55},"in_reply_to":"7f515b1d_d9b92a15","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":894,"context_line":"            tag_list, getattr(self.driver, operator))"},{"line_number":895,"context_line":"        return self.driver.list_projects_from_ids(project_ids)"},{"line_number":896,"context_line":""},{"line_number":897,"context_line":"    def create_project_tag(self, project_id, tag, initiator\u003dNone):"},{"line_number":898,"context_line":"        \"\"\"Create a new tag on project.\"\"\""},{"line_number":899,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":900,"context_line":"        tag_name \u003d urllib.parse.unquote(tag.strip())"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_fef04c93","line":897,"range":{"start_line":897,"start_character":33,"end_line":897,"end_character":66},"updated":"2017-09-28 21:00:04.000000000","message":"We should add documentation strings for these.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":894,"context_line":"            tag_list, getattr(self.driver, operator))"},{"line_number":895,"context_line":"        return self.driver.list_projects_from_ids(project_ids)"},{"line_number":896,"context_line":""},{"line_number":897,"context_line":"    def create_project_tag(self, project_id, tag, initiator\u003dNone):"},{"line_number":898,"context_line":"        \"\"\"Create a new tag on project.\"\"\""},{"line_number":899,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":900,"context_line":"        tag_name \u003d urllib.parse.unquote(tag.strip())"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_2a4750bf","line":897,"range":{"start_line":897,"start_character":33,"end_line":897,"end_character":66},"in_reply_to":"7f515b1d_fef04c93","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"5ed359f0f759a31661fcd7909d303d49ffaee8e5","unresolved":false,"context_lines":[{"line_number":898,"context_line":"        \"\"\"Create a new tag on project.\"\"\""},{"line_number":899,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":900,"context_line":"        tag_name \u003d urllib.parse.unquote(tag.strip())"},{"line_number":901,"context_line":"        if tag_name in project.get(\u0027tags\u0027):"},{"line_number":902,"context_line":"            return tag_name"},{"line_number":903,"context_line":"        project \u003d {\u0027tags\u0027: project[\u0027tags\u0027]}"},{"line_number":904,"context_line":"        project[\u0027tags\u0027].append(tag_name)"},{"line_number":905,"context_line":"        validation.lazy_validate(schema.project_tags_update, project[\u0027tags\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_c5267bbb","line":902,"range":{"start_line":901,"start_character":0,"end_line":902,"end_character":27},"updated":"2017-10-04 12:41:29.000000000","message":"so we\u0027re not returning duplicated entry ?","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":898,"context_line":"        \"\"\"Create a new tag on project.\"\"\""},{"line_number":899,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":900,"context_line":"        tag_name \u003d urllib.parse.unquote(tag.strip())"},{"line_number":901,"context_line":"        if tag_name in project.get(\u0027tags\u0027):"},{"line_number":902,"context_line":"            return tag_name"},{"line_number":903,"context_line":"        project \u003d {\u0027tags\u0027: project[\u0027tags\u0027]}"},{"line_number":904,"context_line":"        project[\u0027tags\u0027].append(tag_name)"},{"line_number":905,"context_line":"        validation.lazy_validate(schema.project_tags_update, project[\u0027tags\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_9f49eb33","line":902,"range":{"start_line":901,"start_character":0,"end_line":902,"end_character":27},"in_reply_to":"7f515b1d_c5267bbb","updated":"2017-10-04 20:13:11.000000000","message":"No, we will just silently \"fail\" and say that the project contains the tag.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":909,"context_line":"            self._PROJECT_TAG, tag_name, initiator)"},{"line_number":910,"context_line":"        return tag_name"},{"line_number":911,"context_line":""},{"line_number":912,"context_line":"    def get_project_tag(self, project_id, tag_name):"},{"line_number":913,"context_line":"        \"\"\"Return information for a single tag on a project.\"\"\""},{"line_number":914,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":915,"context_line":"        if tag_name not in project.get(\u0027tags\u0027):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_3e4024a5","line":912,"range":{"start_line":912,"start_character":30,"end_line":912,"end_character":50},"updated":"2017-09-28 21:00:04.000000000","message":"Same comment as above.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":916,"context_line":"            raise exception.ProjectTagNotFound(project_tag\u003dtag_name)"},{"line_number":917,"context_line":"        return tag_name"},{"line_number":918,"context_line":""},{"line_number":919,"context_line":"    def list_project_tags(self, project_id):"},{"line_number":920,"context_line":"        \"\"\"List all tags on project.\"\"\""},{"line_number":921,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":922,"context_line":"        return project.get(\u0027tags\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_1e3d682a","line":919,"range":{"start_line":919,"start_character":32,"end_line":919,"end_character":42},"updated":"2017-09-28 21:00:04.000000000","message":"Same comment as above.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":919,"context_line":"    def list_project_tags(self, project_id):"},{"line_number":920,"context_line":"        \"\"\"List all tags on project.\"\"\""},{"line_number":921,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":922,"context_line":"        return project.get(\u0027tags\u0027)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":925,"context_line":"        \"\"\"Update project tags replaces current tags with a new list.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_1e268816","line":922,"range":{"start_line":922,"start_character":23,"end_line":922,"end_character":34},"updated":"2017-09-28 21:00:04.000000000","message":"If the project doesn\u0027t have tags, should this return None or an empty list?","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"732586d7b898b1eb4d5e7a3281781d2a37123899","unresolved":false,"context_lines":[{"line_number":919,"context_line":"    def list_project_tags(self, project_id):"},{"line_number":920,"context_line":"        \"\"\"List all tags on project.\"\"\""},{"line_number":921,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":922,"context_line":"        return project.get(\u0027tags\u0027)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":925,"context_line":"        \"\"\"Update project tags replaces current tags with a new list.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_b961ceab","line":922,"range":{"start_line":922,"start_character":23,"end_line":922,"end_character":34},"in_reply_to":"7f515b1d_1e268816","updated":"2017-09-28 21:07:11.000000000","message":"This could be project.get(\u0027tags\u0027, []) just in case. good catch","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"5ed359f0f759a31661fcd7909d303d49ffaee8e5","unresolved":false,"context_lines":[{"line_number":919,"context_line":"    def list_project_tags(self, project_id):"},{"line_number":920,"context_line":"        \"\"\"List all tags on project.\"\"\""},{"line_number":921,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":922,"context_line":"        return project.get(\u0027tags\u0027)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":925,"context_line":"        \"\"\"Update project tags replaces current tags with a new list.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_e53057eb","line":922,"range":{"start_line":922,"start_character":23,"end_line":922,"end_character":34},"in_reply_to":"7f515b1d_b961ceab","updated":"2017-10-04 12:41:29.000000000","message":"++","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":919,"context_line":"    def list_project_tags(self, project_id):"},{"line_number":920,"context_line":"        \"\"\"List all tags on project.\"\"\""},{"line_number":921,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":922,"context_line":"        return project.get(\u0027tags\u0027)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":925,"context_line":"        \"\"\"Update project tags replaces current tags with a new list.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_ca179ca3","line":922,"range":{"start_line":922,"start_character":23,"end_line":922,"end_character":34},"in_reply_to":"7f515b1d_e53057eb","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":921,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":922,"context_line":"        return project.get(\u0027tags\u0027)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":925,"context_line":"        \"\"\"Update project tags replaces current tags with a new list.\"\"\""},{"line_number":926,"context_line":"        self.driver.get_project(project_id)"},{"line_number":927,"context_line":"        tag_list \u003d [urllib.parse.unquote(t.strip()) for t in tags]"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_de4230ab","line":924,"range":{"start_line":924,"start_character":34,"end_line":924,"end_character":66},"updated":"2017-09-28 21:00:04.000000000","message":"Same comment as above.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":922,"context_line":"        return project.get(\u0027tags\u0027)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":925,"context_line":"        \"\"\"Update project tags replaces current tags with a new list.\"\"\""},{"line_number":926,"context_line":"        self.driver.get_project(project_id)"},{"line_number":927,"context_line":"        tag_list \u003d [urllib.parse.unquote(t.strip()) for t in tags]"},{"line_number":928,"context_line":"        project \u003d {\u0027tags\u0027: tag_list}"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_fee16c9c","line":925,"range":{"start_line":925,"start_character":11,"end_line":925,"end_character":69},"updated":"2017-09-28 21:00:04.000000000","message":"Suggest a wording that is somewhat consistent with the other documentation strings:\n\n  Overwrite existing project tags with a list of new tags","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":922,"context_line":"        return project.get(\u0027tags\u0027)"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"    def update_project_tags(self, project_id, tags, initiator\u003dNone):"},{"line_number":925,"context_line":"        \"\"\"Update project tags replaces current tags with a new list.\"\"\""},{"line_number":926,"context_line":"        self.driver.get_project(project_id)"},{"line_number":927,"context_line":"        tag_list \u003d [urllib.parse.unquote(t.strip()) for t in tags]"},{"line_number":928,"context_line":"        project \u003d {\u0027tags\u0027: tag_list}"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_aa0c6094","line":925,"range":{"start_line":925,"start_character":11,"end_line":925,"end_character":69},"in_reply_to":"7f515b1d_fee16c9c","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":929,"context_line":"        self.update_project(project_id, project)"},{"line_number":930,"context_line":"        return tag_list"},{"line_number":931,"context_line":""},{"line_number":932,"context_line":"    def delete_project_tag(self, project_id, tag):"},{"line_number":933,"context_line":"        \"\"\"Delete single tag from project.\"\"\""},{"line_number":934,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":935,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_be15349e","line":932,"range":{"start_line":932,"start_character":33,"end_line":932,"end_character":48},"updated":"2017-09-28 21:00:04.000000000","message":"Same comment as above.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":937,"context_line":"        except ValueError:"},{"line_number":938,"context_line":"            raise exception.ProjectTagNotFound(project_tag\u003dtag)"},{"line_number":939,"context_line":"        self.update_project(project_id, project)"},{"line_number":940,"context_line":"        notifications.Audit.deleted("},{"line_number":941,"context_line":"            self._PROJECT_TAG, tag)"},{"line_number":942,"context_line":""},{"line_number":943,"context_line":"MEMOIZE_CONFIG \u003d cache.get_memoization_decorator(group\u003d\u0027domain_config\u0027)"},{"line_number":944,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_1e544852","line":941,"range":{"start_line":940,"start_character":8,"end_line":941,"end_character":35},"updated":"2017-09-28 21:00:04.000000000","message":"nit: This should all fit on a single line.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":937,"context_line":"        except ValueError:"},{"line_number":938,"context_line":"            raise exception.ProjectTagNotFound(project_tag\u003dtag)"},{"line_number":939,"context_line":"        self.update_project(project_id, project)"},{"line_number":940,"context_line":"        notifications.Audit.deleted("},{"line_number":941,"context_line":"            self._PROJECT_TAG, tag)"},{"line_number":942,"context_line":""},{"line_number":943,"context_line":"MEMOIZE_CONFIG \u003d cache.get_memoization_decorator(group\u003d\u0027domain_config\u0027)"},{"line_number":944,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_6a266819","line":941,"range":{"start_line":940,"start_character":8,"end_line":941,"end_character":35},"in_reply_to":"7f515b1d_1e544852","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"8ed5fb1315a35bd29f35622fa7126c9133399fc8","unresolved":false,"context_lines":[{"line_number":889,"context_line":""},{"line_number":890,"context_line":"        :param tags: A string containing a single tag or"},{"line_number":891,"context_line":"                     a list of tags separated by ,"},{"line_number":892,"context_line":"        :param operator: A backend method name for searching"},{"line_number":893,"context_line":"                         projects by tags/tags-any/not-tags"},{"line_number":894,"context_line":""},{"line_number":895,"context_line":"        :returns: A list of projects"},{"line_number":896,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_26e98419","line":893,"range":{"start_line":892,"start_character":25,"end_line":893,"end_character":59},"updated":"2017-10-06 18:11:36.000000000","message":"this is really confusing/not easy to understand. I could only understand this after looking at the controller/router patch that does the tag operator -\u003e backend method name mapping. please see my suggestion in that patch","commit_id":"29f70738ab01219f63c967f937e922b911ddf330"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"26f0d39f2067b6d378d09167c7430c7030f788da","unresolved":false,"context_lines":[{"line_number":889,"context_line":""},{"line_number":890,"context_line":"        :param tags: A string containing a single tag or"},{"line_number":891,"context_line":"                     a list of tags separated by ,"},{"line_number":892,"context_line":"        :param operator: A backend method name for searching"},{"line_number":893,"context_line":"                         projects by tags/tags-any/not-tags"},{"line_number":894,"context_line":""},{"line_number":895,"context_line":"        :returns: A list of projects"},{"line_number":896,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"7f515b1d_5a77b33b","line":893,"range":{"start_line":892,"start_character":25,"end_line":893,"end_character":59},"in_reply_to":"7f515b1d_26e98419","updated":"2017-10-06 20:51:38.000000000","message":"We could pull this logic up into the manager, too. That would make the backend super simple in that it just returns a list of tags for a project. The the manager is on the hook for doing the filtering.\n\nThat might make more sense if the manager is supposed to have business logic anyway.","commit_id":"29f70738ab01219f63c967f937e922b911ddf330"},{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"0726ae1a43aa1cb98d9f1d19935499505859c710","unresolved":false,"context_lines":[{"line_number":29,"context_line":"from keystone import notifications"},{"line_number":30,"context_line":"from keystone.resource.backends import base"},{"line_number":31,"context_line":"from keystone.resource.backends import sql as resource_sql"},{"line_number":32,"context_line":"from keystone.resource import schema"},{"line_number":33,"context_line":"from keystone.token import provider as token_provider"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"CONF \u003d keystone.conf.CONF"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f4e5783_a9bc7969","line":32,"updated":"2017-10-10 19:50:29.000000000","message":"Is there a reason for doing schema validation here instead of at the controller?","commit_id":"b09b58f3a8b1908ba3c4811c469e53862de4c678"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"404e8f744ad7899677708e07309c83b7f38cd0a9","unresolved":false,"context_lines":[{"line_number":29,"context_line":"from keystone import notifications"},{"line_number":30,"context_line":"from keystone.resource.backends import base"},{"line_number":31,"context_line":"from keystone.resource.backends import sql as resource_sql"},{"line_number":32,"context_line":"from keystone.resource import schema"},{"line_number":33,"context_line":"from keystone.token import provider as token_provider"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"CONF \u003d keystone.conf.CONF"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f4e5783_12ddf613","line":32,"in_reply_to":"5f4e5783_a9bc7969","updated":"2017-10-10 21:12:09.000000000","message":"We could move this into the controller","commit_id":"b09b58f3a8b1908ba3c4811c469e53862de4c678"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"c6793f11647731a010e0301894e3ce66fbd98af4","unresolved":false,"context_lines":[{"line_number":909,"context_line":"        \"\"\""},{"line_number":910,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":911,"context_line":"        if tag_name not in project.get(\u0027tags\u0027):"},{"line_number":912,"context_line":"            raise exception.ProjectTagNotFound(project_tag\u003dtag_name)"},{"line_number":913,"context_line":"        return tag_name"},{"line_number":914,"context_line":""},{"line_number":915,"context_line":"    def list_project_tags(self, project_id):"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_2feb85dc","line":912,"range":{"start_line":912,"start_character":18,"end_line":912,"end_character":46},"updated":"2017-10-13 16:04:14.000000000","message":"This could be documented in the doc strings with :raises: but we can do that in a follow up. That shouldn\u0027t hold this up any more.","commit_id":"5140e5a451afb601a44a83f4d5731d56e896b1f1"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"e77b0225fe51924d2d69437e0b5482b2e6c238e9","unresolved":false,"context_lines":[{"line_number":909,"context_line":"        \"\"\""},{"line_number":910,"context_line":"        project \u003d self.driver.get_project(project_id)"},{"line_number":911,"context_line":"        if tag_name not in project.get(\u0027tags\u0027):"},{"line_number":912,"context_line":"            raise exception.ProjectTagNotFound(project_tag\u003dtag_name)"},{"line_number":913,"context_line":"        return tag_name"},{"line_number":914,"context_line":""},{"line_number":915,"context_line":"    def list_project_tags(self, project_id):"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_944ccd42","line":912,"range":{"start_line":912,"start_character":18,"end_line":912,"end_character":46},"in_reply_to":"5f4e5783_2feb85dc","updated":"2017-10-13 18:32:17.000000000","message":"Done","commit_id":"5140e5a451afb601a44a83f4d5731d56e896b1f1"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"c6793f11647731a010e0301894e3ce66fbd98af4","unresolved":false,"context_lines":[{"line_number":946,"context_line":"        try:"},{"line_number":947,"context_line":"            project[\u0027tags\u0027].remove(tag)"},{"line_number":948,"context_line":"        except ValueError:"},{"line_number":949,"context_line":"            raise exception.ProjectTagNotFound(project_tag\u003dtag)"},{"line_number":950,"context_line":"        self.update_project(project_id, project)"},{"line_number":951,"context_line":"        notifications.Audit.deleted(self._PROJECT_TAG, tag)"},{"line_number":952,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_4fc7e165","line":949,"range":{"start_line":949,"start_character":18,"end_line":949,"end_character":46},"updated":"2017-10-13 16:04:14.000000000","message":"Same comment here - but in a follow up for sure.","commit_id":"5140e5a451afb601a44a83f4d5731d56e896b1f1"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"e77b0225fe51924d2d69437e0b5482b2e6c238e9","unresolved":false,"context_lines":[{"line_number":946,"context_line":"        try:"},{"line_number":947,"context_line":"            project[\u0027tags\u0027].remove(tag)"},{"line_number":948,"context_line":"        except ValueError:"},{"line_number":949,"context_line":"            raise exception.ProjectTagNotFound(project_tag\u003dtag)"},{"line_number":950,"context_line":"        self.update_project(project_id, project)"},{"line_number":951,"context_line":"        notifications.Audit.deleted(self._PROJECT_TAG, tag)"},{"line_number":952,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_5452d5df","line":949,"range":{"start_line":949,"start_character":18,"end_line":949,"end_character":46},"in_reply_to":"5f4e5783_4fc7e165","updated":"2017-10-13 18:32:17.000000000","message":"Done","commit_id":"5140e5a451afb601a44a83f4d5731d56e896b1f1"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"629a4e7eff87c67a5520708c5d021f2ca21787b1","unresolved":false,"context_lines":[{"line_number":34,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":35,"context_line":"MEMOIZE \u003d cache.get_memoization_decorator(group\u003d\u0027resource\u0027)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"TAG_SEARCH_FILTERS \u003d (\u0027tags\u0027, \u0027tags-any\u0027, \u0027not-tags\u0027, \u0027not-tags-any\u0027)"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"@dependency.provider(\u0027resource_api\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f4e5783_97428f3d","line":37,"range":{"start_line":37,"start_character":0,"end_line":37,"end_character":69},"updated":"2017-10-13 19:02:17.000000000","message":"It\u0027d be nice to not have to define this in multiple places. That way if we add support for other tags we don\u0027t have to maintain two lists. We can do that in as a fast follow on patch though.","commit_id":"075184e506048e0f957c3cd7c27dec431dd9a43c"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"629a4e7eff87c67a5520708c5d021f2ca21787b1","unresolved":false,"context_lines":[{"line_number":824,"context_line":"    def list_projects(self, hints\u003dNone):"},{"line_number":825,"context_line":"        if hints:"},{"line_number":826,"context_line":"            tag_filters \u003d {}"},{"line_number":827,"context_line":"            # Handle project tag filters separately"},{"line_number":828,"context_line":"            for f in list(hints.filters):"},{"line_number":829,"context_line":"                if f[\u0027name\u0027] in TAG_SEARCH_FILTERS:"},{"line_number":830,"context_line":"                    tag_filters[f[\u0027name\u0027]] \u003d f[\u0027value\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f4e5783_5761b7d2","line":827,"range":{"start_line":827,"start_character":12,"end_line":827,"end_character":51},"updated":"2017-10-13 19:02:17.000000000","message":"This results are aggregated in the controller layer, right? The controller is what allows us to filter on tags an other project attributes in the same request, right?\n\nLine 836 only returns a request filtered by project tags.","commit_id":"075184e506048e0f957c3cd7c27dec431dd9a43c"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"a715e83bd83d0ea55d9b4047ecddf667c07dd31c","unresolved":false,"context_lines":[{"line_number":824,"context_line":"    def list_projects(self, hints\u003dNone):"},{"line_number":825,"context_line":"        if hints:"},{"line_number":826,"context_line":"            tag_filters \u003d {}"},{"line_number":827,"context_line":"            # Handle project tag filters separately"},{"line_number":828,"context_line":"            for f in list(hints.filters):"},{"line_number":829,"context_line":"                if f[\u0027name\u0027] in TAG_SEARCH_FILTERS:"},{"line_number":830,"context_line":"                    tag_filters[f[\u0027name\u0027]] \u003d f[\u0027value\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f4e5783_a902c73b","line":827,"range":{"start_line":827,"start_character":12,"end_line":827,"end_character":51},"in_reply_to":"5f4e5783_5761b7d2","updated":"2017-10-14 03:12:23.000000000","message":"The filters are added in the controller layer, correct. Here they are searched on with calls to the backend for both tag filters and project attributes and then aggregated accordingly.","commit_id":"075184e506048e0f957c3cd7c27dec431dd9a43c"}],"keystone/tests/unit/resource/test_backends.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1538,"context_line":"        user \u003d self.identity_api.get_user(user[\u0027id\u0027])"},{"line_number":1539,"context_line":"        self.assertNotIn(\u0027default_project_id\u0027, user)"},{"line_number":1540,"context_line":""},{"line_number":1541,"context_line":"    def _create_project_and_tags(self, tag_size\u003d1):"},{"line_number":1542,"context_line":"        \"\"\"Create a project and tags associated to that project."},{"line_number":1543,"context_line":""},{"line_number":1544,"context_line":"        :param tag_size: the desired number of tags attached to a project,"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_3e8a64be","line":1541,"range":{"start_line":1541,"start_character":39,"end_line":1541,"end_character":47},"updated":"2017-09-28 21:00:04.000000000","message":"nit: number_of_tags ?","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":1538,"context_line":"        user \u003d self.identity_api.get_user(user[\u0027id\u0027])"},{"line_number":1539,"context_line":"        self.assertNotIn(\u0027default_project_id\u0027, user)"},{"line_number":1540,"context_line":""},{"line_number":1541,"context_line":"    def _create_project_and_tags(self, tag_size\u003d1):"},{"line_number":1542,"context_line":"        \"\"\"Create a project and tags associated to that project."},{"line_number":1543,"context_line":""},{"line_number":1544,"context_line":"        :param tag_size: the desired number of tags attached to a project,"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_0a1db4bc","line":1541,"range":{"start_line":1541,"start_character":39,"end_line":1541,"end_character":47},"in_reply_to":"7f515b1d_3e8a64be","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1541,"context_line":"    def _create_project_and_tags(self, tag_size\u003d1):"},{"line_number":1542,"context_line":"        \"\"\"Create a project and tags associated to that project."},{"line_number":1543,"context_line":""},{"line_number":1544,"context_line":"        :param tag_size: the desired number of tags attached to a project,"},{"line_number":1545,"context_line":"                         default is 1 - one tag attached to one project."},{"line_number":1546,"context_line":""},{"line_number":1547,"context_line":"        :returns project: project dictionary created."}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_7eb57c7d","line":1544,"range":{"start_line":1544,"start_character":15,"end_line":1544,"end_character":23},"updated":"2017-09-28 21:00:04.000000000","message":"Tag size seems like:\n\n  tag_size \u003d 6\n  tag \u003d \u0027abcdef\u0027","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1545,"context_line":"                         default is 1 - one tag attached to one project."},{"line_number":1546,"context_line":""},{"line_number":1547,"context_line":"        :returns project: project dictionary created."},{"line_number":1548,"context_line":"        :returns tags: a list of the tags created."},{"line_number":1549,"context_line":"        \"\"\""},{"line_number":1550,"context_line":"        tags \u003d [uuid.uuid4().hex for i in range(tag_size)]"},{"line_number":1551,"context_line":"        ref \u003d unit.new_project_ref("}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_3eb3849a","line":1548,"range":{"start_line":1548,"start_character":17,"end_line":1548,"end_character":21},"updated":"2017-09-28 21:00:04.000000000","message":"This method seems to return a tuple with tags being one part of that, we should document this also returns a new project.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":1545,"context_line":"                         default is 1 - one tag attached to one project."},{"line_number":1546,"context_line":""},{"line_number":1547,"context_line":"        :returns project: project dictionary created."},{"line_number":1548,"context_line":"        :returns tags: a list of the tags created."},{"line_number":1549,"context_line":"        \"\"\""},{"line_number":1550,"context_line":"        tags \u003d [uuid.uuid4().hex for i in range(tag_size)]"},{"line_number":1551,"context_line":"        ref \u003d unit.new_project_ref("}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_aa8100c6","line":1548,"range":{"start_line":1548,"start_character":17,"end_line":1548,"end_character":21},"in_reply_to":"7f515b1d_3eb3849a","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1583,"context_line":"        tag_list \u003d tags[0] + \u0027,\u0027 + tags[1]"},{"line_number":1584,"context_line":"        project_ref \u003d self.resource_api.list_projects_by_tags("},{"line_number":1585,"context_line":"            tag_list, \u0027filter_not_tags\u0027)"},{"line_number":1586,"context_line":"        self.assertNotIn(project, project_ref)"},{"line_number":1587,"context_line":""},{"line_number":1588,"context_line":"    def test_list_projects_not_tags_any(self):"},{"line_number":1589,"context_line":"        project, tags \u003d self._create_project_and_tags(tag_size\u003d2)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_be4d349b","line":1586,"range":{"start_line":1586,"start_character":34,"end_line":1586,"end_character":45},"updated":"2017-09-28 21:00:04.000000000","message":"nit: we could also assert this value is an empty list.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":1583,"context_line":"        tag_list \u003d tags[0] + \u0027,\u0027 + tags[1]"},{"line_number":1584,"context_line":"        project_ref \u003d self.resource_api.list_projects_by_tags("},{"line_number":1585,"context_line":"            tag_list, \u0027filter_not_tags\u0027)"},{"line_number":1586,"context_line":"        self.assertNotIn(project, project_ref)"},{"line_number":1587,"context_line":""},{"line_number":1588,"context_line":"    def test_list_projects_not_tags_any(self):"},{"line_number":1589,"context_line":"        project, tags \u003d self._create_project_and_tags(tag_size\u003d2)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_ea601838","line":1586,"range":{"start_line":1586,"start_character":34,"end_line":1586,"end_character":45},"in_reply_to":"7f515b1d_be4d349b","updated":"2017-10-04 20:13:11.000000000","message":"This fails when asserting against an empty list, I think the testcase setup creates other projects as well that are returned.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1591,"context_line":"            tags[0], \u0027filter_not_tags_any\u0027)"},{"line_number":1592,"context_line":"        project_ref_alt \u003d self.resource_api.list_projects_by_tags("},{"line_number":1593,"context_line":"            tags[-1], \u0027filter_not_tags_any\u0027)"},{"line_number":1594,"context_line":"        self.assertNotIn(project, project_ref)"},{"line_number":1595,"context_line":"        self.assertNotIn(project, project_ref_alt)"},{"line_number":1596,"context_line":""},{"line_number":1597,"context_line":"    def test_get_project_contains_tags(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_fe2bac91","line":1594,"range":{"start_line":1594,"start_character":34,"end_line":1594,"end_character":45},"updated":"2017-09-28 21:00:04.000000000","message":"nit: same comment here as above.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1595,"context_line":"        self.assertNotIn(project, project_ref_alt)"},{"line_number":1596,"context_line":""},{"line_number":1597,"context_line":"    def test_get_project_contains_tags(self):"},{"line_number":1598,"context_line":"        project, _ \u003d self._create_project_and_tags(tag_size\u003d1)"},{"line_number":1599,"context_line":"        tag \u003d uuid.uuid4().hex"},{"line_number":1600,"context_line":"        self.resource_api.create_project_tag(project[\u0027id\u0027], tag)"},{"line_number":1601,"context_line":"        project[\u0027tags\u0027].append(tag)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_de28f097","line":1598,"range":{"start_line":1598,"start_character":60,"end_line":1598,"end_character":61},"updated":"2017-09-28 21:00:04.000000000","message":"nit: this is the default, so we don\u0027t need to specify it here.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":1595,"context_line":"        self.assertNotIn(project, project_ref_alt)"},{"line_number":1596,"context_line":""},{"line_number":1597,"context_line":"    def test_get_project_contains_tags(self):"},{"line_number":1598,"context_line":"        project, _ \u003d self._create_project_and_tags(tag_size\u003d1)"},{"line_number":1599,"context_line":"        tag \u003d uuid.uuid4().hex"},{"line_number":1600,"context_line":"        self.resource_api.create_project_tag(project[\u0027id\u0027], tag)"},{"line_number":1601,"context_line":"        project[\u0027tags\u0027].append(tag)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_ca655c47","line":1598,"range":{"start_line":1598,"start_character":60,"end_line":1598,"end_character":61},"in_reply_to":"7f515b1d_de28f097","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1607,"context_line":""},{"line_number":1608,"context_line":"    def test_list_project_tags(self):"},{"line_number":1609,"context_line":"        # GET /v3/projects/{project_id}/tags"},{"line_number":1610,"context_line":"        project, tags \u003d self._create_project_and_tags(tag_size\u003d1)"},{"line_number":1611,"context_line":"        tag_ref \u003d self.resource_api.list_project_tags(project[\u0027id\u0027])"},{"line_number":1612,"context_line":"        self.assertEqual(tags[0], tag_ref[0])"},{"line_number":1613,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_fe04cc19","line":1610,"range":{"start_line":1610,"start_character":53,"end_line":1610,"end_character":65},"updated":"2017-09-28 21:00:04.000000000","message":"Same comment here as above.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1622,"context_line":"        tag_ref \u003d self.resource_api.get_project_tag(project[\u0027id\u0027], tags[0])"},{"line_number":1623,"context_line":"        self.assertEqual(tags[0], tag_ref)"},{"line_number":1624,"context_line":""},{"line_number":1625,"context_line":"    def test_create_project_tag_with_trailing_whitespace(self):"},{"line_number":1626,"context_line":"        # PUT /v3/projects/{project_id}/tags/{tag}"},{"line_number":1627,"context_line":"        project, _ \u003d self._create_project_and_tags(tag_size\u003d1)"},{"line_number":1628,"context_line":"        tag \u003d uuid.uuid4().hex + \u0027   \u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_7906b61e","line":1625,"range":{"start_line":1625,"start_character":32,"end_line":1625,"end_character":36},"updated":"2017-09-28 21:00:04.000000000","message":"nit: trims","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1624,"context_line":""},{"line_number":1625,"context_line":"    def test_create_project_tag_with_trailing_whitespace(self):"},{"line_number":1626,"context_line":"        # PUT /v3/projects/{project_id}/tags/{tag}"},{"line_number":1627,"context_line":"        project, _ \u003d self._create_project_and_tags(tag_size\u003d1)"},{"line_number":1628,"context_line":"        tag \u003d uuid.uuid4().hex + \u0027   \u0027"},{"line_number":1629,"context_line":"        tag_ref \u003d self.resource_api.create_project_tag(project[\u0027id\u0027], tag)"},{"line_number":1630,"context_line":"        self.assertEqual(tag.strip(), tag_ref)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_393ddec3","line":1627,"range":{"start_line":1627,"start_character":51,"end_line":1627,"end_character":61},"updated":"2017-09-28 21:00:04.000000000","message":"This is the default.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1636,"context_line":"                          self.resource_api.create_project_tag,"},{"line_number":1637,"context_line":"                          project[\u0027id\u0027], last_tag)"},{"line_number":1638,"context_line":""},{"line_number":1639,"context_line":"    def test_create_project_tag_case_creates_different_tags(self):"},{"line_number":1640,"context_line":"        project, _ \u003d self._create_project_and_tags(tag_size\u003d1)"},{"line_number":1641,"context_line":"        new_tags \u003d [\u0027aaa\u0027, \u0027AAA\u0027]"},{"line_number":1642,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_f9198679","line":1639,"range":{"start_line":1639,"start_character":32,"end_line":1639,"end_character":59},"updated":"2017-09-28 21:00:04.000000000","message":"is_case_sensitive","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":1636,"context_line":"                          self.resource_api.create_project_tag,"},{"line_number":1637,"context_line":"                          project[\u0027id\u0027], last_tag)"},{"line_number":1638,"context_line":""},{"line_number":1639,"context_line":"    def test_create_project_tag_case_creates_different_tags(self):"},{"line_number":1640,"context_line":"        project, _ \u003d self._create_project_and_tags(tag_size\u003d1)"},{"line_number":1641,"context_line":"        new_tags \u003d [\u0027aaa\u0027, \u0027AAA\u0027]"},{"line_number":1642,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_aa5a2080","line":1639,"range":{"start_line":1639,"start_character":32,"end_line":1639,"end_character":59},"in_reply_to":"7f515b1d_f9198679","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1637,"context_line":"                          project[\u0027id\u0027], last_tag)"},{"line_number":1638,"context_line":""},{"line_number":1639,"context_line":"    def test_create_project_tag_case_creates_different_tags(self):"},{"line_number":1640,"context_line":"        project, _ \u003d self._create_project_and_tags(tag_size\u003d1)"},{"line_number":1641,"context_line":"        new_tags \u003d [\u0027aaa\u0027, \u0027AAA\u0027]"},{"line_number":1642,"context_line":""},{"line_number":1643,"context_line":"        ref \u003d self.resource_api.update_project_tags(project[\u0027id\u0027], new_tags)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_791fd65a","line":1640,"range":{"start_line":1640,"start_character":51,"end_line":1640,"end_character":61},"updated":"2017-09-28 21:00:04.000000000","message":"This is the default.","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1653,"context_line":"        self.assertIn(\u0027foo bar\u0027, ref)"},{"line_number":1654,"context_line":""},{"line_number":1655,"context_line":"    def test_update_project_tags(self):"},{"line_number":1656,"context_line":"        # PUT /v3/projects/{projecti_id}/tags"},{"line_number":1657,"context_line":"        project, tags \u003d self._create_project_and_tags(tag_size\u003d2)"},{"line_number":1658,"context_line":"        project_tag_ref \u003d self.resource_api.list_project_tags(project[\u0027id\u0027])"},{"line_number":1659,"context_line":"        self.assertEqual(len(project_tag_ref), 2)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_d916ca49","line":1656,"range":{"start_line":1656,"start_character":35,"end_line":1656,"end_character":36},"updated":"2017-09-28 21:00:04.000000000","message":"rogue \u0027i\u0027","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"658ca67a04f6fb35a9cc4783b9fae4a195bf90a5","unresolved":false,"context_lines":[{"line_number":1653,"context_line":"        self.assertIn(\u0027foo bar\u0027, ref)"},{"line_number":1654,"context_line":""},{"line_number":1655,"context_line":"    def test_update_project_tags(self):"},{"line_number":1656,"context_line":"        # PUT /v3/projects/{projecti_id}/tags"},{"line_number":1657,"context_line":"        project, tags \u003d self._create_project_and_tags(tag_size\u003d2)"},{"line_number":1658,"context_line":"        project_tag_ref \u003d self.resource_api.list_project_tags(project[\u0027id\u0027])"},{"line_number":1659,"context_line":"        self.assertEqual(len(project_tag_ref), 2)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_8a5f6471","line":1656,"range":{"start_line":1656,"start_character":35,"end_line":1656,"end_character":36},"in_reply_to":"7f515b1d_d916ca49","updated":"2017-10-04 20:13:11.000000000","message":"Done","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"93b4f24a571b10fc0bdf4703661943c2a79cb941","unresolved":false,"context_lines":[{"line_number":1678,"context_line":"        self.resource_api.delete_project_tag(project[\u0027id\u0027], tag_to_delete)"},{"line_number":1679,"context_line":"        project_tag_ref \u003d self.resource_api.list_project_tags("},{"line_number":1680,"context_line":"            project[\u0027id\u0027])"},{"line_number":1681,"context_line":"        self.assertEqual(len(project_tag_ref), 1)"},{"line_number":1682,"context_line":""},{"line_number":1683,"context_line":"    def test_delete_project_tag_returns_not_found(self):"},{"line_number":1684,"context_line":"        self.assertRaises(exception.ProjectNotFound,"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_b9778ea0","line":1681,"range":{"start_line":1681,"start_character":8,"end_line":1681,"end_character":49},"updated":"2017-09-28 21:00:04.000000000","message":"We can even assert the other tag hasn\u0027t been removed or changed.\n\n  self.assertEqual(project_tag_ref[0], tags[0])","commit_id":"6f7027be17f267b1f812a5f436c9ffd2ff4413ba"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"c6793f11647731a010e0301894e3ce66fbd98af4","unresolved":false,"context_lines":[{"line_number":1566,"context_line":"        self.assertIn(tag, ref[\u0027tags\u0027])"},{"line_number":1567,"context_line":""},{"line_number":1568,"context_line":"    def test_list_project_tags(self):"},{"line_number":1569,"context_line":"        # GET /v3/projects/{project_id}/tags"},{"line_number":1570,"context_line":"        project, tags \u003d self._create_project_and_tags(num_of_tags\u003d1)"},{"line_number":1571,"context_line":"        tag_ref \u003d self.resource_api.list_project_tags(project[\u0027id\u0027])"},{"line_number":1572,"context_line":"        self.assertEqual(tags[0], tag_ref[0])"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_0f91e947","line":1569,"range":{"start_line":1569,"start_character":8,"end_line":1569,"end_character":44},"updated":"2017-10-13 16:04:14.000000000","message":"This is also going to be tested in full when the controller patch is implemented because we should be able to do actual RESTful tests. This is just testing the backend method.","commit_id":"5140e5a451afb601a44a83f4d5731d56e896b1f1"}]}
