)]}'
{"nova/virt/driver.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"255d31241e4ca15a934ed993b8aa3bc1cdbcf683","unresolved":false,"context_lines":[{"line_number":887,"context_line":"    def unrescue("},{"line_number":888,"context_line":"        self,"},{"line_number":889,"context_line":"        context: \u0027nova_context.RequestContext\u0027,"},{"line_number":890,"context_line":"        instance: \u0027instance_obj.Instance\u0027,"},{"line_number":891,"context_line":"    ):"},{"line_number":892,"context_line":"        \"\"\"Unrescue the specified instance."},{"line_number":893,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_239c155c","line":890,"updated":"2020-07-07 14:53:37.000000000","message":"@gibi: Try removing quotes from this. You\u0027ll see [1]\n\n[1] http://paste.openstack.org/show/795620/","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18e3cb1c63fa26624a4f894c46821b75a8e5a9bb","unresolved":false,"context_lines":[{"line_number":888,"context_line":"        self,"},{"line_number":889,"context_line":"        context: \u0027nova_context.RequestContext\u0027,"},{"line_number":890,"context_line":"        instance: \u0027instance_obj.Instance\u0027,"},{"line_number":891,"context_line":"    ):"},{"line_number":892,"context_line":"        \"\"\"Unrescue the specified instance."},{"line_number":893,"context_line":""},{"line_number":894,"context_line":"        :param context: security context"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_f1fea369","line":891,"updated":"2020-07-02 10:29:57.000000000","message":"Did we notify out of tree driver authors about this change?","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"}],"nova/virt/hyperv/driver.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18e3cb1c63fa26624a4f894c46821b75a8e5a9bb","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from oslo_log import log as logging"},{"line_number":28,"context_line":"import six"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"from nova import context"},{"line_number":31,"context_line":"from nova import exception"},{"line_number":32,"context_line":"from nova.virt import driver"},{"line_number":33,"context_line":"from nova.virt.hyperv import eventhandler"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_d138bf3e","line":30,"updated":"2020-07-02 10:29:57.000000000","message":"Why did you decided to import context in this case while in other case you only import it under ty.TYPE_CHECKING condition? \n\nI don\u0027t really see to much value importing the context module as \u0027context\u0027  because almost every the function below hides the module with a context formal parameter name.","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"d70039051e3288810ac9c51322b3f5305f61195b","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from oslo_log import log as logging"},{"line_number":28,"context_line":"import six"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"from nova import context"},{"line_number":31,"context_line":"from nova import exception"},{"line_number":32,"context_line":"from nova.virt import driver"},{"line_number":33,"context_line":"from nova.virt.hyperv import eventhandler"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_9402b508","line":30,"in_reply_to":"bf51134e_d138bf3e","updated":"2020-07-02 10:33:49.000000000","message":"It\u0027s the delayed interpolation thing again. I can\u0027t actually validate anything from \u0027nova.objects\u0027 so I need to surround it with quotes, and if I\u0027m doing that then the requirement isn\u0027t used at runtime. Good point on the naming though. Will update.","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"}],"nova/virt/libvirt/driver.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"18e3cb1c63fa26624a4f894c46821b75a8e5a9bb","unresolved":false,"context_lines":[{"line_number":3583,"context_line":"    def unrescue("},{"line_number":3584,"context_line":"        self,"},{"line_number":3585,"context_line":"        context: nova_context.RequestContext,"},{"line_number":3586,"context_line":"        instance: \u0027objects.Instance\u0027,"},{"line_number":3587,"context_line":"    ):"},{"line_number":3588,"context_line":"        \"\"\"Reboot the VM which is being rescued back into primary images.\"\"\""},{"line_number":3589,"context_line":"        instance_dir \u003d libvirt_utils.get_instance_path(instance)"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_51a78f50","line":3586,"updated":"2020-07-02 10:29:57.000000000","message":"I guess the type is given as a string even if objects are imported due to the fact that objects dynamically exporting the sub packages. (I tried converting this to typename locally and it does not fail but I guess it is some local quirk for me still)","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"4a8307abf02c63e25d12a60e91f14bb5907d6383","unresolved":false,"context_lines":[{"line_number":3583,"context_line":"    def unrescue("},{"line_number":3584,"context_line":"        self,"},{"line_number":3585,"context_line":"        context: nova_context.RequestContext,"},{"line_number":3586,"context_line":"        instance: \u0027objects.Instance\u0027,"},{"line_number":3587,"context_line":"    ):"},{"line_number":3588,"context_line":"        \"\"\"Reboot the VM which is being rescued back into primary images.\"\"\""},{"line_number":3589,"context_line":"        instance_dir \u003d libvirt_utils.get_instance_path(instance)"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_a3682587","line":3586,"in_reply_to":"bf51134e_2576e0a5","updated":"2020-07-07 14:53:03.000000000","message":"tl;dr: We should always surround any o.vo from \u0027nova.objects\u0027 in quotes, and we need to enclose imports inside a \u0027if ty.TYPE_CHECKING\u0027 conditional anytime we wish to avoid circular references.\n\nThis took me a while to grok but I think I\u0027ve got it now. I think there are couple of intertwined issues here: circular dependencies, the \"dynamic\" loading behavior of the \u0027nova.objects\u0027 module, and differences in how Python the interpreter works and mypy. Consider the following snippet:\n\n  def hello_world(foo: bar.Baz):\n      pass\n\nBecause we have configured \u0027ignore_missing_imports\u0027 to \u0027True\u0027 in \u0027setup.cfg\u0027, mypy will complain if the \u0027bar\u0027 module isn\u0027t defined, but it won\u0027t check anything inside the \u0027bar\u0027 module unless this module is included in the list of scanned modules (currently loaded from \u0027mypy-files.txt\u0027)\n\nBy comparison, Python itself will actually try to load \u0027bar.Baz\u0027 just like it would if you were declaring a variable or subclass of this type. If \u0027bar\u0027 doesn\u0027t exist, you\u0027ll see the same undefined reference/import complaint that mypy issued. However, if \u0027Baz\u0027 doesn\u0027t exist in \u0027bar\u0027, it\u0027ll complain that the \u0027bar\u0027 module doesn\u0027t have the \u0027Baz\u0027 attribute.\n\nThat means something like this will fail:\n\n  if ty.TYPE_CHECKING:\n      import bar\n\n  def hello_world(foo: bar.Baz):\n      pass\n\nThis fails as everything inside the TYPE_CHECKING conditional only executes in the mypy context, so it\u0027s effectively \u0027if False\u0027 during runtime. However, you sometimes need to use the \u0027TYPE_CHECKING\u0027 conditional to avoid circular references. If we need to use this check to avoid this circular references then the correct response is to delay interpolation using quotes.\n\n  if ty.TYPE_CHECKING:\n      import bar\n\n  def hello_world(foo: \u0027bar.Baz\u0027):\n      pass\n\nWhen this is used, the type check is ignored by Python (it\u0027s just a string) but parsed by mypy, with the same caveats that \u0027bar\u0027 must be defined and the contents of \u0027bar\u0027 will only be checked if it\u0027s in the list of validated modules.\n\nNow, to bring this back to \u0027nova.objects\u0027. The quotes aren\u0027t to delay interpolation for mypy - they\u0027re to *prevent* it for Python. Because it attempts to evaluate the code, we *must* ensure \u0027nova.objects.register_all()\u0027 has been called before the module with the type hints is imported. If you don\u0027t, Python will fail with \"module \u0027nova.objects\u0027 has no attribute \u0027Foo\u0027\" as soon as it tries to parse the module.  You can prove this from the REPL.\n\n  (py36) $ python\n  \u003e\u003e\u003e from nova import objects\n  \u003e\u003e\u003e def test(instance: objects.Instance):\n  ...     pass\n  ...\n  Traceback (most recent call last):\n    File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  AttributeError: module \u0027nova.objects\u0027 has no attribute \u0027Instance\u0027\n  \u003e\u003e\u003e objects.register_all()\n  \u003e\u003e\u003e def test(instance: objects.Instance):\n  ...     pass\n  ...\n  \u003e\u003e\u003e\n\nWe can\u0027t guarantee that to be case so always surrounding anything from \u0027nova.objects\u0027 in quotes seems to be the correct thing to do. In addition, we will need to use quotes anytime we need to handle single quotes.","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"d70039051e3288810ac9c51322b3f5305f61195b","unresolved":false,"context_lines":[{"line_number":3583,"context_line":"    def unrescue("},{"line_number":3584,"context_line":"        self,"},{"line_number":3585,"context_line":"        context: nova_context.RequestContext,"},{"line_number":3586,"context_line":"        instance: \u0027objects.Instance\u0027,"},{"line_number":3587,"context_line":"    ):"},{"line_number":3588,"context_line":"        \"\"\"Reboot the VM which is being rescued back into primary images.\"\"\""},{"line_number":3589,"context_line":"        instance_dir \u003d libvirt_utils.get_instance_path(instance)"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_f407b117","line":3586,"in_reply_to":"bf51134e_51a78f50","updated":"2020-07-02 10:33:49.000000000","message":"It doesn\u0027t fail if you do \u0027tox -e mypy\u0027? Hmm, that\u0027s odd","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"371da5d38da6ad459849c3979db2ae1ff9e996d3","unresolved":false,"context_lines":[{"line_number":3583,"context_line":"    def unrescue("},{"line_number":3584,"context_line":"        self,"},{"line_number":3585,"context_line":"        context: nova_context.RequestContext,"},{"line_number":3586,"context_line":"        instance: \u0027objects.Instance\u0027,"},{"line_number":3587,"context_line":"    ):"},{"line_number":3588,"context_line":"        \"\"\"Reboot the VM which is being rescued back into primary images.\"\"\""},{"line_number":3589,"context_line":"        instance_dir \u003d libvirt_utils.get_instance_path(instance)"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_d9df080a","line":3586,"in_reply_to":"bf51134e_a3682587","updated":"2020-07-07 16:17:09.000000000","message":"Thanks for the explanation. I think I got it now. But I cannot promise I won\u0027t ask similar questions in the future. (There is still an itch in the back of my mind that something is missing)","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"5cb87b716e1c46cfce00ee2eccde2e632c664808","unresolved":false,"context_lines":[{"line_number":3583,"context_line":"    def unrescue("},{"line_number":3584,"context_line":"        self,"},{"line_number":3585,"context_line":"        context: nova_context.RequestContext,"},{"line_number":3586,"context_line":"        instance: \u0027objects.Instance\u0027,"},{"line_number":3587,"context_line":"    ):"},{"line_number":3588,"context_line":"        \"\"\"Reboot the VM which is being rescued back into primary images.\"\"\""},{"line_number":3589,"context_line":"        instance_dir \u003d libvirt_utils.get_instance_path(instance)"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf51134e_2576e0a5","line":3586,"in_reply_to":"bf51134e_f407b117","updated":"2020-07-07 10:32:07.000000000","message":"Yepp. It is also green on the gate too https://review.opendev.org/#/c/739663","commit_id":"9c6bd12991cbbb78aa44d601c1dbe8968115c178"}]}
