)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"f28aaf42b02c12dea16145d267b08aadb0041adf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"9a39ef72_73872a31","updated":"2026-06-18 18:30:25.000000000","message":"a comment about the returned object in create_inventory method","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"fcd6eab25ac5dc91fcd92268043d1fa517da1f60","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"fedfae0d_a8075fd3","updated":"2026-06-03 09:53:11.000000000","message":"check-rdo","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"6084c9712dc35cd35c9a89f793fcf02484a07236","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"f8d2540b_dfb3b9c2","updated":"2026-06-04 12:19:31.000000000","message":"check-rdo job should be fixed now","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"bedac88f18e04ea101ff32e08982fc9b973dcd50","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"c721b621_e16b692d","updated":"2026-06-03 07:11:41.000000000","message":"recheck prometheus job timed out","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"d76b580a699986547a71fb965ec126ed42a4b0ce","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"8d512a1a_945c924e","updated":"2026-06-18 18:45:45.000000000","message":"voting again since the next patch solves the issue that I pointed here.","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"945178cb74870db747003a0de273bc2d4befc61d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"c7b14355_e3dd5042","updated":"2026-06-19 18:14:35.000000000","message":"Thanks","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"bc37361ca25ca9b20748225302fdcd132e3e39c1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"ddd7dbaf_7c7fab07","updated":"2026-06-19 07:41:14.000000000","message":"lgtm, it\u0027s consistent with the approach for other clients with openstacksdk.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"7be29583ff255edc393d27ce5a4f904fedee9f1d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"040b55ce_ba77fb9c","updated":"2026-06-19 09:31:16.000000000","message":"recheck","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"442f0621ae4aa43c0615d130f9ad7eb93db4a60b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"c3c4d5d5_19b35a5c","updated":"2026-06-19 11:50:50.000000000","message":"recheck","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"}],"watcher/common/placement_helper.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d148d9b6c18805122f5038adc87257925787381b","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"@dc.dataclass(frozen\u003dTrue)"},{"line_number":29,"context_line":"class Inventory:"},{"line_number":30,"context_line":"    \"\"\"Pure dataclass for placement inventory data."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    Extracted from the Placement API inventory response with all"}],"source_content_type":"text/x-python","patch_set":2,"id":"8ed0b7bf_1da1e751","line":29,"updated":"2026-06-19 09:40:35.000000000","message":"The Inventory dataclass could benefit from a to_dict() method for interoperability with code that may still expect dict-like access or for logging purposes.\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Easier transition for any code paths that may need to serialize or log inventory data in dict format.\n\n**Recommendation**:\nAdd a to_dict() method that returns the dict representation, useful for logging and backward compatibility in test assertions.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d148d9b6c18805122f5038adc87257925787381b","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    attributes resolved at construction time."},{"line_number":34,"context_line":"    \"\"\""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    total: int"},{"line_number":37,"context_line":"    reserved: int"},{"line_number":38,"context_line":"    min_unit: int"},{"line_number":39,"context_line":"    max_unit: int"}],"source_content_type":"text/x-python","patch_set":2,"id":"5d7b932b_1673adc3","line":36,"updated":"2026-06-19 09:40:35.000000000","message":"Inventory dataclass fields lack default values. If Placement API adds a new optional field in the future, the from_placement_api method will need modification even if the field is not used by Watcher.\n\n**Severity**: WARNING | **Confidence**: 0.7\n\n**Impact**: Tight coupling to the exact set of Placement API fields. Any API evolution requires code changes even if Watcher does not use the new fields.\n\n**Suggestion**:\nConsider whether this is acceptable given the existing pattern in nova_helper (which also uses explicit fields). If so, this is informational. If flexibility is desired, consider using **kwargs or a more flexible approach.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"430d42b5f7588544de1580df2ddc23058fbba4df","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    allocation_ratio: float"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    @classmethod"},{"line_number":44,"context_line":"    def from_placement_api(cls, inventory_dict):"},{"line_number":45,"context_line":"        \"\"\"Create an Inventory from a Placement API inventory dict."},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"        :param inventory_dict: dict from Placement API response"}],"source_content_type":"text/x-python","patch_set":2,"id":"92409fa8_42a6597a","line":44,"updated":"2026-06-19 12:00:11.000000000","message":"The from_placement_api classmethod accesses six dict keys without any error handling or validation. If the Placement API response is malformed or missing a key, a raw KeyError will propagate to the caller with no contextual information.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: A malformed Placement API response would cause an unhandled KeyError with an unhelpful message like \"\u0027total\u0027\" instead of a descriptive error indicating which resource provider or inventory field was missing.\n\n**Suggestion**:\nWrap the key access in a try/except block that catches KeyError and raises a more descriptive exception, or use .get() with validation. For example: try the construction, except KeyError as e: raise ValueError(f\u0027Missing inventory field {e} in placement response\u0027) from e. Alternatively, document that malformed responses are a caller responsibility.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"430d42b5f7588544de1580df2ddc23058fbba4df","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    allocation_ratio: float"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    @classmethod"},{"line_number":44,"context_line":"    def from_placement_api(cls, inventory_dict):"},{"line_number":45,"context_line":"        \"\"\"Create an Inventory from a Placement API inventory dict."},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"        :param inventory_dict: dict from Placement API response"}],"source_content_type":"text/x-python","patch_set":2,"id":"738ed4f4_366cdf2f","line":44,"updated":"2026-06-19 12:00:11.000000000","message":"The from_placement_api classmethod parameter inventory_dict lacks a type annotation. The get_inventories method uses modern type hints (dict[str, Inventory]) but from_placement_api does not annotate its input.\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Adding a type annotation like \u0027inventory_dict: dict\u0027 or \u0027inventory_dict: Mapping[str, Any]\u0027 improves IDE support, enables static type checking, and maintains consistency with the type hints already added to get_inventories.\n\n**Recommendation**:\nChange the signature to: def from_placement_api(cls, inventory_dict: dict) -\u003e \u0027Inventory\u0027: or use Mapping[str, int | float] for more precision.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d148d9b6c18805122f5038adc87257925787381b","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    allocation_ratio: float"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    @classmethod"},{"line_number":44,"context_line":"    def from_placement_api(cls, inventory_dict):"},{"line_number":45,"context_line":"        \"\"\"Create an Inventory from a Placement API inventory dict."},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"        :param inventory_dict: dict from Placement API response"}],"source_content_type":"text/x-python","patch_set":2,"id":"35d0ad63_602b3c62","line":44,"updated":"2026-06-19 09:40:35.000000000","message":"from_placement_api method parameter lacks a type hint while the get_inventories method in the same file was annotated in this patch, creating an inconsistency within the same module.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: Mixing annotated and unannotated signatures in the same module reduces the value of type hints and may confuse static analysis tools.\n\n**Suggestion**:\nAdd type hints to from_placement_api, e.g., def from_placement_api(cls, inventory_dict: dict) -\u003e \u0027Inventory\u0027: or use a TypedDict for the inventory_dict parameter.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"430d42b5f7588544de1580df2ddc23058fbba4df","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    @classmethod"},{"line_number":44,"context_line":"    def from_placement_api(cls, inventory_dict):"},{"line_number":45,"context_line":"        \"\"\"Create an Inventory from a Placement API inventory dict."},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"        :param inventory_dict: dict from Placement API response"},{"line_number":48,"context_line":"        :returns: Inventory dataclass instance"}],"source_content_type":"text/x-python","patch_set":2,"id":"9912dc28_f8ada730","line":45,"updated":"2026-06-19 12:00:11.000000000","message":"The from_placement_api docstring could include a :rtype directive for completeness, matching the documentation style used elsewhere in the project.\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Adding :rtype: Inventory improves generated API documentation and helps IDE autocompletion understand the return type from docstring parsing.\n\n**Recommendation**:\nAdd \u0027:rtype: Inventory\u0027 after the \u0027:returns:\u0027 line in the docstring.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d148d9b6c18805122f5038adc87257925787381b","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        :param inventory_dict: dict from Placement API response"},{"line_number":48,"context_line":"        :returns: Inventory dataclass instance"},{"line_number":49,"context_line":"        \"\"\""},{"line_number":50,"context_line":"        return cls("},{"line_number":51,"context_line":"            total\u003dinventory_dict[\u0027total\u0027],"},{"line_number":52,"context_line":"            reserved\u003dinventory_dict[\u0027reserved\u0027],"},{"line_number":53,"context_line":"            min_unit\u003dinventory_dict[\u0027min_unit\u0027],"}],"source_content_type":"text/x-python","patch_set":2,"id":"52e0d9ba_c769ae56","line":50,"updated":"2026-06-19 09:40:35.000000000","message":"from_placement_api uses direct dict key access (inventory_dict[\u0027total\u0027], etc.) without a fallback, which will raise KeyError if the Placement API response is missing a field.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: If the Placement API returns an inventory entry missing one of the expected fields (e.g., due to a version mismatch or API change), this will raise an unhandled KeyError instead of a clear error message.\n\n**Suggestion**:\nConsider wrapping the construction in a try/except KeyError with a descriptive error message, or use dict.get() with sensible defaults and log a warning for missing fields.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"430d42b5f7588544de1580df2ddc23058fbba4df","unresolved":false,"context_lines":[{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        return error_msg"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def get_inventories(self, rp_uuid: str) -\u003e dict[str, Inventory]:"},{"line_number":81,"context_line":"        \"\"\"Calls the placement API to get resource inventory information."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        :param rp_uuid: UUID of the resource provider to get."}],"source_content_type":"text/x-python","patch_set":2,"id":"699dc30e_305062d4","line":80,"updated":"2026-06-19 12:00:11.000000000","message":"The get_inventories method uses PEP 585 lowercase dict[str, Inventory] type hint syntax, but no other method in the watcher codebase uses this modern syntax. This creates a minor inconsistency.\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Using typing.Dict for consistency with the rest of the codebase, or keeping modern syntax but documenting the choice, would reduce confusion for contributors familiar with older conventions.\n\n**Recommendation**:\nEither use typing.Dict[str, Inventory] for consistency with broader OpenStack style, or keep the modern syntax since Python 3.10+ is the project minimum. Low priority.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d148d9b6c18805122f5038adc87257925787381b","unresolved":false,"context_lines":[{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        return error_msg"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def get_inventories(self, rp_uuid: str) -\u003e dict[str, Inventory]:"},{"line_number":81,"context_line":"        \"\"\"Calls the placement API to get resource inventory information."},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        :param rp_uuid: UUID of the resource provider to get."}],"source_content_type":"text/x-python","patch_set":2,"id":"6a81df84_1a5442ca","line":80,"updated":"2026-06-19 09:40:35.000000000","message":"get_inventories return type annotation is dict[str, Inventory] but the method can return None on failure (non-200 response). The annotation should be dict[str, Inventory] | None or Optional[dict[str, Inventory]].\n\n**Severity**: HIGH | **Confidence**: 0.9\n\n**Risk**: Callers and type checkers will not be aware that None can be returned, leading to potential AttributeError at runtime if the failure path is hit and callers do not guard with a None check.\n\n**Priority**: Before merge\n**Why This Matters**: The type annotation was introduced in this patch, so it should be accurate. Both callers (collector/nova.py and notification/nova.py) do check with \u0027if inventories and ...\u0027 which protects against None, but a wrong annotation misleads future developers and static analysis tools.\n\n**Recommendation**:\nChange the return type to dict[str, Inventory] | None (or Optional[dict[str, Inventory]] for older Python compatibility) to reflect the actual failure behavior.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"430d42b5f7588544de1580df2ddc23058fbba4df","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        url \u003d f\u0027/resource_providers/{rp_uuid}/inventories\u0027"},{"line_number":88,"context_line":"        resp \u003d self.get(url)"},{"line_number":89,"context_line":"        if resp.status_code \u003d\u003d HTTPStatus.OK:"},{"line_number":90,"context_line":"            json \u003d resp.json()"},{"line_number":91,"context_line":"            return {"},{"line_number":92,"context_line":"                rc: Inventory.from_placement_api(inv)"},{"line_number":93,"context_line":"                for rc, inv in json[\u0027inventories\u0027].items()"}],"source_content_type":"text/x-python","patch_set":2,"id":"0a3b0fcb_9c7bafd9","line":90,"updated":"2026-06-19 12:00:11.000000000","message":"The variable named \u0027json\u0027 on line 90 shadows the commonly-used json module name. While json is not imported in this file currently, this naming choice is error-prone if json is ever imported in the future.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: If a future maintainer adds \u0027import json\u0027 to this file, the local variable assignment will shadow the module, causing confusing AttributeError exceptions at runtime.\n\n**Suggestion**:\nRename the local variable from \u0027json\u0027 to \u0027json_resp\u0027 or \u0027body\u0027 to avoid shadowing the standard library module name.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"}],"watcher/tests/unit/common/test_placement_helper.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d148d9b6c18805122f5038adc87257925787381b","unresolved":false,"context_lines":[{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        expected_url \u003d f\u0027/resource_providers/{rp_uuid}/inventories\u0027"},{"line_number":150,"context_line":"        self._assert_keystone_called_once(kss_req, expected_url, \u0027GET\u0027)"},{"line_number":151,"context_line":"        expected \u003d {"},{"line_number":152,"context_line":"            rc: placement_helper.Inventory.from_placement_api(inv)"},{"line_number":153,"context_line":"            for rc, inv in fake_inventories.items()"},{"line_number":154,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":2,"id":"56116c00_f8fe31f8","line":151,"updated":"2026-06-19 09:40:35.000000000","message":"The test test_get_inventories_OK reconstructs the expected result using the same from_placement_api method being tested, which means a bug in from_placement_api would not be caught by this test.\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Constructing expected Inventory objects with explicit values would provide a stronger test that catches construction bugs independently.\n\n**Recommendation**:\nBuild expected Inventory objects directly via Inventory(total\u003d35, reserved\u003d0, ...) rather than using from_placement_api, so the test validates the conversion logic rather than reusing it.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"}],"watcher/tests/unit/common/utils.py":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"f28aaf42b02c12dea16145d267b08aadb0041adf","unresolved":true,"context_lines":[{"line_number":156,"context_line":"        :param kwargs: inventory attributes"},{"line_number":157,"context_line":"        :returns: placement_helper.Inventory instance"},{"line_number":158,"context_line":"        \"\"\""},{"line_number":159,"context_line":"        return {"},{"line_number":160,"context_line":"            \"total\": kwargs.pop(\u0027total\u0027, 0),"},{"line_number":161,"context_line":"            \"reserved\": kwargs.pop(\u0027reserved\u0027, 0),"},{"line_number":162,"context_line":"            \"min_unit\": kwargs.pop(\u0027min_unit\u0027, 1),"},{"line_number":163,"context_line":"            \"max_unit\": kwargs.pop(\u0027max_unit\u0027, 0),"},{"line_number":164,"context_line":"            \"step_size\": kwargs.pop(\u0027step_size\u0027, 1),"},{"line_number":165,"context_line":"            \"allocation_ratio\": kwargs.pop(\u0027allocation_ratio\u0027, 1.0),"},{"line_number":166,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":1,"id":"a23dff54_ca03141e","line":166,"range":{"start_line":159,"start_character":0,"end_line":166,"end_character":9},"updated":"2026-06-18 18:30:25.000000000","message":"this is returning a dict instead of a Inventory.\nisn\u0027t expected to return an Inventory(**inventory_info)?","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"d76b580a699986547a71fb965ec126ed42a4b0ce","unresolved":true,"context_lines":[{"line_number":156,"context_line":"        :param kwargs: inventory attributes"},{"line_number":157,"context_line":"        :returns: placement_helper.Inventory instance"},{"line_number":158,"context_line":"        \"\"\""},{"line_number":159,"context_line":"        return {"},{"line_number":160,"context_line":"            \"total\": kwargs.pop(\u0027total\u0027, 0),"},{"line_number":161,"context_line":"            \"reserved\": kwargs.pop(\u0027reserved\u0027, 0),"},{"line_number":162,"context_line":"            \"min_unit\": kwargs.pop(\u0027min_unit\u0027, 1),"},{"line_number":163,"context_line":"            \"max_unit\": kwargs.pop(\u0027max_unit\u0027, 0),"},{"line_number":164,"context_line":"            \"step_size\": kwargs.pop(\u0027step_size\u0027, 1),"},{"line_number":165,"context_line":"            \"allocation_ratio\": kwargs.pop(\u0027allocation_ratio\u0027, 1.0),"},{"line_number":166,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":1,"id":"dd247112_643b6010","line":166,"range":{"start_line":159,"start_character":0,"end_line":166,"end_character":9},"in_reply_to":"a23dff54_ca03141e","updated":"2026-06-18 18:45:45.000000000","message":"After reviewing the following patch..\nThis is fixed by actually replacing with openstacksdk inventory, which is aligned with other methods in this file. The only thing is that the docstring says \":returns: placement_helper.Inventory instance\"\nwhich is also fixed in next patch","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"945178cb74870db747003a0de273bc2d4befc61d","unresolved":false,"context_lines":[{"line_number":156,"context_line":"        :param kwargs: inventory attributes"},{"line_number":157,"context_line":"        :returns: placement_helper.Inventory instance"},{"line_number":158,"context_line":"        \"\"\""},{"line_number":159,"context_line":"        return {"},{"line_number":160,"context_line":"            \"total\": kwargs.pop(\u0027total\u0027, 0),"},{"line_number":161,"context_line":"            \"reserved\": kwargs.pop(\u0027reserved\u0027, 0),"},{"line_number":162,"context_line":"            \"min_unit\": kwargs.pop(\u0027min_unit\u0027, 1),"},{"line_number":163,"context_line":"            \"max_unit\": kwargs.pop(\u0027max_unit\u0027, 0),"},{"line_number":164,"context_line":"            \"step_size\": kwargs.pop(\u0027step_size\u0027, 1),"},{"line_number":165,"context_line":"            \"allocation_ratio\": kwargs.pop(\u0027allocation_ratio\u0027, 1.0),"},{"line_number":166,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":1,"id":"949ff976_19852322","line":166,"range":{"start_line":159,"start_character":0,"end_line":166,"end_character":9},"in_reply_to":"b1ba5328_d9600ef4","updated":"2026-06-19 18:14:35.000000000","message":"Done","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"b401da28bf08cd4d1e752c60fc24e3ff6f5b3c72","unresolved":true,"context_lines":[{"line_number":156,"context_line":"        :param kwargs: inventory attributes"},{"line_number":157,"context_line":"        :returns: placement_helper.Inventory instance"},{"line_number":158,"context_line":"        \"\"\""},{"line_number":159,"context_line":"        return {"},{"line_number":160,"context_line":"            \"total\": kwargs.pop(\u0027total\u0027, 0),"},{"line_number":161,"context_line":"            \"reserved\": kwargs.pop(\u0027reserved\u0027, 0),"},{"line_number":162,"context_line":"            \"min_unit\": kwargs.pop(\u0027min_unit\u0027, 1),"},{"line_number":163,"context_line":"            \"max_unit\": kwargs.pop(\u0027max_unit\u0027, 0),"},{"line_number":164,"context_line":"            \"step_size\": kwargs.pop(\u0027step_size\u0027, 1),"},{"line_number":165,"context_line":"            \"allocation_ratio\": kwargs.pop(\u0027allocation_ratio\u0027, 1.0),"},{"line_number":166,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":1,"id":"b1ba5328_d9600ef4","line":166,"range":{"start_line":159,"start_character":0,"end_line":166,"end_character":9},"in_reply_to":"dd247112_643b6010","updated":"2026-06-19 06:40:18.000000000","message":"it\u0027s the docstring what is wrong but this is correct. This method is mimicking how it curently gets information from placement API, as a json payload from the API request, I\u0027ll fix the docstring to be more accurate","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"d148d9b6c18805122f5038adc87257925787381b","unresolved":false,"context_lines":[{"line_number":150,"context_line":""},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"class PlacementResourcesMixin:"},{"line_number":153,"context_line":"    def create_inventory(self, **kwargs):"},{"line_number":154,"context_line":"        \"\"\"Create an Inventory representation."},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"        :param kwargs: inventory attributes"}],"source_content_type":"text/x-python","patch_set":2,"id":"bc6f3529_17dd2dd2","line":153,"updated":"2026-06-19 09:40:35.000000000","message":"The PlacementResourcesMixin.create_inventory method returns a plain dict rather than a placement_helper.Inventory object, which is inconsistent with the NovaResourcesMixin pattern where create_openstacksdk_server returns a Server object.\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Returning an Inventory directly would simplify test code that currently wraps the dict with Inventory.from_placement_api() at each call site.\n\n**Recommendation**:\nConsider having create_inventory return placement_helper.Inventory.from_placement_api(dict) directly, or rename to create_inventory_dict to clarify it returns a dict, not an Inventory object.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"430d42b5f7588544de1580df2ddc23058fbba4df","unresolved":false,"context_lines":[{"line_number":154,"context_line":"        \"\"\"Create an Inventory representation."},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"        :param kwargs: inventory attributes"},{"line_number":157,"context_line":"        :returns: json representation of an Inventory instance"},{"line_number":158,"context_line":"        \"\"\""},{"line_number":159,"context_line":"        return {"},{"line_number":160,"context_line":"            \"total\": kwargs.pop(\u0027total\u0027, 0),"}],"source_content_type":"text/x-python","patch_set":2,"id":"b161858f_b98b55d5","line":157,"updated":"2026-06-19 12:00:11.000000000","message":"The create_inventory docstring states it returns \u0027json representation of an Inventory instance\u0027 but it actually returns a plain Python dict. The term \u0027json representation\u0027 is misleading since no JSON serialization occurs.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: Developers reading the docstring may misunderstand what the method returns, leading to incorrect assumptions about the return type or thinking JSON serialization/deserialization is involved.\n\n**Suggestion**:\nUpdate the docstring to: \u0027:returns: a dict representation of placement inventory data\u0027 or \u0027:returns: a dict matching the Placement API inventory format\u0027.","commit_id":"d0f2173ce9a9f08818ee75a426a0b129203c343d"}],"watcher/tests/unit/decision_engine/cluster/test_nova_cdmc.py":[{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"f28aaf42b02c12dea16145d267b08aadb0041adf","unresolved":true,"context_lines":[{"line_number":64,"context_line":"        m_placement_helper \u003d mock.Mock(name\u003d\"placement_helper\")"},{"line_number":65,"context_line":"        m_placement_helper.get_inventories.return_value \u003d {"},{"line_number":66,"context_line":"            orc.VCPU: placement_helper.Inventory.from_placement_api("},{"line_number":67,"context_line":"                self.create_inventory("},{"line_number":68,"context_line":"                    allocation_ratio\u003d16.0, total\u003d8, max_unit\u003d8"},{"line_number":69,"context_line":"                )"},{"line_number":70,"context_line":"            ),"}],"source_content_type":"text/x-python","patch_set":1,"id":"22a8a794_7061351b","line":67,"range":{"start_line":67,"start_character":21,"end_line":67,"end_character":37},"updated":"2026-06-18 18:30:25.000000000","message":"create_inventory shoud return an Inventory instead","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"b401da28bf08cd4d1e752c60fc24e3ff6f5b3c72","unresolved":true,"context_lines":[{"line_number":64,"context_line":"        m_placement_helper \u003d mock.Mock(name\u003d\"placement_helper\")"},{"line_number":65,"context_line":"        m_placement_helper.get_inventories.return_value \u003d {"},{"line_number":66,"context_line":"            orc.VCPU: placement_helper.Inventory.from_placement_api("},{"line_number":67,"context_line":"                self.create_inventory("},{"line_number":68,"context_line":"                    allocation_ratio\u003d16.0, total\u003d8, max_unit\u003d8"},{"line_number":69,"context_line":"                )"},{"line_number":70,"context_line":"            ),"}],"source_content_type":"text/x-python","patch_set":1,"id":"4a2dd831_9f7d1fae","line":67,"range":{"start_line":67,"start_character":21,"end_line":67,"end_character":37},"in_reply_to":"22a8a794_7061351b","updated":"2026-06-19 06:40:18.000000000","message":"the type is correct, currently it gets placement information as a json payload from the placement API https://github.com/openstack/watcher/blob/master/watcher/common/placement_helper.py#L55-L56 so the `create_inventory` replicates that. In the next patch as you correctly noted I change the method to return Inventory objects from the opesntacksdk placement proxy","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"},{"author":{"_account_id":30002,"name":"Douglas Viroel","email":"viroel@gmail.com","username":"dviroel"},"change_message_id":"945178cb74870db747003a0de273bc2d4befc61d","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        m_placement_helper \u003d mock.Mock(name\u003d\"placement_helper\")"},{"line_number":65,"context_line":"        m_placement_helper.get_inventories.return_value \u003d {"},{"line_number":66,"context_line":"            orc.VCPU: placement_helper.Inventory.from_placement_api("},{"line_number":67,"context_line":"                self.create_inventory("},{"line_number":68,"context_line":"                    allocation_ratio\u003d16.0, total\u003d8, max_unit\u003d8"},{"line_number":69,"context_line":"                )"},{"line_number":70,"context_line":"            ),"}],"source_content_type":"text/x-python","patch_set":1,"id":"9427ec40_7aef6d4b","line":67,"range":{"start_line":67,"start_character":21,"end_line":67,"end_character":37},"in_reply_to":"4a2dd831_9f7d1fae","updated":"2026-06-19 18:14:35.000000000","message":"Acknowledged","commit_id":"9bcbcb4f9b73a893ed40f0e26d638880f8e4a5e2"}]}
