)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"b68597b17d9bd43fdef05741fe63571572ced509","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"f013fea0_98388d8f","updated":"2024-05-01 18:17:18.000000000","message":"Holding off until we understand why we apply the validator for allocation_pools at all.","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"4542a89ca6ef78692c682cb61aacb17bfe30ce7d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"22b0452d_245445ba","updated":"2024-05-01 18:24:13.000000000","message":"I am removing Workflow-1 because I think the patch is still beneficial, regardless whether we remove or modify the converter for allocation_pools (I think a bug should be reported for that.)","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"47ab91700c080b4ea3ddfaf6818ce1bee55a72ac","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"0ef63b20_fcba2585","updated":"2024-05-01 19:31:32.000000000","message":"Let me take some time to understand it better. :)","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"5dff2caf8f316c7b55b1cb4c66368e9228d574f3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"d5dc6dc0_4e7a9d46","updated":"2024-05-01 01:49:14.000000000","message":"recheck","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"f03d19319f11f736a4ea47360209e4eb3d87c27f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"7fe14e41_6212af33","updated":"2024-05-03 23:06:57.000000000","message":"I\u0027m switching the converter for the field here: https://review.opendev.org/c/openstack/neutron-lib/+/918149/1","commit_id":"d1020da3eacff914259b3411f30ecb564d9f047c"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"c9d656311fbc1afa20a22c989fb203ddd00ec2ae","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"e38fd9fc_2dd903b0","updated":"2024-05-14 16:41:29.000000000","message":"recheck unrelated failure in FIP configuration on backend","commit_id":"d1020da3eacff914259b3411f30ecb564d9f047c"}],"neutron_lib/tests/unit/api/test_conversions.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"17c4c3be952627025058458082195e5359a4ec6b","unresolved":true,"context_lines":[{"line_number":210,"context_line":"        self.assertEqual(\u00272001:db8:0:1:1:1:1:1/128\u0027, result)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def test_convert_subnetpools(self):"},{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"222c5c36_0eb49316","line":213,"updated":"2024-05-01 16:23:44.000000000","message":"Can you just point out where we were calling the converter with a list/dictionary? I couldn\u0027t find it with a quick search.","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"3797006843bfd63a268e064a4f17708a7624d662","unresolved":true,"context_lines":[{"line_number":210,"context_line":"        self.assertEqual(\u00272001:db8:0:1:1:1:1:1/128\u0027, result)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def test_convert_subnetpools(self):"},{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"5aa14b6c_5fab0fe8","line":213,"in_reply_to":"222c5c36_0eb49316","updated":"2024-05-01 18:14:31.000000000","message":"```\n{0} neutron.tests.unit.db.test_db_base_plugin_v2.TestSubnetPoolsV2.test_allocate_specific_subnet_prefix_allocation_pools [0.228729s] ... FAILED\n\nCaptured traceback:\n~~~~~~~~~~~~~~~~~~~\n    Traceback (most recent call last):\n\n      File \"/home/zuul/src/opendev.org/openstack/neutron/neutron/tests/base.py\", line 178, in func\n    return f(self, *args, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^^^^\n\n      File \"/home/zuul/src/opendev.org/openstack/neutron/neutron/tests/unit/db/test_db_base_plugin_v2.py\", line 6641, in test_allocate_specific_subnet_prefix_allocation_pools\n    res[\u0027subnet\u0027][\u0027allocation_pools\u0027][0][\u0027start\u0027])\n    ~~~^^^^^^^^^^\n\n    KeyError: \u0027subnet\u0027\n\n\nCaptured pythonlogging:\n~~~~~~~~~~~~~~~~~~~~~~~\n       ERROR [neutron.pecan_wsgi.hooks.translation] POST failed.\nTraceback (most recent call last):\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/pecan/core.py\", line 681, in __call__\n    controller, args, kwargs \u003d self.find_controller(state)\n                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/pecan/core.py\", line 859, in find_controller\n    controller, args, kw \u003d super(Pecan, self).find_controller(_state)\n                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/pecan/core.py\", line 549, in find_controller\n    self.handle_hooks(self.determine_hooks(controller), \u0027before\u0027, state)\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/pecan/core.py\", line 866, in handle_hooks\n    return super(Pecan, self).handle_hooks(hooks, *args, **kw)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/pecan/core.py\", line 331, in handle_hooks\n    result \u003d getattr(hook, hook_type)(*args)\n             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/zuul/src/opendev.org/openstack/neutron/neutron/pecan_wsgi/hooks/body_validation.py\", line 71, in before\n    raise e\n  File \"/home/zuul/src/opendev.org/openstack/neutron/neutron/pecan_wsgi/hooks/body_validation.py\", line 61, in before\n    data \u003d v2_base.Controller.prepare_request_body(\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/zuul/src/opendev.org/openstack/neutron/neutron/api/v2/base.py\", line 781, in prepare_request_body\n    attr_ops.convert_values(res_dict, exc_cls\u003dwebob.exc.HTTPBadRequest)\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/neutron_lib/api/attributes.py\", line 226, in convert_values\n    res_dict[attr] \u003d attr_vals[\u0027convert_to\u0027](res_dict[attr])\n                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/neutron_lib/api/converters.py\", line 196, in convert_ip_to_canonical_format\n    ip \u003d netaddr.IPAddress(value)\n         ^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/netaddr/ip/__init__.py\", line 333, in __init__\n    self._value \u003d module.str_to_int(addr, flags)\n                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/home/zuul/src/opendev.org/openstack/neutron/.tox/py311/lib/python3.11/site-packages/netaddr/strategy/ipv4.py\", line 121, in str_to_int\n    elif pton_mode and any(len(p) \u003e 1 and p.startswith(\u00270\u0027) for p in addr.split(\u0027.\u0027)):\n                                                                     ^^^^^^^^^^\nAttributeError: \u0027list\u0027 object has no attribute \u0027split\u0027\n```\n\nfrom the job that pulls netaddr 1.2.1 through upper-constraints: https://zuul.opendev.org/t/openstack/build/9b5f7274b73642daaa57d83552c351c7\n\nThe flow is subnetpools that support both a string and a \"list of {start: ... , end: ...}\"","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"48c6f1fbc90b3d0fb3efdb87c5dde5dfcc083c2b","unresolved":true,"context_lines":[{"line_number":210,"context_line":"        self.assertEqual(\u00272001:db8:0:1:1:1:1:1/128\u0027, result)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def test_convert_subnetpools(self):"},{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7f28a784_8c1d31ba","line":213,"in_reply_to":"4043fd7d_ae3be78c","updated":"2024-05-03 22:37:10.000000000","message":"Here is the code that converts / validates request attributes:\n\n```\n    def convert_values(\n            self, res_dict,\n            exc_cls\u003dlambda m: exceptions.InvalidInput(error_message\u003dm)):\n        \"\"\"Convert and validate attribute values for a request.\n\n        :param res_dict: The resource attributes from the request.\n        :param exc_cls: Exception to be raised on error that must take\n            a single error message as it\u0027s only constructor arg.\n        :raises: exc_cls If any errors occur converting/validating the\n            res_dict.\n        \"\"\"\n        for attr, attr_vals in self.attributes.items():\n            if (attr not in res_dict or\n                    res_dict[attr] is constants.ATTR_NOT_SPECIFIED):\n                continue\n            # Convert values if necessary\n            if \u0027convert_to\u0027 in attr_vals:\n                res_dict[attr] \u003d attr_vals[\u0027convert_to\u0027](res_dict[attr])\n            # Check that configured values are correct\n            if \u0027validate\u0027 not in attr_vals:\n                continue\n            for rule in attr_vals[\u0027validate\u0027]:\n                validator \u003d validators.get_validator(rule)\n                res \u003d validator(res_dict[attr],\n                                attr_vals[\u0027validate\u0027][rule])\n                if res:\n                    msg_dict \u003d {\u0027attr\u0027: attr, \u0027reason\u0027: res}\n                    msg \u003d _(\"Invalid input for %(attr)s. \"\n                            \"Reason: %(reason)s.\") % msg_dict\n                    raise exc_cls(msg)\n\n```\n\nNote that it first calls `convert_to` on the attribute (in our case - on `allocation_pools` - which is a list of dicts), then, if present, it calls `validate` on the same.\n\nI don\u0027t think using `converters.convert_ip_to_canonical_format` as `convert_to` for the field is correct in the first place. I will replace it. But also - I think this converter should be patched as per this patch here, because it doesn\u0027t conform to its own promise (see the docstring.)","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"ad466d2f404edbdf5dc9a306dcbd438724ab032c","unresolved":true,"context_lines":[{"line_number":210,"context_line":"        self.assertEqual(\u00272001:db8:0:1:1:1:1:1/128\u0027, result)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def test_convert_subnetpools(self):"},{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"86c85b9b_92e31ff0","line":213,"in_reply_to":"5aa14b6c_5fab0fe8","updated":"2024-05-01 18:16:58.000000000","message":"But your question makes me think if allocation_pools REALLY support a string... As per api-ref, it\u0027s `Allocation pools with start and end IP addresses for this subnet. If allocation_pools are not specified, OpenStack Networking automatically allocates pools for covering all IP addresses in the CIDR, excluding the address reserved for the subnet gateway by default.` No string option. Should this validator even apply?","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"6c28f74de6d237cc7ae671dec2895979e5b1e312","unresolved":true,"context_lines":[{"line_number":210,"context_line":"        self.assertEqual(\u00272001:db8:0:1:1:1:1:1/128\u0027, result)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def test_convert_subnetpools(self):"},{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"8c4e0c41_6f9f6908","line":213,"in_reply_to":"86c85b9b_92e31ff0","updated":"2024-05-01 18:21:51.000000000","message":"Looks like https://review.opendev.org/c/openstack/neutron-lib/+/493280 introduced this converter for the field, but I don\u0027t think it ever worked. (Of course, the patch didn\u0027t have test cases added, so no one noticed.)\n\nWas the goal to canonicalize ip addresses that are set as values for pool dict keys? (start and end)","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"368bc4289257834652e8886fe841292993699056","unresolved":true,"context_lines":[{"line_number":210,"context_line":"        self.assertEqual(\u00272001:db8:0:1:1:1:1:1/128\u0027, result)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def test_convert_subnetpools(self):"},{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"a6d2083e_6016b94a","line":213,"in_reply_to":"8c4e0c41_6f9f6908","updated":"2024-05-01 19:22:22.000000000","message":"Ok, from the failure it was just the string value of the \u0027start\u0027 of the allocation pool that was supposed to be passed, not the dictionary. That should call the validator called validate_ip_pools() which knows about the \u0027start\u0027 and \u0027end\u0027 keys.\n\n_validate_dict_item() is the thing doing the work here - using the converter (if necessary), then calling the validator.\n\nSo I don\u0027t think this will ever be called with the pool, just the start/end values, but that isn\u0027t happening in test_allocate_specific_subnet_prefix_allocation_pools() ? I am confused.","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"9f6ab23154e71104dbd5f8508e4096835db5dc2f","unresolved":true,"context_lines":[{"line_number":210,"context_line":"        self.assertEqual(\u00272001:db8:0:1:1:1:1:1/128\u0027, result)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def test_convert_subnetpools(self):"},{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"aacceb6d_bd4689d8","line":213,"in_reply_to":"a6d2083e_6016b94a","updated":"2024-05-01 19:29:17.000000000","message":"Here is the definition of the field from api:\n\n```\n        \u0027allocation_pools\u0027: {\n            \u0027allow_post\u0027: True, \u0027allow_put\u0027: True,\n            \u0027default\u0027: constants.ATTR_NOT_SPECIFIED,\n            \u0027convert_to\u0027: converters.convert_ip_to_canonical_format,\n            \u0027validate\u0027: {\u0027type:ip_pools\u0027: None},\n            \u0027is_visible\u0027: True},\n\n```\n\nNote that both convert_to and validate are set. `validate_ip_pools` is triggered by `validate`. What I\u0027m dealing with is `convert_to` part of the definition.\n\nI think the end game for this field should be to have a `convert_to` that would canonicalize the `start` and `end` values for each item in the list. Instead, as of now, it attempts to \"convert\" the list as if it\u0027s an address - obviously failing, silently (with older netaddr) or with the exception I posted (with newer version).\n\nI may later post a patch to change the `convert_to` handler for the field. That said, I think this patch is also needed regardless of `allocation_pools`, because the promise of the converter (as per its docstring, see below) is that it will return the input argument back if it\u0027s not a valid IP address.\n\n```\n    \"\"\"IP Address is validated and then converted to canonical format.\n\n    :param value: The IP Address which needs to be checked.\n    :returns: - None if \u0027value\u0027 is None,\n              - \u0027value\u0027 if \u0027value\u0027 is IPv4 address,\n              - \u0027value\u0027 if \u0027value\u0027 is not an IP Address\n              - canonical IPv6 address if \u0027value\u0027 is IPv6 address.\n\n    \"\"\"\n\n```","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"bf8f584b0e6ea92cba8a4e133b216b6be42bb029","unresolved":true,"context_lines":[{"line_number":210,"context_line":"        self.assertEqual(\u00272001:db8:0:1:1:1:1:1/128\u0027, result)"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    def test_convert_subnetpools(self):"},{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"4043fd7d_ae3be78c","line":213,"in_reply_to":"aacceb6d_bd4689d8","updated":"2024-05-01 19:44:44.000000000","message":"You can run the neutron test with a locally-modified neutron-lib to help debug, see the TOX_ENV_SRC_MODULES instructions in TESTING.rst.","commit_id":"9390829b87ca8ebdfec43717f248dd59da0364b0"}],"neutron_lib/tests/unit/api/test_converters.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"c5b7db53c768b5408314f956ba5a19b9d43cfc1f","unresolved":true,"context_lines":[{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"class TestConvertIPv6CIDRCanonicalFormat(base.BaseTestCase):"},{"line_number":219,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"0595bfed_fee40784","line":216,"updated":"2024-05-06 23:49:43.000000000","message":"Is this still valid after your other change? convert_ip_to_canonical_format() shouldn\u0027t get a subnet pool after that.","commit_id":"d1020da3eacff914259b3411f30ecb564d9f047c"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"433813e04c4f285a4ba70157d3aae52f597f8a76","unresolved":true,"context_lines":[{"line_number":213,"context_line":"        pools \u003d [{\u0027start\u0027: \u00271.1.1.1\u0027, \u0027end\u0027: \u00271.1.1.100\u0027}]"},{"line_number":214,"context_line":"        result \u003d converters.convert_ip_to_canonical_format(pools)"},{"line_number":215,"context_line":"        self.assertEqual(pools, result)"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"class TestConvertIPv6CIDRCanonicalFormat(base.BaseTestCase):"},{"line_number":219,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"c564bfbb_abced4b2","line":216,"in_reply_to":"0595bfed_fee40784","updated":"2024-05-07 14:13:45.000000000","message":"I shouldn\u0027t. But I still think it\u0027s valid; alternatively, we should change the semantics for the function (as documented in docstring) to reflect that it can actually fail with exception or otherwise. I don\u0027t have huge preference.","commit_id":"d1020da3eacff914259b3411f30ecb564d9f047c"}]}
