)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"73b90c6fe3384782fbfc5b8cc77adfdf3c75e2dd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"b6d6a2f7_4935efe4","updated":"2025-02-24 12:11:15.000000000","message":"has the same tag removal bug as the managed patch and I have couple of nits","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"189055dd2f939abf1d8b5d39821183e66d07adb7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"2168d02e_cb277d7a","updated":"2025-02-27 09:33:54.000000000","message":"I have just two small nits I can live with. This looks good now.","commit_id":"7b31a0b5e314bbfb183e8c6042119bd25e006d76"}],"nova/objects/pci_device.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"73b90c6fe3384782fbfc5b8cc77adfdf3c75e2dd","unresolved":true,"context_lines":[{"line_number":185,"context_line":"                data \u003d v if isinstance(v, str) else jsonutils.dumps(v)"},{"line_number":186,"context_line":"                extra_info.update({k: data})"},{"line_number":187,"context_line":"                self.extra_info \u003d extra_info"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":190,"context_line":"        super(PciDevice, self).__init__(*args, **kwargs)"},{"line_number":191,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"bb78578b_8d00716a","line":188,"updated":"2025-02-24 12:11:15.000000000","message":"needs similar field removal logic than suggested for managed","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"189055dd2f939abf1d8b5d39821183e66d07adb7","unresolved":false,"context_lines":[{"line_number":185,"context_line":"                data \u003d v if isinstance(v, str) else jsonutils.dumps(v)"},{"line_number":186,"context_line":"                extra_info.update({k: data})"},{"line_number":187,"context_line":"                self.extra_info \u003d extra_info"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":190,"context_line":"        super(PciDevice, self).__init__(*args, **kwargs)"},{"line_number":191,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"fb6a1f97_226b30f5","line":188,"in_reply_to":"bb78578b_8d00716a","updated":"2025-02-27 09:33:54.000000000","message":"Done","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"189055dd2f939abf1d8b5d39821183e66d07adb7","unresolved":true,"context_lines":[{"line_number":186,"context_line":"                extra_info.update({k: data})"},{"line_number":187,"context_line":"                self.extra_info \u003d extra_info"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"        # Remove the \"managed\" key if it was set previously"},{"line_number":190,"context_line":"        # As with the previous case, we must explicitly assign to"},{"line_number":191,"context_line":"        # self.extra_info so that obj_what_changed detects the modification"},{"line_number":192,"context_line":"        # and triggers a save later."}],"source_content_type":"text/x-python","patch_set":3,"id":"eef4653a_4ca3b592","line":189,"updated":"2025-02-27 09:33:54.000000000","message":"nit: update the comment that now it removes a set of tags not just managed","commit_id":"7b31a0b5e314bbfb183e8c6042119bd25e006d76"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2d8c3b8bc4fc3f2ce82e27d69e8c17499f4dedb3","unresolved":true,"context_lines":[{"line_number":186,"context_line":"                extra_info.update({k: data})"},{"line_number":187,"context_line":"                self.extra_info \u003d extra_info"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"        # Remove the \"managed\" key if it was set previously"},{"line_number":190,"context_line":"        # As with the previous case, we must explicitly assign to"},{"line_number":191,"context_line":"        # self.extra_info so that obj_what_changed detects the modification"},{"line_number":192,"context_line":"        # and triggers a save later."}],"source_content_type":"text/x-python","patch_set":3,"id":"9772c15c_9c0eaa75","line":189,"in_reply_to":"eef4653a_4ca3b592","updated":"2025-02-27 10:16:57.000000000","message":"yup, will have to be addressed in a FUP.","commit_id":"7b31a0b5e314bbfb183e8c6042119bd25e006d76"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"189055dd2f939abf1d8b5d39821183e66d07adb7","unresolved":true,"context_lines":[{"line_number":190,"context_line":"        # As with the previous case, we must explicitly assign to"},{"line_number":191,"context_line":"        # self.extra_info so that obj_what_changed detects the modification"},{"line_number":192,"context_line":"        # and triggers a save later."},{"line_number":193,"context_line":"        spec_tags \u003d [\"managed\", \"live_migratable\"]"},{"line_number":194,"context_line":"        for tag in spec_tags:"},{"line_number":195,"context_line":"            if tag not in dev_dict and tag in self.extra_info:"},{"line_number":196,"context_line":"                extra_info \u003d self.extra_info"}],"source_content_type":"text/x-python","patch_set":3,"id":"ffe5f813_72ae000c","line":193,"updated":"2025-02-27 09:33:54.000000000","message":"nit: I would call it something like `tags_to_clean`","commit_id":"7b31a0b5e314bbfb183e8c6042119bd25e006d76"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"db38cf04d4a09345a4c15c564ab162cb1b5da514","unresolved":true,"context_lines":[{"line_number":190,"context_line":"        # As with the previous case, we must explicitly assign to"},{"line_number":191,"context_line":"        # self.extra_info so that obj_what_changed detects the modification"},{"line_number":192,"context_line":"        # and triggers a save later."},{"line_number":193,"context_line":"        spec_tags \u003d [\"managed\", \"live_migratable\"]"},{"line_number":194,"context_line":"        for tag in spec_tags:"},{"line_number":195,"context_line":"            if tag not in dev_dict and tag in self.extra_info:"},{"line_number":196,"context_line":"                extra_info \u003d self.extra_info"}],"source_content_type":"text/x-python","patch_set":3,"id":"3df096a0_da8b5c38","line":193,"in_reply_to":"12eae422_ddcb1b70","updated":"2025-02-27 19:08:22.000000000","message":"ya that woudl be better","commit_id":"7b31a0b5e314bbfb183e8c6042119bd25e006d76"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2d8c3b8bc4fc3f2ce82e27d69e8c17499f4dedb3","unresolved":true,"context_lines":[{"line_number":190,"context_line":"        # As with the previous case, we must explicitly assign to"},{"line_number":191,"context_line":"        # self.extra_info so that obj_what_changed detects the modification"},{"line_number":192,"context_line":"        # and triggers a save later."},{"line_number":193,"context_line":"        spec_tags \u003d [\"managed\", \"live_migratable\"]"},{"line_number":194,"context_line":"        for tag in spec_tags:"},{"line_number":195,"context_line":"            if tag not in dev_dict and tag in self.extra_info:"},{"line_number":196,"context_line":"                extra_info \u003d self.extra_info"}],"source_content_type":"text/x-python","patch_set":3,"id":"12eae422_ddcb1b70","line":193,"in_reply_to":"ffe5f813_72ae000c","updated":"2025-02-27 10:16:57.000000000","message":"agreed","commit_id":"7b31a0b5e314bbfb183e8c6042119bd25e006d76"}],"nova/pci/devspec.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"73b90c6fe3384782fbfc5b8cc77adfdf3c75e2dd","unresolved":false,"context_lines":[{"line_number":319,"context_line":"            self.tags.get(PCI_REMOTE_MANAGED_TAG))"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"        self._normalize_device_spec_tag(\"managed\")"},{"line_number":322,"context_line":"        self._normalize_device_spec_tag(\"live_migratable\")"},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"        if self._remote_managed:"},{"line_number":325,"context_line":"            if address_obj is None:"}],"source_content_type":"text/x-python","patch_set":2,"id":"496a0817_4869c8b0","line":322,"updated":"2025-02-24 12:11:15.000000000","message":"this looks nice, thanks","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"73b90c6fe3384782fbfc5b8cc77adfdf3c75e2dd","unresolved":true,"context_lines":[{"line_number":415,"context_line":"                    else \"false\""},{"line_number":416,"context_line":"                )"},{"line_number":417,"context_line":"            except ValueError as e:"},{"line_number":418,"context_line":"                raise exception.PciConfigInvalidSpec(reason\u003dstr(e))"},{"line_number":419,"context_line":""},{"line_number":420,"context_line":"    def sync_pci_device_with_spec_tags(self, dev: ty.Dict[str, ty.Any]):"},{"line_number":421,"context_line":"        spec_tags \u003d [\"managed\", \"live_migratable\"]"}],"source_content_type":"text/x-python","patch_set":2,"id":"af01d056_549d33db","line":418,"updated":"2025-02-24 12:11:15.000000000","message":"nit: I would probably include a bit more information to the message as this is a generic helper now:\n```\nraise exception.PciConfigInvalidSpec(reason\u003df\"Cannot parse tag \u0027{tag}\u0027: \" + str(e))\n```","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"1ef33e44c534e32c8aec0adfe851e198f1c88efc","unresolved":false,"context_lines":[{"line_number":415,"context_line":"                    else \"false\""},{"line_number":416,"context_line":"                )"},{"line_number":417,"context_line":"            except ValueError as e:"},{"line_number":418,"context_line":"                raise exception.PciConfigInvalidSpec(reason\u003dstr(e))"},{"line_number":419,"context_line":""},{"line_number":420,"context_line":"    def sync_pci_device_with_spec_tags(self, dev: ty.Dict[str, ty.Any]):"},{"line_number":421,"context_line":"        spec_tags \u003d [\"managed\", \"live_migratable\"]"}],"source_content_type":"text/x-python","patch_set":2,"id":"6ad8a38d_f33fa89a","line":418,"in_reply_to":"af01d056_549d33db","updated":"2025-02-26 18:49:46.000000000","message":"Done","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"73b90c6fe3384782fbfc5b8cc77adfdf3c75e2dd","unresolved":true,"context_lines":[{"line_number":425,"context_line":"                dev.update({tag: tag_value})"},{"line_number":426,"context_line":"            else:"},{"line_number":427,"context_line":"                if tag in dev:"},{"line_number":428,"context_line":"                    del dev[tag]"}],"source_content_type":"text/x-python","patch_set":2,"id":"058be858_342c62e6","line":428,"updated":"2025-02-24 12:11:15.000000000","message":"this is not effective. Removing the field needs to happen in PCIDevice obj code. See the similar comment the managed series.","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"1ef33e44c534e32c8aec0adfe851e198f1c88efc","unresolved":false,"context_lines":[{"line_number":425,"context_line":"                dev.update({tag: tag_value})"},{"line_number":426,"context_line":"            else:"},{"line_number":427,"context_line":"                if tag in dev:"},{"line_number":428,"context_line":"                    del dev[tag]"}],"source_content_type":"text/x-python","patch_set":2,"id":"094270e6_8b7ebbcf","line":428,"in_reply_to":"058be858_342c62e6","updated":"2025-02-26 18:49:46.000000000","message":"Done","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"}],"nova/tests/unit/objects/test_pci_device.py":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2d8c3b8bc4fc3f2ce82e27d69e8c17499f4dedb3","unresolved":false,"context_lines":[{"line_number":114,"context_line":"    }"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"@ddt.ddt"},{"line_number":118,"context_line":"class _TestPciDeviceObject(object):"},{"line_number":119,"context_line":"    def _create_fake_instance(self):"},{"line_number":120,"context_line":"        self.inst \u003d instance.Instance()"}],"source_content_type":"text/x-python","patch_set":3,"id":"4ee90285_25b353fe","line":117,"updated":"2025-02-27 10:16:57.000000000","message":"👍","commit_id":"7b31a0b5e314bbfb183e8c6042119bd25e006d76"}],"nova/tests/unit/pci/test_manager.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"73b90c6fe3384782fbfc5b8cc77adfdf3c75e2dd","unresolved":true,"context_lines":[{"line_number":261,"context_line":"    @ddt.data({\"tag\": \"managed\"},"},{"line_number":262,"context_line":"              {\"tag\": \"live_migratable\"})"},{"line_number":263,"context_line":"    def test_update_devices_from_hypervisor_resources_with_tag("},{"line_number":264,"context_line":"        self, case, _mock_vf"},{"line_number":265,"context_line":"    ):"},{"line_number":266,"context_line":"        spec \u003d ["},{"line_number":267,"context_line":"            \u0027{\"product_id\":\"8086\", \"vendor_id\":\"10c9\", \u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"06f8b66d_8a7e5c34","line":264,"updated":"2025-02-24 12:11:15.000000000","message":"nit: use data instead of case as case is keyword since py 3.10","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"1ef33e44c534e32c8aec0adfe851e198f1c88efc","unresolved":false,"context_lines":[{"line_number":261,"context_line":"    @ddt.data({\"tag\": \"managed\"},"},{"line_number":262,"context_line":"              {\"tag\": \"live_migratable\"})"},{"line_number":263,"context_line":"    def test_update_devices_from_hypervisor_resources_with_tag("},{"line_number":264,"context_line":"        self, case, _mock_vf"},{"line_number":265,"context_line":"    ):"},{"line_number":266,"context_line":"        spec \u003d ["},{"line_number":267,"context_line":"            \u0027{\"product_id\":\"8086\", \"vendor_id\":\"10c9\", \u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"89efe706_ac794d90","line":264,"in_reply_to":"06f8b66d_8a7e5c34","updated":"2025-02-26 18:49:46.000000000","message":"Done","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"}],"nova/tests/unit/pci/test_whitelist.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"73b90c6fe3384782fbfc5b8cc77adfdf3c75e2dd","unresolved":true,"context_lines":[{"line_number":99,"context_line":"        {\"tag\": \"live_migratable\", \"value\": \"false\", \"expected\": \"false\"},"},{"line_number":100,"context_line":"        {\"tag\": \"live_migratable\", \"value\": \"0\", \"expected\": \"false\"},"},{"line_number":101,"context_line":"    )"},{"line_number":102,"context_line":"    def test_device_tags(self, case):"},{"line_number":103,"context_line":"        wl \u003d ("},{"line_number":104,"context_line":"            \u0027{\"product_id\":\"0001\", \"vendor_id\":\"8086\", \"\u0027 +"},{"line_number":105,"context_line":"            case[\"tag\"] +"}],"source_content_type":"text/x-python","patch_set":2,"id":"1d7f4b41_f608258a","line":102,"updated":"2025-02-24 12:11:15.000000000","message":"ditto use data instead of case","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"1ef33e44c534e32c8aec0adfe851e198f1c88efc","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        {\"tag\": \"live_migratable\", \"value\": \"false\", \"expected\": \"false\"},"},{"line_number":100,"context_line":"        {\"tag\": \"live_migratable\", \"value\": \"0\", \"expected\": \"false\"},"},{"line_number":101,"context_line":"    )"},{"line_number":102,"context_line":"    def test_device_tags(self, case):"},{"line_number":103,"context_line":"        wl \u003d ("},{"line_number":104,"context_line":"            \u0027{\"product_id\":\"0001\", \"vendor_id\":\"8086\", \"\u0027 +"},{"line_number":105,"context_line":"            case[\"tag\"] +"}],"source_content_type":"text/x-python","patch_set":2,"id":"4eaea4e1_fa80fed0","line":102,"in_reply_to":"1d7f4b41_f608258a","updated":"2025-02-26 18:49:46.000000000","message":"Done","commit_id":"82f106d61b10f748f1839fab157115ca404f49a7"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"db38cf04d4a09345a4c15c564ab162cb1b5da514","unresolved":true,"context_lines":[{"line_number":85,"context_line":"        parsed \u003d whitelist.Whitelist([white_list])"},{"line_number":86,"context_line":"        self.assertTrue(parsed.device_assignable(dev_dict))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    @ddt.data("},{"line_number":89,"context_line":"        {\"tag\": \"managed\", \"value\": \"yes\", \"expected\": \"true\"},"},{"line_number":90,"context_line":"        {\"tag\": \"managed\", \"value\": \"true\", \"expected\": \"true\"},"},{"line_number":91,"context_line":"        {\"tag\": \"managed\", \"value\": \"1\", \"expected\": \"true\"},"}],"source_content_type":"text/x-python","patch_set":3,"id":"fe378fb1_a8d58296","line":88,"updated":"2025-02-27 19:08:22.000000000","message":"so some degree this is sor of just testing the behvior of strutiles.strtobool\n\nwhich you should be mocking in unit tests since it an external depency.\n\non the other hand this will catch if they ever break this contract.\n\ni guess this is ok but  this does nto need to be exaustive.\n\nyes,no true,false woudl have been enough.\ni.e. one example of needign a conversion an done of not for true and false","commit_id":"7b31a0b5e314bbfb183e8c6042119bd25e006d76"}]}
