)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"62800efdf3c129d91fd6b764728a1763a1faf83b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"c756a6d7_40e98287","updated":"2026-03-18 17:24:58.000000000","message":"Looks good to me. The -1 is the for forward reference causing the CI failures","commit_id":"cde702ef9672a4b008014ea0d0d89ac979682380"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"87ed8c4a767437a9beae440e894f71fdb1cef78d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"46d67999_720a3248","updated":"2026-04-15 14:16:15.000000000","message":"To be clear, I\u0027m also waiting on @kajinamit@oss.nttdata.com to come back to this before I sign off on it. I\u0027m +2 either way, though I still have a preference for using `isinstance`","commit_id":"6d9b43f4635a61635d556e6002c6cd9f681a86fe"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9a85566c1ddea5f76a1d071ef0796a4d75be1e1e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"4b5f9a60_46aa21f3","updated":"2026-04-29 15:33:57.000000000","message":"I\u0027ll let @kajinamit@oss.nttdata.com come back to this, but this looks good to me now.","commit_id":"be9557ee8d19bf1b03fd6a59a9d14d175ddf960b"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a851c0adb7259092020cfe68aa41f781b4ce0c8a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"1af3ddde_9ed46a1f","updated":"2026-04-15 21:00:34.000000000","message":"recheck failure has nothing to do with this change (and isn\u0027t reflected across all of the other unit jobs)","commit_id":"be9557ee8d19bf1b03fd6a59a9d14d175ddf960b"}],"oslo_utils/imageutils/format_inspector.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"2f331f8f12ad7ccd968bc3dc31b6eada8315f796","unresolved":true,"context_lines":[{"line_number":480,"context_line":"                    exc,"},{"line_number":481,"context_line":"                )"},{"line_number":482,"context_line":"            except SafetyCheckFailed as exc:"},{"line_number":483,"context_line":"                # This can happen if"},{"line_number":484,"context_line":"                for name, failure in exc.failures.items():"},{"line_number":485,"context_line":"                    failures[\u0027inner_\u0027 + name] \u003d failure"},{"line_number":486,"context_line":"                    LOG.warning("}],"source_content_type":"text/x-python","patch_set":1,"id":"0df42547_e41d85d9","line":483,"updated":"2026-02-26 20:45:32.000000000","message":"Half-finished thought?","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f7f3eea4d3bb3c716f2c9cc92cc7a9998641b0d","unresolved":false,"context_lines":[{"line_number":480,"context_line":"                    exc,"},{"line_number":481,"context_line":"                )"},{"line_number":482,"context_line":"            except SafetyCheckFailed as exc:"},{"line_number":483,"context_line":"                # This can happen if"},{"line_number":484,"context_line":"                for name, failure in exc.failures.items():"},{"line_number":485,"context_line":"                    failures[\u0027inner_\u0027 + name] \u003d failure"},{"line_number":486,"context_line":"                    LOG.warning("}],"source_content_type":"text/x-python","patch_set":1,"id":"5c413df2_b4842459","line":483,"in_reply_to":"02a61ddb_6df7a87b","updated":"2026-03-18 14:48:41.000000000","message":"Done","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2df4186b04383a91b1336855f3cdcc8cc100fe14","unresolved":true,"context_lines":[{"line_number":480,"context_line":"                    exc,"},{"line_number":481,"context_line":"                )"},{"line_number":482,"context_line":"            except SafetyCheckFailed as exc:"},{"line_number":483,"context_line":"                # This can happen if"},{"line_number":484,"context_line":"                for name, failure in exc.failures.items():"},{"line_number":485,"context_line":"                    failures[\u0027inner_\u0027 + name] \u003d failure"},{"line_number":486,"context_line":"                    LOG.warning("}],"source_content_type":"text/x-python","patch_set":1,"id":"02a61ddb_6df7a87b","line":483,"in_reply_to":"0df42547_e41d85d9","updated":"2026-02-26 20:50:12.000000000","message":"...or poetic philosophical exercise for the reader?\n\n(yes obviously)","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"2f331f8f12ad7ccd968bc3dc31b6eada8315f796","unresolved":true,"context_lines":[{"line_number":503,"context_line":"    inspector."},{"line_number":504,"context_line":"    \"\"\""},{"line_number":505,"context_line":""},{"line_number":506,"context_line":"    def __init__(self, *args: Any, **kwargs: Any) -\u003e None:"},{"line_number":507,"context_line":"        self._inner_format: FileInspector | None \u003d None"},{"line_number":508,"context_line":"        super().__init__(*args, **kwargs)"},{"line_number":509,"context_line":"        self.add_safety_check("},{"line_number":510,"context_line":"            SafetyCheck(\u0027inner_safety\u0027, self.check_inner_safety)"},{"line_number":511,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":1,"id":"e925bccf_b9ef3ac2","line":508,"range":{"start_line":506,"start_character":0,"end_line":508,"end_character":41},"updated":"2026-02-26 20:45:32.000000000","message":"We know the parameters we accept here.\n\n```suggestion\n    def __init__(self, tracing: bool \u003d False) -\u003e None:\n        self._inner_format: FileInspector | None \u003d None\n        super().__init__(tracing\u003dtracing)\n```","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"23a8857dbb7d648bdbc945702d615751d4ac51c6","unresolved":true,"context_lines":[{"line_number":503,"context_line":"    inspector."},{"line_number":504,"context_line":"    \"\"\""},{"line_number":505,"context_line":""},{"line_number":506,"context_line":"    def __init__(self, *args: Any, **kwargs: Any) -\u003e None:"},{"line_number":507,"context_line":"        self._inner_format: FileInspector | None \u003d None"},{"line_number":508,"context_line":"        super().__init__(*args, **kwargs)"},{"line_number":509,"context_line":"        self.add_safety_check("},{"line_number":510,"context_line":"            SafetyCheck(\u0027inner_safety\u0027, self.check_inner_safety)"},{"line_number":511,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":1,"id":"3c9c31bb_a2fea19d","line":508,"range":{"start_line":506,"start_character":0,"end_line":508,"end_character":41},"in_reply_to":"22df6230_287d8d9a","updated":"2026-03-10 13:31:12.000000000","message":"Understood, but by doing this we lose the ability to determine whether we\u0027re calling the method correctly. For the sake of of an additional hunk in the diff of the following change, I think we should be specific here.","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f7f3eea4d3bb3c716f2c9cc92cc7a9998641b0d","unresolved":false,"context_lines":[{"line_number":503,"context_line":"    inspector."},{"line_number":504,"context_line":"    \"\"\""},{"line_number":505,"context_line":""},{"line_number":506,"context_line":"    def __init__(self, *args: Any, **kwargs: Any) -\u003e None:"},{"line_number":507,"context_line":"        self._inner_format: FileInspector | None \u003d None"},{"line_number":508,"context_line":"        super().__init__(*args, **kwargs)"},{"line_number":509,"context_line":"        self.add_safety_check("},{"line_number":510,"context_line":"            SafetyCheck(\u0027inner_safety\u0027, self.check_inner_safety)"},{"line_number":511,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":1,"id":"6304a231_d9008b7c","line":508,"range":{"start_line":506,"start_character":0,"end_line":508,"end_character":41},"in_reply_to":"3c9c31bb_a2fea19d","updated":"2026-03-18 14:48:41.000000000","message":"Done","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2df4186b04383a91b1336855f3cdcc8cc100fe14","unresolved":true,"context_lines":[{"line_number":503,"context_line":"    inspector."},{"line_number":504,"context_line":"    \"\"\""},{"line_number":505,"context_line":""},{"line_number":506,"context_line":"    def __init__(self, *args: Any, **kwargs: Any) -\u003e None:"},{"line_number":507,"context_line":"        self._inner_format: FileInspector | None \u003d None"},{"line_number":508,"context_line":"        super().__init__(*args, **kwargs)"},{"line_number":509,"context_line":"        self.add_safety_check("},{"line_number":510,"context_line":"            SafetyCheck(\u0027inner_safety\u0027, self.check_inner_safety)"},{"line_number":511,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":1,"id":"22df6230_287d8d9a","line":508,"range":{"start_line":506,"start_character":0,"end_line":508,"end_character":41},"in_reply_to":"e925bccf_b9ef3ac2","updated":"2026-02-26 20:50:12.000000000","message":"Ack, but I was trying to avoid having to modify this every time the base changes (like in the next patch) just to be able to initialize a new variable.","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"e4820bd2c16417529db64ab256d1d147de7dd520","unresolved":true,"context_lines":[{"line_number":511,"context_line":"        )"},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"00f9c6db_6f141c8e","line":514,"range":{"start_line":514,"start_character":8,"end_line":514,"end_character":20},"updated":"2026-03-10 15:36:51.000000000","message":"I\u0027m wondering if we can add this to the base FileInspector and let it return None always, to have consistent interfaces ?\nIt may allow us to remove isinstance check https://review.opendev.org/c/openstack/oslo.utils/+/978095/1/oslo_utils/imageutils/cli.py#110 and we get the same benefit in real usage in services.","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"1507339a573622ba0a59b2ea8be2d3bc5858c838","unresolved":true,"context_lines":[{"line_number":511,"context_line":"        )"},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"4c50e139_1e04e099","line":514,"range":{"start_line":514,"start_character":8,"end_line":514,"end_character":20},"in_reply_to":"00f9c6db_6f141c8e","updated":"2026-03-10 15:44:21.000000000","message":"Well, I wanted to be able to tell the difference between something that expects/can-have an inner format from one that can\u0027t. If we haven\u0027t processed enough to know what the inner format is, I\u0027d like to know that, distinct from \"can this format even have such a thing?\"","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f24f9ce18737c0ca0f1916185f1c618ba3b9a93e","unresolved":true,"context_lines":[{"line_number":511,"context_line":"        )"},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"48874d17_e0fd297f","line":514,"range":{"start_line":514,"start_character":8,"end_line":514,"end_character":20},"in_reply_to":"0c2e0055_a0e1647c","updated":"2026-03-19 14:30:26.000000000","message":"Ack, I also much prefer what we had before as well. I\u0027ll look for @kajinamit@oss.nttdata.com to opine now that he can see this and decide.","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a22e31ce1e1dde03879fad9d349ccc896e379187","unresolved":true,"context_lines":[{"line_number":511,"context_line":"        )"},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9ec0fd31_f1b97e64","line":514,"range":{"start_line":514,"start_character":8,"end_line":514,"end_character":20},"in_reply_to":"48874d17_e0fd297f","updated":"2026-04-10 17:54:41.000000000","message":"Still haven\u0027t made a reversion here. If I don\u0027t hear from @kajinamit@oss.nttdata.com soon I\u0027ll revert back to the `isinstance()` variant.","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"65f2cd1408722cbd2c20350dc0376d938b2113ac","unresolved":true,"context_lines":[{"line_number":511,"context_line":"        )"},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"e377437e_b9537949","line":514,"range":{"start_line":514,"start_character":8,"end_line":514,"end_character":20},"in_reply_to":"4c50e139_1e04e099","updated":"2026-03-17 16:09:11.000000000","message":"OK. Maybe we can raise NotImplementedError rather than returning None ?","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9a85566c1ddea5f76a1d071ef0796a4d75be1e1e","unresolved":false,"context_lines":[{"line_number":511,"context_line":"        )"},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ed0b73b0_c6e17569","line":514,"range":{"start_line":514,"start_character":8,"end_line":514,"end_character":20},"in_reply_to":"9ec0fd31_f1b97e64","updated":"2026-04-29 15:33:57.000000000","message":"Looks like this has been reverted now.","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"eee18f65303bb9133852822b1d6b0d2cd467a355","unresolved":true,"context_lines":[{"line_number":511,"context_line":"        )"},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"0c2e0055_a0e1647c","line":514,"range":{"start_line":514,"start_character":8,"end_line":514,"end_character":20},"in_reply_to":"e189bd50_2db76d1b","updated":"2026-03-19 10:52:43.000000000","message":"\u003e To me, a thing that contains another thing is a specialization of the base class, and it has more things that we can do with it and other inherent behaviors. That is what a subclass is for, IMHO.\n\nI\u0027m inclined to agree with this and had no issues with the `isinstance` check we had previously (in fact I prefer it to the `try-except` pattern we have now). I can however live with the current approach if @kajinamit@oss.nttdata.com strongly prefers that 🤷 I\u0027ll leave this to you two to figure out...","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5dc3e69d1994ba8bb536397ceae5e58cf21398aa","unresolved":true,"context_lines":[{"line_number":511,"context_line":"        )"},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"e189bd50_2db76d1b","line":514,"range":{"start_line":514,"start_character":8,"end_line":514,"end_character":20},"in_reply_to":"e377437e_b9537949","updated":"2026-03-18 13:48:34.000000000","message":"(just reiterating what I said in IRC for posterity)\n\nI\u0027m not sure if you\u0027re suggesting raising NotImplementedError here instead of returning None, or combining this with the main class and raising NotImplementedError there for thing that are not containers of things. The former is not good, IMHO, because we need to know \"this thing does contain another thing but we haven\u0027t identified it yet.\" I suppose the latter would be doable there, but I don\u0027t understand why that\u0027s better.\n\nTo me, a thing that contains another thing is a specialization of the base class, and it has more things that we can do with it and other inherent behaviors. That is what a subclass is for, IMHO.\n\nThe contains-a-thing variant needs to have an implied safety check added for the inner format, and it needs another standardized interface to get to the inner format.\n\nIs the major concern that I use isinstance() to distinguish these? I guess maybe that\u0027s a religious argument, but adding every interface that any subclass can have to the top-level class, requiring everything that uses it to `try..except NotImplementedError` is much less desirable. But, I have no sway here so if that\u0027s the way things in oslo should work (or the cores think they should work) then that\u0027s fine. I\u0027d just like to know the reasoning to make sure we\u0027re not missing something. If it\u0027s just religious, then like all religions, I have no arguments to make :)","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"2f331f8f12ad7ccd968bc3dc31b6eada8315f796","unresolved":true,"context_lines":[{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"    def check_inner_safety(self) -\u003e None:"},{"line_number":519,"context_line":"        \"\"\"Runs safety_check() on the inner format.\"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"2e260dee_038a08d0","line":516,"updated":"2026-02-26 20:45:32.000000000","message":"I don\u0027t see anything setting `_inner_format` this outside of tests?","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2df4186b04383a91b1336855f3cdcc8cc100fe14","unresolved":true,"context_lines":[{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"    def check_inner_safety(self) -\u003e None:"},{"line_number":519,"context_line":"        \"\"\"Runs safety_check() on the inner format.\"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"5792e708_164f4816","line":516,"in_reply_to":"2e260dee_038a08d0","updated":"2026-02-26 20:50:12.000000000","message":"This is setup for the patch at the end. A generic class that does things like this, but this one itself doesn\u0027t do anything other than extend the base class\u0027 interface.","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"23a8857dbb7d648bdbc945702d615751d4ac51c6","unresolved":false,"context_lines":[{"line_number":513,"context_line":"    @property"},{"line_number":514,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":515,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":516,"context_line":"        return self._inner_format"},{"line_number":517,"context_line":""},{"line_number":518,"context_line":"    def check_inner_safety(self) -\u003e None:"},{"line_number":519,"context_line":"        \"\"\"Runs safety_check() on the inner format.\"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"682a307f_0b85aa8b","line":516,"in_reply_to":"5792e708_164f4816","updated":"2026-03-10 13:31:12.000000000","message":"We discussed this on IRC but I\u0027d missed [this line](https://review.opendev.org/c/openstack/oslo.utils/+/978097/1/oslo_utils/imageutils/format_inspector.py#1630). All good.","commit_id":"52168450459c344de5b8994f1ee4aaa203ab6104"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"62800efdf3c129d91fd6b764728a1763a1faf83b","unresolved":true,"context_lines":[{"line_number":496,"context_line":"            raise SafetyCheckFailed(failures)"},{"line_number":497,"context_line":""},{"line_number":498,"context_line":"    @property"},{"line_number":499,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":500,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":501,"context_line":"        raise NotImplementedError(\u0027Not a container format\u0027)"},{"line_number":502,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"5157ccbc_9246d89d","line":499,"updated":"2026-03-18 17:24:58.000000000","message":"This is a forward reference. Either quote it:\n\n```suggestion\n    def inner_format(self) -\u003e \u0027FileInspector | None\u0027:\n```\n\nor add `from __future__ import annotations`. Note that if you do the latter, ruff will insist you remove the quotes from other forward imports higher up this file.","commit_id":"cde702ef9672a4b008014ea0d0d89ac979682380"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"091c2736c780b008d25247b84895208ad46de217","unresolved":true,"context_lines":[{"line_number":496,"context_line":"            raise SafetyCheckFailed(failures)"},{"line_number":497,"context_line":""},{"line_number":498,"context_line":"    @property"},{"line_number":499,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":500,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":501,"context_line":"        raise NotImplementedError(\u0027Not a container format\u0027)"},{"line_number":502,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"ace89095_7dbd4950","line":499,"in_reply_to":"5157ccbc_9246d89d","updated":"2026-03-18 18:54:44.000000000","message":"Whoops, I had it quoted and then failed to commit that before moving something else. What\u0027s the preference?","commit_id":"cde702ef9672a4b008014ea0d0d89ac979682380"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0c7827ca519d7e9eb9efaae16841a8dda0398e8d","unresolved":false,"context_lines":[{"line_number":496,"context_line":"            raise SafetyCheckFailed(failures)"},{"line_number":497,"context_line":""},{"line_number":498,"context_line":"    @property"},{"line_number":499,"context_line":"    def inner_format(self) -\u003e FileInspector | None:"},{"line_number":500,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":501,"context_line":"        raise NotImplementedError(\u0027Not a container format\u0027)"},{"line_number":502,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"2d778ed0_cb9ffb54","line":499,"in_reply_to":"ace89095_7dbd4950","updated":"2026-03-18 20:36:16.000000000","message":"Done","commit_id":"cde702ef9672a4b008014ea0d0d89ac979682380"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0c7827ca519d7e9eb9efaae16841a8dda0398e8d","unresolved":true,"context_lines":[{"line_number":498,"context_line":"    @property"},{"line_number":499,"context_line":"    def inner_format(self) -\u003e \u0027FileInspector | None\u0027:"},{"line_number":500,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":501,"context_line":"        raise NotImplementedError(\u0027Not a container format\u0027)"},{"line_number":502,"context_line":""},{"line_number":503,"context_line":""},{"line_number":504,"context_line":"class ContainerFileInspector(FileInspector):"}],"source_content_type":"text/x-python","patch_set":3,"id":"fcf5cac0_9a8bae7a","line":501,"updated":"2026-03-18 20:36:16.000000000","message":"@kajinamit@oss.nttdata.com Is this what you\u0027re hoping for? Same interface at the top, but I still get to have an intermediate class to add the behavior I want?","commit_id":"6a563cfd25df77fea1627e12645d028af66a8d57"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9a85566c1ddea5f76a1d071ef0796a4d75be1e1e","unresolved":false,"context_lines":[{"line_number":498,"context_line":"    @property"},{"line_number":499,"context_line":"    def inner_format(self) -\u003e \u0027FileInspector | None\u0027:"},{"line_number":500,"context_line":"        \"\"\"Returns the inner format of the container.\"\"\""},{"line_number":501,"context_line":"        raise NotImplementedError(\u0027Not a container format\u0027)"},{"line_number":502,"context_line":""},{"line_number":503,"context_line":""},{"line_number":504,"context_line":"class ContainerFileInspector(FileInspector):"}],"source_content_type":"text/x-python","patch_set":3,"id":"1728572f_04ac1692","line":501,"in_reply_to":"fcf5cac0_9a8bae7a","updated":"2026-04-29 15:33:57.000000000","message":"Done","commit_id":"6a563cfd25df77fea1627e12645d028af66a8d57"}]}
