)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"593a540c7b1c8f725da0eda529d9676441a842cc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"02432b58_f651214c","updated":"2024-10-25 05:05:57.000000000","message":"Nice refactoring, LGTM.","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"31bfb469e7e566c6a66809031e36607c3831bf54","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"181c9811_82fdcd4b","updated":"2024-10-28 11:40:02.000000000","message":"The stray comment that @Jianjian noticed should be fixed.\n\nOne of the tests is (was already) pretty weak w.r.t. the regression it is intended to prevent. Possibly \"mea culpa\"! Suggested improvement (plus fixes for the comments) here \n\nhttps://review.opendev.org/c/openstack/swift/+/933557 sq? fixups for test_expirer.py\n\nI would have just pushed and merged but someone should check my hack in FakeInternalClient","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"839cd54720daa8caa2f5b73fa98d475292b4f486","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"eefbfdfa_16576736","updated":"2024-10-25 16:46:52.000000000","message":"recheck\nthe py3.8 pip failure has already solved by Tim!","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2abd88774cab465143d09a1a38d468bb92bd43d8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"961f4b9d_3efb459f","updated":"2024-10-28 19:26:04.000000000","message":"thanks for the help!  I think we can live with the \"hack\" in FakeInternalClient to make it handle acceptable_status more like the real for now.\n\nEventually I\u0027m imagining a \"build fake swift form aco_dict\" helper that registers responses and returns a *real* InternalClient wrapping a FakeSwift; but I\u0027m not sure if we have the appetite to do/review that work (yet) - so a better FakeInternalClient to help with maintenance of regressions seems like a decent compromise for now.","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d800ed775da22a607659517122e61c1c5c66aed5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"b17ccbd8_3deb0a12","updated":"2024-10-31 19:03:06.000000000","message":"I\u0027m not convinced that \"it\u0027s more like the real\" is enough of a reason to include a dead return in","commit_id":"697c167288c1feb99e5656a9580b9ae0c23d6c99"}],"test/unit/obj/test_expirer.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"593a540c7b1c8f725da0eda529d9676441a842cc","unresolved":true,"context_lines":[{"line_number":1603,"context_line":"        # UnexpectedResponse, and expect the second task container will"},{"line_number":1604,"context_line":"        # continue to be processed."},{"line_number":1605,"context_line":""},{"line_number":1606,"context_line":"        # Store reference to the real method before mocking"},{"line_number":1607,"context_line":"        self.expirer.swift.aco_dict[\u0027.expiring_objects\u0027]["},{"line_number":1608,"context_line":"            self.just_past_time_container] \u003d \\"},{"line_number":1609,"context_line":"            internal_client.UnexpectedResponse("}],"source_content_type":"text/x-python","patch_set":1,"id":"7e5f85e0_dbdb5a55","line":1606,"updated":"2024-10-25 05:05:57.000000000","message":"remove this line of comment","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2abd88774cab465143d09a1a38d468bb92bd43d8","unresolved":false,"context_lines":[{"line_number":1603,"context_line":"        # UnexpectedResponse, and expect the second task container will"},{"line_number":1604,"context_line":"        # continue to be processed."},{"line_number":1605,"context_line":""},{"line_number":1606,"context_line":"        # Store reference to the real method before mocking"},{"line_number":1607,"context_line":"        self.expirer.swift.aco_dict[\u0027.expiring_objects\u0027]["},{"line_number":1608,"context_line":"            self.just_past_time_container] \u003d \\"},{"line_number":1609,"context_line":"            internal_client.UnexpectedResponse("}],"source_content_type":"text/x-python","patch_set":1,"id":"26dbd71a_319e02a2","line":1606,"in_reply_to":"7e5f85e0_dbdb5a55","updated":"2024-10-28 19:26:04.000000000","message":"Done","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"593a540c7b1c8f725da0eda529d9676441a842cc","unresolved":false,"context_lines":[{"line_number":1610,"context_line":"                \u0027Mocked error\u0027, Response(status\u003d503))"},{"line_number":1611,"context_line":""},{"line_number":1612,"context_line":"        with mock.patch.object(self.expirer, \u0027pop_queue\u0027):"},{"line_number":1613,"context_line":"            self.expirer.run_once()"},{"line_number":1614,"context_line":"        # everything but the broken container"},{"line_number":1615,"context_line":"        expected \u003d sorted("},{"line_number":1616,"context_line":"            p"}],"source_content_type":"text/x-python","patch_set":1,"id":"581f874c_55bab6fe","line":1613,"updated":"2024-10-25 05:05:57.000000000","message":"Nice! now we have those call stubs in the FakeInternalClient, so we can just call ``self.expirer.run_once``.","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"31bfb469e7e566c6a66809031e36607c3831bf54","unresolved":true,"context_lines":[{"line_number":1684,"context_line":"            self.expirer.logger.statsd_client.get_increment_counts()"},{"line_number":1685,"context_line":"        )"},{"line_number":1686,"context_line":""},{"line_number":1687,"context_line":"    def test_iter_task_to_expire_404_response_on_empty_container(self):"},{"line_number":1688,"context_line":"        # Test that object listing on a missing container returns 404 and"},{"line_number":1689,"context_line":"        # raise UnexpectedResponse, and expect ``iter_task_to_expire`` won\u0027t"},{"line_number":1690,"context_line":"        # delete this task container."}],"source_content_type":"text/x-python","patch_set":1,"id":"5ff2d2c2_900dbcf4","line":1687,"range":{"start_line":1687,"start_character":49,"end_line":1687,"end_character":54},"updated":"2024-10-28 11:40:02.000000000","message":"should probably be missing rather than empty","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2abd88774cab465143d09a1a38d468bb92bd43d8","unresolved":false,"context_lines":[{"line_number":1684,"context_line":"            self.expirer.logger.statsd_client.get_increment_counts()"},{"line_number":1685,"context_line":"        )"},{"line_number":1686,"context_line":""},{"line_number":1687,"context_line":"    def test_iter_task_to_expire_404_response_on_empty_container(self):"},{"line_number":1688,"context_line":"        # Test that object listing on a missing container returns 404 and"},{"line_number":1689,"context_line":"        # raise UnexpectedResponse, and expect ``iter_task_to_expire`` won\u0027t"},{"line_number":1690,"context_line":"        # delete this task container."}],"source_content_type":"text/x-python","patch_set":1,"id":"32507f88_b7e1556d","line":1687,"range":{"start_line":1687,"start_character":49,"end_line":1687,"end_character":54},"in_reply_to":"5ff2d2c2_900dbcf4","updated":"2024-10-28 19:26:04.000000000","message":"Done","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"31bfb469e7e566c6a66809031e36607c3831bf54","unresolved":true,"context_lines":[{"line_number":1693,"context_line":"        self.expirer.swift.aco_dict["},{"line_number":1694,"context_line":"            \u0027.expiring_objects\u0027][missing_time_container] \u003d \\"},{"line_number":1695,"context_line":"            internal_client.UnexpectedResponse("},{"line_number":1696,"context_line":"                \u0027Mocked error\u0027, Response(status\u003d404))"},{"line_number":1697,"context_line":""},{"line_number":1698,"context_line":"        with mock.patch.object(self.expirer, \u0027pop_queue\u0027):"},{"line_number":1699,"context_line":"            self.expirer.run_once()"}],"source_content_type":"text/x-python","patch_set":1,"id":"f4bf0d43_6a8b55ba","line":1696,"updated":"2024-10-28 11:40:02.000000000","message":"this test is a bit odd in that the regression being covered is expirer line 343 i.e. 404 is no longer an acceptable status. However, the test is just changing the fake internal client to raise a 404 *regardless* of how it is called. Add 404 as an acceptable status at line 343 of the expirer and this will NOT fail.\n\nIdeally we\u0027d add acceptable status behavior to the FakeInternalClient. I don\u0027t like building more into the FakeInternalClient but it would prevent the regresion","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2abd88774cab465143d09a1a38d468bb92bd43d8","unresolved":false,"context_lines":[{"line_number":1693,"context_line":"        self.expirer.swift.aco_dict["},{"line_number":1694,"context_line":"            \u0027.expiring_objects\u0027][missing_time_container] \u003d \\"},{"line_number":1695,"context_line":"            internal_client.UnexpectedResponse("},{"line_number":1696,"context_line":"                \u0027Mocked error\u0027, Response(status\u003d404))"},{"line_number":1697,"context_line":""},{"line_number":1698,"context_line":"        with mock.patch.object(self.expirer, \u0027pop_queue\u0027):"},{"line_number":1699,"context_line":"            self.expirer.run_once()"}],"source_content_type":"text/x-python","patch_set":1,"id":"1019d0c8_100356db","line":1696,"in_reply_to":"f4bf0d43_6a8b55ba","updated":"2024-10-28 19:26:04.000000000","message":"Done","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"31bfb469e7e566c6a66809031e36607c3831bf54","unresolved":true,"context_lines":[{"line_number":1734,"context_line":"        self.assertFalse(log_lines)"},{"line_number":1735,"context_line":""},{"line_number":1736,"context_line":"    def test_iter_task_to_expire_503_response_on_empty_container(self):"},{"line_number":1737,"context_line":"        # Test that object listing on a missing container returns 503 and"},{"line_number":1738,"context_line":"        # raise UnexpectedResponse, and expect ``iter_task_to_expire`` won\u0027t"},{"line_number":1739,"context_line":"        # delete this task container."},{"line_number":1740,"context_line":"        missing_time \u003d str(self.now - 172800)"}],"source_content_type":"text/x-python","patch_set":1,"id":"111571b9_cbe38368","line":1737,"updated":"2024-10-28 11:40:02.000000000","message":"neither ``empty`` or ``missing`` seem relevant qualifiers to the container in this context","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2abd88774cab465143d09a1a38d468bb92bd43d8","unresolved":false,"context_lines":[{"line_number":1734,"context_line":"        self.assertFalse(log_lines)"},{"line_number":1735,"context_line":""},{"line_number":1736,"context_line":"    def test_iter_task_to_expire_503_response_on_empty_container(self):"},{"line_number":1737,"context_line":"        # Test that object listing on a missing container returns 503 and"},{"line_number":1738,"context_line":"        # raise UnexpectedResponse, and expect ``iter_task_to_expire`` won\u0027t"},{"line_number":1739,"context_line":"        # delete this task container."},{"line_number":1740,"context_line":"        missing_time \u003d str(self.now - 172800)"}],"source_content_type":"text/x-python","patch_set":1,"id":"a88ec169_940c591b","line":1737,"in_reply_to":"111571b9_cbe38368","updated":"2024-10-28 19:26:04.000000000","message":"Acknowledged","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"593a540c7b1c8f725da0eda529d9676441a842cc","unresolved":false,"context_lines":[{"line_number":1780,"context_line":"            ])"},{"line_number":1781,"context_line":""},{"line_number":1782,"context_line":"        log_lines \u003d self.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":1783,"context_line":"        self.assertEqual("},{"line_number":1784,"context_line":"            log_lines[0],"},{"line_number":1785,"context_line":"            \u0027Unexpected response while listing objects in container \u0027"},{"line_number":1786,"context_line":"            \u0027.expiring_objects %s: Mocked error\u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"24c09562_1af7c97b","line":1783,"updated":"2024-10-25 05:05:57.000000000","message":"if it\u0027s not this line of log assertion, this test case can be easily combined with the previous test case ``test_iter_task_to_expire_404_response_on_empty_container``, since they only differ in terms of the error code.","commit_id":"19b2a9340ce27959ad3ae3c24d5a23d199f442d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f07b2fb750670c56ad2f4b036bab50f072521629","unresolved":true,"context_lines":[{"line_number":47,"context_line":"    last_not_sleep \u003d seconds"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"class FakeInternalClient(object):"},{"line_number":51,"context_line":"    container_ring \u003d FakeRing()"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def __init__(self, aco_dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"ffbb6287_5ae2c082","line":50,"updated":"2024-10-28 21:02:39.000000000","message":"Probably out of scope, but I wonder if we could unify some of these:\n```\n$ grep -R \u0027class FakeInternalClient\u0027 test\ntest/unit/obj/test_expirer.py:class FakeInternalClient(object):\ntest/unit/cli/test_container_deleter.py:class FakeInternalClient(internal_client.InternalClient):\ntest/unit/container/test_reconciler.py:class FakeInternalClient(reconciler.InternalClient):\n```","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"55bd2dee470b55cd5159e541a3cc2b489c4308f9","unresolved":false,"context_lines":[{"line_number":47,"context_line":"    last_not_sleep \u003d seconds"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"class FakeInternalClient(object):"},{"line_number":51,"context_line":"    container_ring \u003d FakeRing()"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def __init__(self, aco_dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"aaa42f72_922ed1aa","line":50,"in_reply_to":"ffbb6287_5ae2c082","updated":"2024-11-01 15:43:11.000000000","message":"Acknowledged","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f07b2fb750670c56ad2f4b036bab50f072521629","unresolved":false,"context_lines":[{"line_number":62,"context_line":"                      },"},{"line_number":63,"context_line":"                  \u0027account2\u0027: {},"},{"line_number":64,"context_line":"                  \u0027account3\u0027: {"},{"line_number":65,"context_line":"                      \u0027some_bad_container\u0027: UnexpectedResponse(),"},{"line_number":66,"context_line":"                  },"},{"line_number":67,"context_line":"                 }"},{"line_number":68,"context_line":"            N.B. the objects entries should be the container-server JSON style"}],"source_content_type":"text/x-python","patch_set":2,"id":"e68e347c_1f4da2a6","line":65,"range":{"start_line":65,"start_character":44,"end_line":65,"end_character":64},"updated":"2024-10-28 21:02:39.000000000","message":"OK, and it has to be an *instance*, not the *type*.","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f07b2fb750670c56ad2f4b036bab50f072521629","unresolved":true,"context_lines":[{"line_number":83,"context_line":"            obj_count +\u003d len(obj_list_or_err)"},{"line_number":84,"context_line":"        return container_count, obj_count"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def iter_containers(self, account, prefix\u003d\u0027\u0027):"},{"line_number":87,"context_line":"        acc_dict \u003d self.aco_dict[account]"},{"line_number":88,"context_line":"        return [{\u0027name\u0027: six.text_type(container)}"},{"line_number":89,"context_line":"                for container in sorted(acc_dict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"35cb9049_77fb62fe","line":86,"updated":"2024-10-28 21:02:39.000000000","message":"It\u0027s a little funny to me that we only track calls for 3/5 of the methods we override...","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5d599960b0e1f91676d1587e2ced2b8760e2bed9","unresolved":true,"context_lines":[{"line_number":83,"context_line":"            obj_count +\u003d len(obj_list_or_err)"},{"line_number":84,"context_line":"        return container_count, obj_count"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def iter_containers(self, account, prefix\u003d\u0027\u0027):"},{"line_number":87,"context_line":"        acc_dict \u003d self.aco_dict[account]"},{"line_number":88,"context_line":"        return [{\u0027name\u0027: six.text_type(container)}"},{"line_number":89,"context_line":"                for container in sorted(acc_dict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"aad7108d_e534781f","line":86,"in_reply_to":"35cb9049_77fb62fe","updated":"2024-10-31 11:23:33.000000000","message":"IIUC we just track the ones we care about. Captured ``iter_objects`` gives us the containers so implicitly verifies ``iter_container``.","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"55bd2dee470b55cd5159e541a3cc2b489c4308f9","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            obj_count +\u003d len(obj_list_or_err)"},{"line_number":84,"context_line":"        return container_count, obj_count"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def iter_containers(self, account, prefix\u003d\u0027\u0027):"},{"line_number":87,"context_line":"        acc_dict \u003d self.aco_dict[account]"},{"line_number":88,"context_line":"        return [{\u0027name\u0027: six.text_type(container)}"},{"line_number":89,"context_line":"                for container in sorted(acc_dict)"}],"source_content_type":"text/x-python","patch_set":2,"id":"dcef1838_48df8234","line":86,"in_reply_to":"aad7108d_e534781f","updated":"2024-11-01 15:43:11.000000000","message":"Acknowledged","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f07b2fb750670c56ad2f4b036bab50f072521629","unresolved":true,"context_lines":[{"line_number":105,"context_line":"            acceptable_statuses \u003d kwargs.get(\u0027acceptable_statuses\u0027, [])"},{"line_number":106,"context_line":"            if exc.resp.status_int in acceptable_statuses or \\"},{"line_number":107,"context_line":"                    exc.resp.status_int // 100 in acceptable_statuses:"},{"line_number":108,"context_line":"                return []"},{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"6cc364e3_c0d7c7b9","line":108,"updated":"2024-10-28 21:02:39.000000000","message":"Wait, then why are we registering some flavor of `UnexpectedResponse`? Why not just register `[]`?\n\nI see there\u0027s some other discussion around it -- not sure why the solution should be \"reimplement `acceptable_statuses`\" instead of \"check the `acceptable_statuses` for the call which we\u0027re now tracking\".","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"55bd2dee470b55cd5159e541a3cc2b489c4308f9","unresolved":false,"context_lines":[{"line_number":105,"context_line":"            acceptable_statuses \u003d kwargs.get(\u0027acceptable_statuses\u0027, [])"},{"line_number":106,"context_line":"            if exc.resp.status_int in acceptable_statuses or \\"},{"line_number":107,"context_line":"                    exc.resp.status_int // 100 in acceptable_statuses:"},{"line_number":108,"context_line":"                return []"},{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"193b3fae_f46235ae","line":108,"in_reply_to":"098f7532_f03ad585","updated":"2024-11-01 15:43:11.000000000","message":"Done","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"67a64877395f45446e158a1818d8e545ae718a85","unresolved":true,"context_lines":[{"line_number":105,"context_line":"            acceptable_statuses \u003d kwargs.get(\u0027acceptable_statuses\u0027, [])"},{"line_number":106,"context_line":"            if exc.resp.status_int in acceptable_statuses or \\"},{"line_number":107,"context_line":"                    exc.resp.status_int // 100 in acceptable_statuses:"},{"line_number":108,"context_line":"                return []"},{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"cb6982d2_ef5f1a8c","line":108,"in_reply_to":"6cc364e3_c0d7c7b9","updated":"2024-10-29 08:51:19.000000000","message":"Registering ``UnexpectedResponse`` and also asserting that the call has ``acceptable_statuses\u003d[2]`` would also work.\n\nClay has discussed elsewhere that ideally we wouldn\u0027t be using a fake internal client, but patching up FakeSwift instead.","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5d599960b0e1f91676d1587e2ced2b8760e2bed9","unresolved":true,"context_lines":[{"line_number":105,"context_line":"            acceptable_statuses \u003d kwargs.get(\u0027acceptable_statuses\u0027, [])"},{"line_number":106,"context_line":"            if exc.resp.status_int in acceptable_statuses or \\"},{"line_number":107,"context_line":"                    exc.resp.status_int // 100 in acceptable_statuses:"},{"line_number":108,"context_line":"                return []"},{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"098f7532_f03ad585","line":108,"in_reply_to":"cb6982d2_ef5f1a8c","updated":"2024-10-31 11:23:33.000000000","message":"I added assertions on the acceptable_statuses, but also kept the handling of acceptable_statuses here. If we\u0027re going to have a fake internal client it seems better to have it match the real thing more closely.","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f07b2fb750670c56ad2f4b036bab50f072521629","unresolved":true,"context_lines":[{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"},{"line_number":112,"context_line":"            raise obj_iter"},{"line_number":113,"context_line":"        resp \u003d []"},{"line_number":114,"context_line":"        for obj in obj_iter:"},{"line_number":115,"context_line":"            if not isinstance(obj, dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"ca75d9f9_189ad170","line":112,"updated":"2024-10-28 21:02:39.000000000","message":"I missed this on the first read through because I was so distracted by the `UnexpectedResponse` special handling 😕","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"55bd2dee470b55cd5159e541a3cc2b489c4308f9","unresolved":false,"context_lines":[{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"},{"line_number":112,"context_line":"            raise obj_iter"},{"line_number":113,"context_line":"        resp \u003d []"},{"line_number":114,"context_line":"        for obj in obj_iter:"},{"line_number":115,"context_line":"            if not isinstance(obj, dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"b7e4dd49_d2146470","line":112,"in_reply_to":"26367bf2_87d5173e","updated":"2024-11-01 15:43:11.000000000","message":"Done","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d800ed775da22a607659517122e61c1c5c66aed5","unresolved":true,"context_lines":[{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"},{"line_number":112,"context_line":"            raise obj_iter"},{"line_number":113,"context_line":"        resp \u003d []"},{"line_number":114,"context_line":"        for obj in obj_iter:"},{"line_number":115,"context_line":"            if not isinstance(obj, dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"b98376e9_521bdbdf","line":112,"in_reply_to":"6dd37483_2f1b1db7","updated":"2024-10-31 19:03:06.000000000","message":"The more I stare at this, the more it bugs me:\n\n- The `self.aco_dict[account][container]` state gives us a weird API -- it takes a list of names to return, *or* an exception, but if you give an exception it *might* raise it *or* it might return an empty list?\n- As a result we get four possible returns, but half of them are for the sake of re-implementing `acceptable_statuses`.\n- So down in `test_iter_task_to_expire_404_response_on_missing_container` (which is the only place that could credibly be said to use this) we\u0027re *at best* testing the re-implementation...\n\nBut I think what really pushes me over the edge is that I can remove the entire block\n```\ndiff --git a/test/unit/obj/test_expirer.py b/test/unit/obj/test_expirer.py\nindex 5d9b9aa285..effe07efd5 100644\n--- a/test/unit/obj/test_expirer.py\n+++ b/test/unit/obj/test_expirer.py\n@@ -100,14 +100,6 @@ class FakeInternalClient(object):\n         )\n         acc_dict \u003d self.aco_dict[account]\n         obj_iter \u003d acc_dict.get(container, [])\n-        if isinstance(obj_iter, internal_client.UnexpectedResponse):\n-            exc \u003d obj_iter\n-            acceptable_statuses \u003d kwargs.get(\u0027acceptable_statuses\u0027, [])\n-            if exc.resp.status_int in acceptable_statuses or \\\n-                    exc.resp.status_int // 100 in acceptable_statuses:\n-                return []\n-            else:\n-                raise exc\n         if isinstance(obj_iter, Exception):\n             raise obj_iter\n         resp \u003d []\n```\nand tests still pass. So we don\u0027t even *need* the wonky API!\n\nIf what we *really* want is a **real** `InternalClient` backed by a `FakeSwift`, let\u0027s push for *that* (presumably as a follow-up) rather than add more code to a jig that we\u0027re trying to get rid of!","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"01fb55041d780cfb2d30c3dfa88297c5d5a11dde","unresolved":true,"context_lines":[{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"},{"line_number":112,"context_line":"            raise obj_iter"},{"line_number":113,"context_line":"        resp \u003d []"},{"line_number":114,"context_line":"        for obj in obj_iter:"},{"line_number":115,"context_line":"            if not isinstance(obj, dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"26367bf2_87d5173e","line":112,"in_reply_to":"b98376e9_521bdbdf","updated":"2024-11-01 09:51:40.000000000","message":"ok, I see now that I had failed to even make this fake internal client be like the real one because the fake isn\u0027t defaulting the ``acceptable_statuses`` kwarg 😭. So in ``test_iter_task_to_expire_404_response_on_missing_container`` if the expirer regressed such that it failed to pass ``acceptable_statuses\u003d[2]`` then unlike the real internal client we\u0027d have default ``acceptable_statuses\u003d[]`` and still raise the 404, whereas in the real world the client would suppress the 404 and *would return []*.\n\nSigh.\n\nSo it\u0027s just the assertions I added to cover what ``acceptable_statuses`` are actually passed that cover the regression.\n\nWe might improve on my attempt to make the fake more like the real, but at this point I\u0027m happy to de-invest in that effort. I think we\u0027re all agreed that ideally we wouldn\u0027t be using a fake internal client.","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5d599960b0e1f91676d1587e2ced2b8760e2bed9","unresolved":true,"context_lines":[{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                raise exc"},{"line_number":111,"context_line":"        if isinstance(obj_iter, Exception):"},{"line_number":112,"context_line":"            raise obj_iter"},{"line_number":113,"context_line":"        resp \u003d []"},{"line_number":114,"context_line":"        for obj in obj_iter:"},{"line_number":115,"context_line":"            if not isinstance(obj, dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"6dd37483_2f1b1db7","line":112,"in_reply_to":"ca75d9f9_189ad170","updated":"2024-10-31 11:23:33.000000000","message":"is there a concern here?","commit_id":"c26f92a8c9b2d91970b5ab187fcb02e2db6beec7"}]}
