)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"ae88744f198a1cb1f4a7d4dcc2b64c8a9271e8ac","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"725f3c7d_cfa79ffd","updated":"2026-09-03 15:41:16.000000000","message":"I checked the API docs for all components using tagMixin. Only Image expects repeated tag\u003d params. All others use comma-separated (tags\u003dtag1,tag2). I covered these cases with unit tests. Would you like me to also add functional tests for this behavior?","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"112db939eeafadeef705348ce919306a2102b363","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"d043a723_d5191baf","updated":"2026-09-01 09:19:08.000000000","message":"Tag-based resource filtering was broken due to two issues:\n\n1. Tag lists were sent as repeated query parameters (`?tags\u003dtag1\u0026tags\u003dtag2`), but Openstack services expect comma-separated format (`?tags\u003dtag1,tag2`)\n2. Filtering via `_utils._filter_list` used exact value comparison, which never matched because the resource `tags` attribute is a list while the filter value was a string, and special filter keys (`tags-any`, `not-tags`) don\u0027t correspond to actual resource attributes\n\nFix:\n- Tag serialization now uses comma-separated format via `QueryParameters._transpose` type coercion, ensuring tags are sent as `tags\u003dtag1,tag2`\n- For tag-using resources, all filtering is delegated to the server side. client-side post-filtering via `_filter_list` is bypassed\n- `jmespath` filtering remains available when a string is passed to the filter","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"2ac69d9bbf1153634184566c4d065e2cff6f9463","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":1,"id":"4b92b3f1_9287b473","in_reply_to":"25aa26db_a805b0a8","updated":"2026-09-07 13:36:06.000000000","message":"I\u0027ve tested search_* methods with tags on my local devstack and tried different combinations of filters (tags,any_tags,not_tags,not_any_tags)\n\nCurrently Neutron is not affected by query parameter format.\n- `search_projects` - AttributeError for (any_tags,not_tags,not_any_tags) in _filter_list. Use only **first** param for filtering\n- `search_ports` - AttributeError for (any_tags,not_tags,not_any_tags) in _filter_list\n- `search_servers` - AttributeError for (any_tags,not_tags,not_any_tags) in _filter_list. Use only **last** param for filtering","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"726c4f23e12ee466922ca9349c9eaeb8dae57333","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":1,"id":"b1248b03_2656c616","in_reply_to":"4b92b3f1_9287b473","updated":"2026-09-08 10:26:55.000000000","message":"To verify the tag filtering behavior, I created three test objects with different tag combinations:\n```\n- name\u003dtag-test-AB: tags\u003d[tag-a, tag-b]\n- name\u003dtag-test-BC: tags\u003d[tag-b, tag-c]\n- name\u003dtag-test-A: tags\u003d[tag-a]\n```\nI tested different tag filters and compared the expected results with the API response and the actual query parameters sent by the SDK.\nFor example, for Nova:\n```\nRequest: GET /compute/v2.1/servers/detail?tags\u003dtag-a\u0026tags\u003dtag-b\n\nFilter:   tags\u003d[\u0027tag-a\u0027, \u0027tag-b\u0027]\nExpected: [tag-test-AB]\nFound:    [tag-test-AB, tag-test-BC]\n```\n\nSimilar behavior was observed for Keystone projects:\n```\nRequest: GET /identity/v3/projects?tags\u003dtag-a\u0026tags\u003dtag-c\n\nFilter:   tags\u003d[\u0027tag-a\u0027, \u0027tag-c\u0027]\nExpected: []\nFound:    [tag-test-A, tag-test-AB]\n```\n\nMost resources supporting tag filtering are Neutron network resources. Neutron supports both comma-separated and repeated tag parameters, so there is no strict requirement here. However, the API documentation uses the comma-separated format, e.g. `tags\u003dtag-a,tag-b`. (https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/add-tags-to-core-resources.html#rest-api-impact)","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"e114ff3b9d1bb2a1964b8c91a318d4e4b6ca4eec","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"25aa26db_a805b0a8","in_reply_to":"62c29c49_565bb1c2","updated":"2026-09-04 14:39:50.000000000","message":"this definitely cannot be broken for _all_ services since every service uses different framework for parsing args and implements tags differently","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"c21a21e106eb11e8f41b7c8ff99bf7c37b21b73f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"e499b2c5_c9e2f4f0","in_reply_to":"725f3c7d_cfa79ffd","updated":"2026-09-04 11:48:13.000000000","message":"That would be helpful but it\u0027s a big ask. If you\u0027re happy to do this, please do. If not, I\u0027d be happy with a list of references to the API docs you looked at proving this. It wasn\u0027t clear to me you\u0027d already done this work 😀","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"01eedf4296c6dd8917ac0239727df1dcdbb6ddcc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"62c29c49_565bb1c2","in_reply_to":"d043a723_d5191baf","updated":"2026-09-03 13:37:02.000000000","message":"I believe this is (unfortunately) specific to individual services. I recently proposed a patch to Octavia (load balancing) [to clarify what tag format they support](https://review.opendev.org/c/openstack/octavia/+/1000092).\n\nAre you sure that passing multiple tags as separate params is broken for all services, or just some services? Conversely, are you sure that passing a single param in CSV format works for all services, or just some of them?","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"ada5ad79d60617b958fc6a94e856080d46982020","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"29117059_e3e38726","in_reply_to":"e499b2c5_c9e2f4f0","updated":"2026-09-04 15:43:35.000000000","message":"identity - https://docs.openstack.org/api-ref/identity/v3/#filtering-and-searching-by-tags\n\ncompute -  https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id23\nhttps://docs.openstack.org/api-ref/compute/#list-server-request\n\t\nloadbalancer - https://docs.openstack.org/api-ref/load-balancer/v2/#filtering-by-tags\n\nnetwork. - https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/add-tags-to-core-resources.html#rest-api-impact\nhttps://docs.openstack.org/api-ref/network/v2/index.html#id19\n\nstack - https://docs.openstack.org/api-ref/orchestration/v1/#id17\n\nimages - https://docs.openstack.org/api-ref/image/v2/#id10","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"00f025924f4df9214710d65c38c5b50ba6447524","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"6bb346f7_689315e0","updated":"2026-09-15 09:30:55.000000000","message":"Can we take the changes to `openstack/common/tag.py` and `openstack/resource.py` and move those out to a separate precursor patch? Those are far less complicated and controversial and should be easier to merge. As noted inline, I need to think about how we can address the server-side vs. client-side filters in the cloud layer.","commit_id":"92f4ecc20296b8dd73fc8e85ebeeb83efd10b7c0"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"a21de7a0573ade87c874ad8f8b0ac0b2dccc12fb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"610602a7_20d76831","in_reply_to":"1b1122c4_ef420ad7","updated":"2026-10-08 12:52:06.000000000","message":"We can completely remove dict filtering part from post-filtering in `_filter_list`, because it\u0027s already implemented in the proxy layer. Proxy layer already separates API-side and client-side filters and handles filtering for both cases\nThis way:\n- we keep support for all types of filtering: API-side, client-side, and jmespath\n- we avoid applying filters twice\n- we keep overall code structure, since we only need to change `_filter_list`\n\nWhat do you think?","commit_id":"92f4ecc20296b8dd73fc8e85ebeeb83efd10b7c0"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"906c0af6d488e8e390383b9e9ecb147e8a0e1949","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"26214727_066ab532","in_reply_to":"32831185_f38a9477","updated":"2026-10-08 14:00:53.000000000","message":"client-side filtering `Resource.list`: https://github.com/openstack/openstacksdk/blob/master/openstack/resource.py#L2325\n\nOne more thing I missed: first, we would need to move the filtering to `Resource.list` in all the relevant list methods in the cloud layer. Then we can remove the dict filtering from `_filter_list`.","commit_id":"92f4ecc20296b8dd73fc8e85ebeeb83efd10b7c0"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"98836eb972a6fd0f9b167effb0607c52ff67a917","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"32831185_f38a9477","in_reply_to":"610602a7_20d76831","updated":"2026-10-08 12:57:04.000000000","message":"Small correction: I meant the `Resource.list` method, not the proxy layer.","commit_id":"92f4ecc20296b8dd73fc8e85ebeeb83efd10b7c0"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"e5d3d85344daf5841b5563d388190fa86433eb66","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"1b1122c4_ef420ad7","in_reply_to":"6bb346f7_689315e0","updated":"2026-09-15 14:16:30.000000000","message":"Done\nhttps://review.opendev.org/c/openstack/openstacksdk/+/1005733","commit_id":"92f4ecc20296b8dd73fc8e85ebeeb83efd10b7c0"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"6dab460fe90994551242466d6c0078d9c6f2dd22","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"6d6390b0_2299e80e","updated":"2026-10-14 11:34:15.000000000","message":"I rebased the branch and removed the code that was moved to separate MRs.\n\nThis MR now focuses on: \n- double filtering in `_filter_list()`\n- passing filters to `Resource.list()` (this also fixes tag filtering and makes more filters available)\n\nI think we could gradually update the other Cloud layer methods to use the same approach. It would also make it easier to get rid of `jmespath` filtering later.\n\nWhat do you think?","commit_id":"a5e349a1eddefd78287606f290d6905c145ce19b"}],"openstack/cloud/_compute.py":[{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"e114ff3b9d1bb2a1964b8c91a318d4e4b6ca4eec","unresolved":true,"context_lines":[{"line_number":217,"context_line":"                filters\u003dfilters,"},{"line_number":218,"context_line":"            )"},{"line_number":219,"context_line":"            return _utils._filter_list(servers, name_or_id, None)"},{"line_number":220,"context_line":"        else:"},{"line_number":221,"context_line":"            # (jmespath) client-side filter (backwards compat)"},{"line_number":222,"context_line":"            servers \u003d self.list_servers("},{"line_number":223,"context_line":"                detailed\u003ddetailed,"}],"source_content_type":"text/x-python","patch_set":1,"id":"93d74fb1_46a1ee0e","line":220,"updated":"2026-09-04 14:39:50.000000000","message":"honestly I am not fan of re-introducing deviating style to cloud layer few years after we finally aligned all (or at least all) methods to look similarly.","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"85de865aa36724518d54adff35d341e1fc483cd8","unresolved":true,"context_lines":[{"line_number":217,"context_line":"                filters\u003dfilters,"},{"line_number":218,"context_line":"            )"},{"line_number":219,"context_line":"            return _utils._filter_list(servers, name_or_id, None)"},{"line_number":220,"context_line":"        else:"},{"line_number":221,"context_line":"            # (jmespath) client-side filter (backwards compat)"},{"line_number":222,"context_line":"            servers \u003d self.list_servers("},{"line_number":223,"context_line":"                detailed\u003ddetailed,"}],"source_content_type":"text/x-python","patch_set":1,"id":"0cf8149e_af00135e","line":220,"in_reply_to":"93d74fb1_46a1ee0e","updated":"2026-09-05 09:30:21.000000000","message":"I agree this isn\u0027t ideal. I\u0027d move all filtering server-side and bypass `_filter_list` entirely, but I\u0027m not sure we can fully drop it right now.\n\nGoing forward, I\u0027d suggest deprecating `search_*` (OpenStackDeprecationWarning) for the dict-filters case — point users to `list_*` directly, which already handles server-side pushdown via `_query_mapping`. `search_*` would remain only for name_or_id lookup and jmespath until it\u0027s removed.\n\nFor this patch, I kept the isinstance branching as a transitional step. Note that the current codebase already has inconsistent filtering patterns:\n\n`search_networks` — server-side only\n`search_servers` — mixed\n`search_stacks` — client-side only","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"00f025924f4df9214710d65c38c5b50ba6447524","unresolved":true,"context_lines":[{"line_number":426,"context_line":"        detailed: bool \u003d False,"},{"line_number":427,"context_line":"        all_projects: bool \u003d False,"},{"line_number":428,"context_line":"        bare: bool \u003d False,"},{"line_number":429,"context_line":"        filters: dict[str, Any] | str | None \u003d None,"},{"line_number":430,"context_line":"    ) -\u003e list[_server.Server]:"},{"line_number":431,"context_line":"        \"\"\"List all available servers."},{"line_number":432,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"30062e18_91bb09a1","line":429,"updated":"2026-09-15 09:30:55.000000000","message":"Do we need to make this change? We\u0027ve deprecated JMES support: I\u0027m not sure we should be re-adding it? Ditto for the other list changes.\n\nLater: Okay, this is a response to gtema\u0027s comment on PS1 https://review.opendev.org/c/openstack/openstacksdk/+/1002968/comment/93d74fb1_46a1ee0e/. Hmm, that\u0027s not ideal but neither is this. I need to think about this...","commit_id":"92f4ecc20296b8dd73fc8e85ebeeb83efd10b7c0"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"e5d3d85344daf5841b5563d388190fa86433eb66","unresolved":true,"context_lines":[{"line_number":426,"context_line":"        detailed: bool \u003d False,"},{"line_number":427,"context_line":"        all_projects: bool \u003d False,"},{"line_number":428,"context_line":"        bare: bool \u003d False,"},{"line_number":429,"context_line":"        filters: dict[str, Any] | str | None \u003d None,"},{"line_number":430,"context_line":"    ) -\u003e list[_server.Server]:"},{"line_number":431,"context_line":"        \"\"\"List all available servers."},{"line_number":432,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"f6ea3cc4_d281d28d","line":429,"in_reply_to":"30062e18_91bb09a1","updated":"2026-09-15 14:16:30.000000000","message":"I noticed branch for handle JMES in `resource.list` flow and decided to use it to replace last ugly implementation. Because of this I can exclude `filters` from `_filter_list`\n\nif JMES completely deprecated already I can remove `str` from filters. Should I change datatype of `filters` in `search_*` methods also?","commit_id":"92f4ecc20296b8dd73fc8e85ebeeb83efd10b7c0"}],"openstack/common/tag.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"6de06e3d3da0093a340c6b8f4f34315c40fcd22a","unresolved":true,"context_lines":[{"line_number":25,"context_line":"    not_any_tags: resource.QueryMapping"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TagMixin(resource.ResourceMixinProtocol):"},{"line_number":29,"context_line":"    _tag_query_parameters: _TagQueryParameters \u003d {"},{"line_number":30,"context_line":"        \u0027tags\u0027: {\u0027name\u0027: \u0027tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":31,"context_line":"        \u0027any_tags\u0027: {\u0027name\u0027: \u0027tags-any\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":32,"context_line":"        \u0027not_tags\u0027: {\u0027name\u0027: \u0027not-tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":33,"context_line":"        \u0027not_any_tags\u0027: {"},{"line_number":34,"context_line":"            \u0027name\u0027: \u0027not-tags-any\u0027,"},{"line_number":35,"context_line":"            \u0027type\u0027: utils.comma_separated_list,"},{"line_number":36,"context_line":"        },"},{"line_number":37,"context_line":"    }"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    #: A list of associated tags"},{"line_number":40,"context_line":"    #: *Type: list of tag strings*"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a03b3f6_78c160bc","line":37,"range":{"start_line":28,"start_character":47,"end_line":37,"end_character":5},"updated":"2026-09-04 11:51:31.000000000","message":"How about we move this out of the class, drop the prefix, and duplicate/rename it (e.g. `tag_multiopt_query_parameters` and `tag_csv_query_parameters`: I\u0027m open to better names). That way we can explicitly use the correct form for each service?","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"ada5ad79d60617b958fc6a94e856080d46982020","unresolved":true,"context_lines":[{"line_number":25,"context_line":"    not_any_tags: resource.QueryMapping"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TagMixin(resource.ResourceMixinProtocol):"},{"line_number":29,"context_line":"    _tag_query_parameters: _TagQueryParameters \u003d {"},{"line_number":30,"context_line":"        \u0027tags\u0027: {\u0027name\u0027: \u0027tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":31,"context_line":"        \u0027any_tags\u0027: {\u0027name\u0027: \u0027tags-any\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":32,"context_line":"        \u0027not_tags\u0027: {\u0027name\u0027: \u0027not-tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":33,"context_line":"        \u0027not_any_tags\u0027: {"},{"line_number":34,"context_line":"            \u0027name\u0027: \u0027not-tags-any\u0027,"},{"line_number":35,"context_line":"            \u0027type\u0027: utils.comma_separated_list,"},{"line_number":36,"context_line":"        },"},{"line_number":37,"context_line":"    }"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    #: A list of associated tags"},{"line_number":40,"context_line":"    #: *Type: list of tag strings*"}],"source_content_type":"text/x-python","patch_set":1,"id":"c7415d97_9b4a4828","line":37,"range":{"start_line":28,"start_character":47,"end_line":37,"end_character":5},"in_reply_to":"5a03b3f6_78c160bc","updated":"2026-09-04 15:43:35.000000000","message":"Most services already use tags separated by commas, and Glance is the only exception - handled by local override and covered by tests.\nThe OpenStack REST API guideline recommends this format (https://specs.openstack.org/openstack/api-wg/guidelines/tags.html#filtering-and-searching-by-tags). Mind if we shelve this until a second exception comes up?","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"ada5ad79d60617b958fc6a94e856080d46982020","unresolved":true,"context_lines":[{"line_number":25,"context_line":"    not_any_tags: resource.QueryMapping"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TagMixin(resource.ResourceMixinProtocol):"},{"line_number":29,"context_line":"    _tag_query_parameters: _TagQueryParameters \u003d {"},{"line_number":30,"context_line":"        \u0027tags\u0027: {\u0027name\u0027: \u0027tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":31,"context_line":"        \u0027any_tags\u0027: {\u0027name\u0027: \u0027tags-any\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":32,"context_line":"        \u0027not_tags\u0027: {\u0027name\u0027: \u0027not-tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":33,"context_line":"        \u0027not_any_tags\u0027: {"},{"line_number":34,"context_line":"            \u0027name\u0027: \u0027not-tags-any\u0027,"},{"line_number":35,"context_line":"            \u0027type\u0027: utils.comma_separated_list,"},{"line_number":36,"context_line":"        },"},{"line_number":37,"context_line":"    }"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    #: A list of associated tags"},{"line_number":40,"context_line":"    #: *Type: list of tag strings*"}],"source_content_type":"text/x-python","patch_set":1,"id":"f8f5897e_a60bdc08","line":37,"range":{"start_line":28,"start_character":47,"end_line":37,"end_character":5},"in_reply_to":"5a03b3f6_78c160bc","updated":"2026-09-04 15:43:35.000000000","message":"Most services already use tags separated by commas, and Images is the only exception - handled by local override and covered by tests.\nThe OpenStack REST API guideline recommends this format (https://specs.openstack.org/openstack/api-wg/guidelines/tags.html#filtering-and-searching-by-tags). Mind if we shelve this until a second exception comes up?","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"e9c2a38a01427e321ce8753bb8e63361bc55950e","unresolved":true,"context_lines":[{"line_number":25,"context_line":"    not_any_tags: resource.QueryMapping"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TagMixin(resource.ResourceMixinProtocol):"},{"line_number":29,"context_line":"    _tag_query_parameters: _TagQueryParameters \u003d {"},{"line_number":30,"context_line":"        \u0027tags\u0027: {\u0027name\u0027: \u0027tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":31,"context_line":"        \u0027any_tags\u0027: {\u0027name\u0027: \u0027tags-any\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":32,"context_line":"        \u0027not_tags\u0027: {\u0027name\u0027: \u0027not-tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":33,"context_line":"        \u0027not_any_tags\u0027: {"},{"line_number":34,"context_line":"            \u0027name\u0027: \u0027not-tags-any\u0027,"},{"line_number":35,"context_line":"            \u0027type\u0027: utils.comma_separated_list,"},{"line_number":36,"context_line":"        },"},{"line_number":37,"context_line":"    }"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    #: A list of associated tags"},{"line_number":40,"context_line":"    #: *Type: list of tag strings*"}],"source_content_type":"text/x-python","patch_set":1,"id":"a5e2b1bf_e45af185","line":37,"range":{"start_line":28,"start_character":47,"end_line":37,"end_character":5},"in_reply_to":"f8f5897e_a60bdc08","updated":"2026-10-02 04:54:59.000000000","message":"I think I underestimated your suggestion. Actually we have 3 different formats of query tags:\n\n`tag_query_parameters` - `tag\u003dA\u0026tag\u003dB`\n`tags_csv_underscore_parameters` - `any_tags\u003dA,B`\n`tags_csv_query_parameters` - `any-tags\u003dA,B`\n\nIf you haven\u0027t started working on this yet, I can make a separate MR for this change. But I\u0027d like to agree on the names first. What do you think?","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"cc0fa2914b99096eda10b933d770a3e6eba12f04","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TagMixin(resource.ResourceMixinProtocol):"},{"line_number":29,"context_line":"    _tag_query_parameters: _TagQueryParameters \u003d {"},{"line_number":30,"context_line":"        \u0027tags\u0027: {\u0027name\u0027: \u0027tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":31,"context_line":"        \u0027any_tags\u0027: {\u0027name\u0027: \u0027tags-any\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":32,"context_line":"        \u0027not_tags\u0027: {\u0027name\u0027: \u0027not-tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":33,"context_line":"        \u0027not_any_tags\u0027: {"}],"source_content_type":"text/x-python","patch_set":2,"id":"e5e3fb5a_cec8e8ee","line":30,"updated":"2026-09-14 19:02:31.000000000","message":"pep8: error: Incompatible types (expression has type \"Callable[[str | Iterable[str] | None], str | None]\", TypedDict item \"type\" has type \"Callable[[Any, type[Resource]], Resource | str | None]\")  [typeddict-item]","commit_id":"8eef97221be6839d08758d3ab77fc9437cc00cf2"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"cc0fa2914b99096eda10b933d770a3e6eba12f04","unresolved":false,"context_lines":[{"line_number":28,"context_line":"class TagMixin(resource.ResourceMixinProtocol):"},{"line_number":29,"context_line":"    _tag_query_parameters: _TagQueryParameters \u003d {"},{"line_number":30,"context_line":"        \u0027tags\u0027: {\u0027name\u0027: \u0027tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":31,"context_line":"        \u0027any_tags\u0027: {\u0027name\u0027: \u0027tags-any\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":32,"context_line":"        \u0027not_tags\u0027: {\u0027name\u0027: \u0027not-tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":33,"context_line":"        \u0027not_any_tags\u0027: {"},{"line_number":34,"context_line":"            \u0027name\u0027: \u0027not-tags-any\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"ac5daa5a_3a25d8f0","line":31,"updated":"2026-09-14 19:02:31.000000000","message":"pep8: error: Incompatible types (expression has type \"Callable[[str | Iterable[str] | None], str | None]\", TypedDict item \"type\" has type \"Callable[[Any, type[Resource]], Resource | str | None]\")  [typeddict-item]","commit_id":"8eef97221be6839d08758d3ab77fc9437cc00cf2"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"cc0fa2914b99096eda10b933d770a3e6eba12f04","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    _tag_query_parameters: _TagQueryParameters \u003d {"},{"line_number":30,"context_line":"        \u0027tags\u0027: {\u0027name\u0027: \u0027tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":31,"context_line":"        \u0027any_tags\u0027: {\u0027name\u0027: \u0027tags-any\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":32,"context_line":"        \u0027not_tags\u0027: {\u0027name\u0027: \u0027not-tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":33,"context_line":"        \u0027not_any_tags\u0027: {"},{"line_number":34,"context_line":"            \u0027name\u0027: \u0027not-tags-any\u0027,"},{"line_number":35,"context_line":"            \u0027type\u0027: utils.comma_separated_list,"}],"source_content_type":"text/x-python","patch_set":2,"id":"1e83a4e2_b0b65d21","line":32,"updated":"2026-09-14 19:02:31.000000000","message":"pep8: error: Incompatible types (expression has type \"Callable[[str | Iterable[str] | None], str | None]\", TypedDict item \"type\" has type \"Callable[[Any, type[Resource]], Resource | str | None]\")  [typeddict-item]","commit_id":"8eef97221be6839d08758d3ab77fc9437cc00cf2"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"cc0fa2914b99096eda10b933d770a3e6eba12f04","unresolved":false,"context_lines":[{"line_number":32,"context_line":"        \u0027not_tags\u0027: {\u0027name\u0027: \u0027not-tags\u0027, \u0027type\u0027: utils.comma_separated_list},"},{"line_number":33,"context_line":"        \u0027not_any_tags\u0027: {"},{"line_number":34,"context_line":"            \u0027name\u0027: \u0027not-tags-any\u0027,"},{"line_number":35,"context_line":"            \u0027type\u0027: utils.comma_separated_list,"},{"line_number":36,"context_line":"        },"},{"line_number":37,"context_line":"    }"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"4c9b9748_a0c83f64","line":35,"updated":"2026-09-14 19:02:31.000000000","message":"pep8: error: Incompatible types (expression has type \"Callable[[str | Iterable[str] | None], str | None]\", TypedDict item \"type\" has type \"Callable[[Any, type[Resource]], Resource | str | None]\")  [typeddict-item]","commit_id":"8eef97221be6839d08758d3ab77fc9437cc00cf2"}],"openstack/identity/v3/domain.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"c21a21e106eb11e8f41b7c8ff99bf7c37b21b73f","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":1,"id":"8816bc1a_99f197c3","updated":"2026-09-04 11:48:13.000000000","message":"This change looks legit:\n\nhttps://docs.openstack.org/api-ref/identity/v3/#list-domains\n\nCan you pull it out into a separate precursor patch and add a release note?","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"},{"author":{"_account_id":39399,"name":"Vladislav Terekhov","display_name":"Vlad","email":"VlSTerekhov@gmail.com","username":"tepex"},"change_message_id":"ada5ad79d60617b958fc6a94e856080d46982020","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"180f71cd_371e12da","in_reply_to":"8816bc1a_99f197c3","updated":"2026-09-04 15:43:35.000000000","message":"Done\nhttps://review.opendev.org/c/openstack/openstacksdk/+/1003997","commit_id":"e5d525136027e0c718aceb8475b1df3765c8460c"}]}
