)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy","status":"I\u0027m a Software Engineer at Red Hat and I love Open Source and connect with people! Feel free to DM through IRC, I\u0027ll be delighted to chat"},"change_message_id":"947490223ff75b56d30447b24dc9ec8cb6920d46","unresolved":true,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Preserve None for failed segment validation entries and"},{"line_number":19,"context_line":"leave inline-data entries unchanged."},{"line_number":20,"context_line":"Before storing the manifest, copy each entry and remove the transient"},{"line_number":21,"context_line":"headers key so backend response metadata does not become part of the SLO"},{"line_number":22,"context_line":"manifest."},{"line_number":23,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":28,"id":"94e38303_247f14b4","line":20,"updated":"2026-08-11 12:56:21.000000000","message":"\"*copy each entry* and remove the *transient* headers\" is \n\n1. No copy happens and the commit message should also be updated\n2. \"transient headers\" — The inline code comment was correctly updated to \"validation-only HEAD headers\" but the commit message also needs updating\n\nSince this is a commit message and part of the permanent git history this needs update before merging","commit_id":"583830498dea2fa97395e47adf8ed1b7d6d5a66b"},{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy","status":"I\u0027m a Software Engineer at Red Hat and I love Open Source and connect with people! Feel free to DM through IRC, I\u0027ll be delighted to chat"},"change_message_id":"c2228dc284957e884d9906b134b2dd5dd33c6dff","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Preserve None for failed segment validation entries and"},{"line_number":19,"context_line":"leave inline-data entries unchanged."},{"line_number":20,"context_line":"Before storing the manifest, copy each entry and remove the transient"},{"line_number":21,"context_line":"headers key so backend response metadata does not become part of the SLO"},{"line_number":22,"context_line":"manifest."},{"line_number":23,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":28,"id":"3016578f_83e6fada","line":20,"in_reply_to":"57721ae2_c4aa3698","updated":"2026-08-18 14:25:11.000000000","message":"Done","commit_id":"583830498dea2fa97395e47adf8ed1b7d6d5a66b"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"e42d35171b7b8b82a61099a1ee3b6cf61b77bf0b","unresolved":true,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Preserve None for failed segment validation entries and"},{"line_number":19,"context_line":"leave inline-data entries unchanged."},{"line_number":20,"context_line":"Before storing the manifest, copy each entry and remove the transient"},{"line_number":21,"context_line":"headers key so backend response metadata does not become part of the SLO"},{"line_number":22,"context_line":"manifest."},{"line_number":23,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":28,"id":"57721ae2_c4aa3698","line":20,"in_reply_to":"94e38303_247f14b4","updated":"2026-08-11 19:40:22.000000000","message":"Done!","commit_id":"583830498dea2fa97395e47adf8ed1b7d6d5a66b"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b4e8d74eaa8ef81ac5f045d69dd1eb1adc5ca563","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"4edcab10_46b35f11","updated":"2026-07-21 18:12:07.000000000","message":"I\u0027m skeptical of the value of \"a compatibility shim to support out-of-tree callers\" just so we can change the signature - but the strict spirit of a documented interface we may lean that direction:\n\n```\nif \u0027swift.callback.blah.v2\u0027 in req.environ:\n    callback(arg1, arg2)\nelif \u0027swift.callback.blah\u0027 in req.environ:\n    callback(arg1, arg2)\n```\n\nIt doesn\u0027t reduce the burdern in this case, but as a hat tip to that direction if we\u0027re going to make \"a breaking change\" we might one it once and for all?\n\n\u003e Swift does have one callback family, fetch_crypto_keys, that was deliberately designed to tolerate interface growth via *args, **kwargs.\n\nI think best in this specific case is to avoid the issue all together and just pass in a more rich \"validate this list of docs\" that we\u0027ve annotated with the extra data (which callers can ignore if they want).\n\ni.e. instead of the strict/limited `data_for_storage[i] \u003d seg_data` we can pass in `data_for_validation[i] \u003d dict(seg_data, headers\u003dresp.headers)`\n\n^ IMHO this avoids the \"compatibility with out of tree callbacks\" question - and keeps the single `hook(list_of_dicts)` interfact intact.","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"f77f5d8aa794296a718d2885cf991f8eb42d3e20","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"eeb3e3b7_ece39171","updated":"2026-07-21 22:18:37.000000000","message":"Yea I think keeping the old contract is important for sure, who knows what other callers might use this!","commit_id":"3b3df33678fe4cc77631ec56735b85c0fe632365"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e5f667d222585ec8c00fdb10b51d8a620ab02bc7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":22,"id":"1d17f088_98191961","updated":"2026-08-07 15:18:45.000000000","message":"I like that this change has been proposed in a separate patch. IMHO that makes it easier to review. However, we probably want to make merging this conditional on the use case also merging.\n\nI think some cleanup is worthwhile, but I agree with the concept.","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"db3dbfc2bd44e6ab45546a7c67e5a20553c3c4bd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":22,"id":"cb9fd607_37544da7","updated":"2026-08-07 11:24:17.000000000","message":"recheck \n\nUnrelated to this change: 2026-08-07 00:01:08.639675 | controller | {0} openstack.tests.functional.cloud.test_compute.TestCompute.test_create_and_delete_server [20.672344s] ... FAILED","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":22,"id":"5ea231e9_c954fdc2","in_reply_to":"1d17f088_98191961","updated":"2026-08-07 18:33:30.000000000","message":"100% this will be conditional on the child patch","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":23,"id":"a16169cb_09d9916d","updated":"2026-08-07 18:33:30.000000000","message":"@alistairncoles@gmail.com changes apply and pushed! Thanks for the review, I think the tests are much better now","commit_id":"37ccf9a8cb5da449e649d65feec6a7a1535356fd"},{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy","status":"I\u0027m a Software Engineer at Red Hat and I love Open Source and connect with people! Feel free to DM through IRC, I\u0027ll be delighted to chat"},"change_message_id":"947490223ff75b56d30447b24dc9ec8cb6920d46","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":28,"id":"f3f94789_f3e33a0f","updated":"2026-08-11 12:56:21.000000000","message":"The code is correct, the only issue I found is that the commit message needs update and since is part of permanent git history I believe it has to be updated before merging.","commit_id":"583830498dea2fa97395e47adf8ed1b7d6d5a66b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0fa2b1dbf2b7ce31f47ee8fd3e4be9fd3e155cfc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":46,"id":"8d334f0c_cc12fd5e","updated":"2026-08-27 16:33:01.000000000","message":"Claude says:\n\n```\nIssue: headers copied for every segment even when no hook exists — worth fixing\n\nHeaderKeyDict(head_seg_resp.headers) is built unconditionally at slo.py:1469, inside validate_seg_dict. But the hook lookup doesn\u0027t happen until slo.py:1519 — after the entire StreamingPile HEAD loop has completed. So every SLO manifest PUT in every deployment builds one full header-dict copy per object-backed segment, holds all of them live simultaneously in data_for_validation, and then discards them at :1544. Only s3api MPU checksum persistence consumes them.\n\nAt the default max_manifest_segments \u003d 1000 (slo.py:380) that\u0027s 1000 dict copies per PUT, each carrying the segment\u0027s full X-Object-Meta-* / X-Object-Sysmeta-* set; s3api deployments commonly raise that limit to 10000. It\u0027s allocation and GC pressure, not a leak — but it\u0027s free to avoid:\n\n# hoist above the StreamingPile loop\nhook \u003d req.environ.get(\u0027swift.callback.slo_manifest_hook\u0027)\n...\n    if hook:\n        seg_data[\u0027headers\u0027] \u003d HeaderKeyDict(head_seg_resp.headers)\n\nvalidate_seg_dict already closes over req-scope names, so the hoist is mechanical. The pop at :1544 stays as-is.\n\nMinor\n\nNaming. The rename data_for_storage → data_for_validation reads well at the hook call site (:1521) but is now slightly misleading at :1574, where that same list is the storage payload. A word in the existing comment at :1543 explaining that the strip is what converts it would carry the reader across.\n```","commit_id":"09a4bc1dc7b69321bbe59797d3b494717c623838"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"da302f58621b83843683f3c3c8519256a4783f72","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":47,"id":"aed0c2fb_dd8d30f9","updated":"2026-08-27 22:02:11.000000000","message":"Addressed comments and moved this up the chain so we can get it approved faster","commit_id":"77e558675081d8c76b9d07c523d7661a02e6ca6a"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"8e5f4a5a6fe39bcce782197b8a95e5773d7d8692","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":47,"id":"89c22d56_28433632","updated":"2026-08-27 23:18:02.000000000","message":"recheck /opt/stack/devstack/functions-common:1182 Failed to update apt repos, we\u0027re dead now","commit_id":"77e558675081d8c76b9d07c523d7661a02e6ca6a"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"bc118d5eeae8a28874889f87f83d2f42ad1a9198","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":47,"id":"a1c63756_9ef3dd72","updated":"2026-08-28 02:41:01.000000000","message":"recheck maybe this time we won’t time out :)","commit_id":"77e558675081d8c76b9d07c523d7661a02e6ca6a"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"7fd58b4c54cab756b5f8cf8cd9f2c42349a50728","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":48,"id":"b784a7eb_9a5911f1","updated":"2026-09-01 15:09:54.000000000","message":"LGTM - clean refactoring.","commit_id":"9990f99d36e05fa2f80b7fe392910839b4277025"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"e43ff897b9a0c839283be2d84c400636ff43c5b0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":48,"id":"124913ef_9692fcbb","updated":"2026-08-28 13:17:55.000000000","message":"recheck\n\nopenstack.exceptions.ResourceTimeout: Timeout waiting for Volume","commit_id":"9990f99d36e05fa2f80b7fe392910839b4277025"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4eb843de863a022bec57d17c20f17d1ae41b1ea4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":52,"id":"8efaf2d9_be4e342e","updated":"2026-09-11 17:54:40.000000000","message":"This reminds me, I should probably push on https://review.opendev.org/c/openstack/swift/+/629659 again...","commit_id":"c71ada227565ce0457925e8a0b1cc1e4583a8abd"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"8b35fccbeff7bb9cb936adf5c2e561d7d47dedc6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":55,"id":"67235e2d_d63fdaba","updated":"2026-09-19 21:24:43.000000000","message":"recheck","commit_id":"7e810621c9943922c82878783ecf918b6de2882c"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b4e8d74eaa8ef81ac5f045d69dd1eb1adc5ca563","unresolved":true,"context_lines":[{"line_number":782,"context_line":"        too_small_message \u003d (\u0027s3api requires that each segment be at least \u0027"},{"line_number":783,"context_line":"                             \u0027%d bytes\u0027 % self.conf.min_segment_size)"},{"line_number":784,"context_line":""},{"line_number":785,"context_line":"        def size_checker(manifest, _segment_head_headers):"},{"line_number":786,"context_line":"            # Check the size of each segment except the last and make sure"},{"line_number":787,"context_line":"            # they are all more than the minimum upload chunk size."},{"line_number":788,"context_line":"            # Note that we need to use the *internal* keys, since we\u0027re"}],"source_content_type":"text/x-python","patch_set":2,"id":"818f41ef_871228f3","line":785,"updated":"2026-07-21 18:12:07.000000000","message":"just go ahead and throw a **kwargs on here once and for all?","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"f77f5d8aa794296a718d2885cf991f8eb42d3e20","unresolved":false,"context_lines":[{"line_number":782,"context_line":"        too_small_message \u003d (\u0027s3api requires that each segment be at least \u0027"},{"line_number":783,"context_line":"                             \u0027%d bytes\u0027 % self.conf.min_segment_size)"},{"line_number":784,"context_line":""},{"line_number":785,"context_line":"        def size_checker(manifest, _segment_head_headers):"},{"line_number":786,"context_line":"            # Check the size of each segment except the last and make sure"},{"line_number":787,"context_line":"            # they are all more than the minimum upload chunk size."},{"line_number":788,"context_line":"            # Note that we need to use the *internal* keys, since we\u0027re"}],"source_content_type":"text/x-python","patch_set":2,"id":"054ab57e_5224e991","line":785,"in_reply_to":"818f41ef_871228f3","updated":"2026-07-21 22:18:37.000000000","message":"Acknowledged","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"}],"swift/common/middleware/slo.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b4e8d74eaa8ef81ac5f045d69dd1eb1adc5ca563","unresolved":true,"context_lines":[{"line_number":1510,"context_line":"                        segment_length, seg_data \u003d validate_seg_dict("},{"line_number":1511,"context_line":"                            parsed_data[i], resp,"},{"line_number":1512,"context_line":"                            allow_empty_segment\u003d(i \u003d\u003d len(parsed_data) - 1))"},{"line_number":1513,"context_line":"                        data_for_storage[i] \u003d seg_data"},{"line_number":1514,"context_line":"                        total_size +\u003d segment_length"},{"line_number":1515,"context_line":""},{"line_number":1516,"context_line":"            # Middleware left of SLO can add a callback to the WSGI"}],"source_content_type":"text/x-python","patch_set":2,"id":"e615684a_d26cfe3c","line":1513,"updated":"2026-07-21 18:12:07.000000000","message":"I\u0027m somewhat curious if it would be \"simpler\" to annotate seg_data:\n\n```\ndata_for_storage[i] \u003d seg_data\ndata_for_validation[i] \u003d dict(seg_data, headers\u003dresp.headers)\n```\n\n... and keep the signature the same:\n\n```\n- more_problems \u003d hook(data_for_storage)\n+ more_problems \u003d hook(data_for_validation)\n```","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"f77f5d8aa794296a718d2885cf991f8eb42d3e20","unresolved":false,"context_lines":[{"line_number":1510,"context_line":"                        segment_length, seg_data \u003d validate_seg_dict("},{"line_number":1511,"context_line":"                            parsed_data[i], resp,"},{"line_number":1512,"context_line":"                            allow_empty_segment\u003d(i \u003d\u003d len(parsed_data) - 1))"},{"line_number":1513,"context_line":"                        data_for_storage[i] \u003d seg_data"},{"line_number":1514,"context_line":"                        total_size +\u003d segment_length"},{"line_number":1515,"context_line":""},{"line_number":1516,"context_line":"            # Middleware left of SLO can add a callback to the WSGI"}],"source_content_type":"text/x-python","patch_set":2,"id":"133c19b2_53b64386","line":1513,"in_reply_to":"e615684a_d26cfe3c","updated":"2026-07-21 22:18:37.000000000","message":"This is simpler I agree.","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b4e8d74eaa8ef81ac5f045d69dd1eb1adc5ca563","unresolved":true,"context_lines":[{"line_number":1519,"context_line":"            hook \u003d req.environ.get(\u0027swift.callback.slo_manifest_hook\u0027)"},{"line_number":1520,"context_line":"            if hook:"},{"line_number":1521,"context_line":"                more_problems \u003d hook("},{"line_number":1522,"context_line":"                    data_for_storage, segment_head_headers)"},{"line_number":1523,"context_line":"                if more_problems:"},{"line_number":1524,"context_line":"                    problem_segments.extend(more_problems)"},{"line_number":1525,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"f13278e4_e4ca0c6e","line":1522,"updated":"2026-07-21 18:12:07.000000000","message":"swift/common/middleware/slo.py:1519 changes the documented middleware callback contract from hook(manifest) to hook(manifest, segment_head_headers) with no compatibility shim. In-tree callers were updated, but any out-of-tree middleware upgrading to this Swift version while still implementing the old one-argument hook will fail with TypeError on valid SLO multipart-manifest PUT requests until it updates to the new signature.","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"f77f5d8aa794296a718d2885cf991f8eb42d3e20","unresolved":false,"context_lines":[{"line_number":1519,"context_line":"            hook \u003d req.environ.get(\u0027swift.callback.slo_manifest_hook\u0027)"},{"line_number":1520,"context_line":"            if hook:"},{"line_number":1521,"context_line":"                more_problems \u003d hook("},{"line_number":1522,"context_line":"                    data_for_storage, segment_head_headers)"},{"line_number":1523,"context_line":"                if more_problems:"},{"line_number":1524,"context_line":"                    problem_segments.extend(more_problems)"},{"line_number":1525,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"0b5f346f_31a960ef","line":1522,"in_reply_to":"f13278e4_e4ca0c6e","updated":"2026-07-21 22:18:37.000000000","message":"Acknowledged","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e5f667d222585ec8c00fdb10b51d8a620ab02bc7","unresolved":true,"context_lines":[{"line_number":1507,"context_line":"                            parsed_data[i], resp,"},{"line_number":1508,"context_line":"                            allow_empty_segment\u003d(i \u003d\u003d len(parsed_data) - 1))"},{"line_number":1509,"context_line":"                        if seg_data is not None:"},{"line_number":1510,"context_line":"                            seg_data \u003d dict("},{"line_number":1511,"context_line":"                                seg_data,"},{"line_number":1512,"context_line":"                                headers\u003dHeaderKeyDict(resp.headers))"},{"line_number":1513,"context_line":"                        data_for_validation[i] \u003d seg_data"}],"source_content_type":"text/x-python","patch_set":22,"id":"effb2839_b5102f57","line":1510,"updated":"2026-08-07 15:18:45.000000000","message":"it isn\u0027t necessary to construct a fresh dict here? the original ``seg_data`` cannot be used again because the name ``seg_data`` has been reassigned to the new dict so it\u0027s fine to write:\n\n```\nseg_data[headers] \u003d HeaderKeyDict(resp.headers)\n```\n\nsame for ``resp.headers`` I think, no need to wrap it another HeaderKeyDict.\n\nAlso, ``validate_seg_dict`` could set the headers in seg_data before returning, which eliminates this ``if`` clause completely.\n\nUPDATE re \"same for ``resp.headers`` I think, no need to wrap it another HeaderKeyDict.\" - maybe if we\u0027re worried about the hook modifying headers?? I can see a test that asserts header dicts from the same resp but passed in mutliple seg_data are not the same object. But it could be set in the ``validate_seg_dict`` method\n\n```\ndiff --git a/swift/common/middleware/slo.py b/swift/common/middleware/slo.py\nindex f8ef49566..7b61ae447 100644\n--- a/swift/common/middleware/slo.py\n+++ b/swift/common/middleware/slo.py\n@@ -1465,7 +1465,8 @@ class StaticLargeObject(object):\n                 \u0027bytes\u0027: head_seg_resp.content_length,\n                 \u0027hash\u0027: head_seg_resp.etag,\n                 \u0027content_type\u0027: head_seg_resp.content_type,\n-                \u0027last_modified\u0027: last_modified_formatted\n+                \u0027last_modified\u0027: last_modified_formatted,\n+                \u0027headers\u0027: HeaderKeyDict(head_seg_resp.headers),\n             }\n             if seg_dict.get(\u0027range\u0027):\n                 seg_data[\u0027range\u0027] \u003d seg_dict[\u0027range\u0027]\n@@ -1506,10 +1507,6 @@ class StaticLargeObject(object):\n                         segment_length, seg_data \u003d validate_seg_dict(\n                             parsed_data[i], resp,\n                             allow_empty_segment\u003d(i \u003d\u003d len(parsed_data) - 1))\n-                        if seg_data is not None:\n-                            seg_data \u003d dict(\n-                                seg_data,\n-                                headers\u003dHeaderKeyDict(resp.headers))\n                         data_for_validation[i] \u003d seg_data\n                         total_size +\u003d segment_length\n \n\n```","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"3055991eaea288b14ce62b6c4ac5943121ac61e7","unresolved":false,"context_lines":[{"line_number":1507,"context_line":"                            parsed_data[i], resp,"},{"line_number":1508,"context_line":"                            allow_empty_segment\u003d(i \u003d\u003d len(parsed_data) - 1))"},{"line_number":1509,"context_line":"                        if seg_data is not None:"},{"line_number":1510,"context_line":"                            seg_data \u003d dict("},{"line_number":1511,"context_line":"                                seg_data,"},{"line_number":1512,"context_line":"                                headers\u003dHeaderKeyDict(resp.headers))"},{"line_number":1513,"context_line":"                        data_for_validation[i] \u003d seg_data"}],"source_content_type":"text/x-python","patch_set":22,"id":"0a135425_54c42e34","line":1510,"in_reply_to":"329483c5_0431b42e","updated":"2026-08-19 23:44:40.000000000","message":"Done","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":true,"context_lines":[{"line_number":1507,"context_line":"                            parsed_data[i], resp,"},{"line_number":1508,"context_line":"                            allow_empty_segment\u003d(i \u003d\u003d len(parsed_data) - 1))"},{"line_number":1509,"context_line":"                        if seg_data is not None:"},{"line_number":1510,"context_line":"                            seg_data \u003d dict("},{"line_number":1511,"context_line":"                                seg_data,"},{"line_number":1512,"context_line":"                                headers\u003dHeaderKeyDict(resp.headers))"},{"line_number":1513,"context_line":"                        data_for_validation[i] \u003d seg_data"}],"source_content_type":"text/x-python","patch_set":22,"id":"329483c5_0431b42e","line":1510,"in_reply_to":"effb2839_b5102f57","updated":"2026-08-07 18:33:30.000000000","message":"\u003e it isn\u0027t necessary to construct a fresh dict here?\n\nYea looking at these, we can just throw the resp headers in the original `seg_data`\n\nI\u0027ll also throw in a test to assert the behavior of updating validation headers too\nsomething like:\n`test_handle_multipart_put_callback_header_changes_are_isolated`","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e5f667d222585ec8c00fdb10b51d8a620ab02bc7","unresolved":true,"context_lines":[{"line_number":1513,"context_line":"                        data_for_validation[i] \u003d seg_data"},{"line_number":1514,"context_line":"                        total_size +\u003d segment_length"},{"line_number":1515,"context_line":""},{"line_number":1516,"context_line":"            # Middleware left of SLO can can add a callback to the WSGI"},{"line_number":1517,"context_line":"            # environment, inspect segment validation data, and"},{"line_number":1518,"context_line":"            # perform additional validation or manifest manipulation."},{"line_number":1519,"context_line":"            # Successful object-backed entries include transient HEAD"}],"source_content_type":"text/x-python","patch_set":22,"id":"9abcef6b_5eb49926","line":1516,"range":{"start_line":1516,"start_character":37,"end_line":1516,"end_character":44},"updated":"2026-08-07 15:18:45.000000000","message":"too many ``can`` s 😀","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"3055991eaea288b14ce62b6c4ac5943121ac61e7","unresolved":false,"context_lines":[{"line_number":1513,"context_line":"                        data_for_validation[i] \u003d seg_data"},{"line_number":1514,"context_line":"                        total_size +\u003d segment_length"},{"line_number":1515,"context_line":""},{"line_number":1516,"context_line":"            # Middleware left of SLO can can add a callback to the WSGI"},{"line_number":1517,"context_line":"            # environment, inspect segment validation data, and"},{"line_number":1518,"context_line":"            # perform additional validation or manifest manipulation."},{"line_number":1519,"context_line":"            # Successful object-backed entries include transient HEAD"}],"source_content_type":"text/x-python","patch_set":22,"id":"a3a3ffa0_79bead36","line":1516,"range":{"start_line":1516,"start_character":37,"end_line":1516,"end_character":44},"in_reply_to":"6db3a0d0_46d875c6","updated":"2026-08-19 23:44:40.000000000","message":"Done","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":true,"context_lines":[{"line_number":1513,"context_line":"                        data_for_validation[i] \u003d seg_data"},{"line_number":1514,"context_line":"                        total_size +\u003d segment_length"},{"line_number":1515,"context_line":""},{"line_number":1516,"context_line":"            # Middleware left of SLO can can add a callback to the WSGI"},{"line_number":1517,"context_line":"            # environment, inspect segment validation data, and"},{"line_number":1518,"context_line":"            # perform additional validation or manifest manipulation."},{"line_number":1519,"context_line":"            # Successful object-backed entries include transient HEAD"}],"source_content_type":"text/x-python","patch_set":22,"id":"6db3a0d0_46d875c6","line":1516,"range":{"start_line":1516,"start_character":37,"end_line":1516,"end_character":44},"in_reply_to":"9abcef6b_5eb49926","updated":"2026-08-07 18:33:30.000000000","message":"Whoops! lets just fix this...","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e5f667d222585ec8c00fdb10b51d8a620ab02bc7","unresolved":true,"context_lines":[{"line_number":1516,"context_line":"            # Middleware left of SLO can can add a callback to the WSGI"},{"line_number":1517,"context_line":"            # environment, inspect segment validation data, and"},{"line_number":1518,"context_line":"            # perform additional validation or manifest manipulation."},{"line_number":1519,"context_line":"            # Successful object-backed entries include transient HEAD"},{"line_number":1520,"context_line":"            # headers. SLO copies other manifest changes but removes those"},{"line_number":1521,"context_line":"            # headers before writing."},{"line_number":1522,"context_line":"            hook \u003d req.environ.get(\u0027swift.callback.slo_manifest_hook\u0027)"}],"source_content_type":"text/x-python","patch_set":22,"id":"538f2619_cefa8545","line":1519,"range":{"start_line":1519,"start_character":55,"end_line":1519,"end_character":64},"updated":"2026-08-07 15:18:45.000000000","message":"I stumbled a bit over the use of \"transient\". I\u0027m guessing it refers to how the headers are popped later, but as far as the callback is concerned there is nothing transient about them. Also, we have ``x-object-transient-sysmeta-*`` headers in responses and at first glance I though it was referring to only those headers!","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"3055991eaea288b14ce62b6c4ac5943121ac61e7","unresolved":false,"context_lines":[{"line_number":1516,"context_line":"            # Middleware left of SLO can can add a callback to the WSGI"},{"line_number":1517,"context_line":"            # environment, inspect segment validation data, and"},{"line_number":1518,"context_line":"            # perform additional validation or manifest manipulation."},{"line_number":1519,"context_line":"            # Successful object-backed entries include transient HEAD"},{"line_number":1520,"context_line":"            # headers. SLO copies other manifest changes but removes those"},{"line_number":1521,"context_line":"            # headers before writing."},{"line_number":1522,"context_line":"            hook \u003d req.environ.get(\u0027swift.callback.slo_manifest_hook\u0027)"}],"source_content_type":"text/x-python","patch_set":22,"id":"12e335a0_39bf12da","line":1519,"range":{"start_line":1519,"start_character":55,"end_line":1519,"end_character":64},"in_reply_to":"030d5ddf_2e45b45c","updated":"2026-08-19 23:44:40.000000000","message":"Done","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":true,"context_lines":[{"line_number":1516,"context_line":"            # Middleware left of SLO can can add a callback to the WSGI"},{"line_number":1517,"context_line":"            # environment, inspect segment validation data, and"},{"line_number":1518,"context_line":"            # perform additional validation or manifest manipulation."},{"line_number":1519,"context_line":"            # Successful object-backed entries include transient HEAD"},{"line_number":1520,"context_line":"            # headers. SLO copies other manifest changes but removes those"},{"line_number":1521,"context_line":"            # headers before writing."},{"line_number":1522,"context_line":"            hook \u003d req.environ.get(\u0027swift.callback.slo_manifest_hook\u0027)"}],"source_content_type":"text/x-python","patch_set":22,"id":"030d5ddf_2e45b45c","line":1519,"range":{"start_line":1519,"start_character":55,"end_line":1519,"end_character":64},"in_reply_to":"538f2619_cefa8545","updated":"2026-08-07 18:33:30.000000000","message":"Oh good point! Probably should change this to avoid future confusion, maybe like\n`... validation-only HEAD headers ...`","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e5f667d222585ec8c00fdb10b51d8a620ab02bc7","unresolved":true,"context_lines":[{"line_number":1532,"context_line":"                    continue"},{"line_number":1533,"context_line":"                stored_seg_data \u003d dict(seg_data)"},{"line_number":1534,"context_line":"                stored_seg_data.pop(\u0027headers\u0027, None)"},{"line_number":1535,"context_line":"                data_for_storage.append(stored_seg_data)"},{"line_number":1536,"context_line":""},{"line_number":1537,"context_line":"            if problem_segments:"},{"line_number":1538,"context_line":"                err \u003d HTTPBadRequest(content_type\u003dout_content_type)"}],"source_content_type":"text/x-python","patch_set":22,"id":"20ca0aad_8c01640e","line":1535,"updated":"2026-08-07 15:18:45.000000000","message":"three things:\n\n1. this copying is done before the problem_segments check, so in the unhappy path this is wasted work - move to line 1553\n\n2. I think this can be combined with the for loop at line 1554? just one iteration\n\n3. do we need to copy all the dicts to a new list, vs just popping the headers out of the dicts in the same list?\n\n```\ndiff --git a/swift/common/middleware/slo.py b/swift/common/middleware/slo.py\nindex f8ef49566..248e14a8f 100644\n--- a/swift/common/middleware/slo.py\n+++ b/swift/common/middleware/slo.py\n@@ -1525,15 +1525,6 @@ class StaticLargeObject(object):\n                 if more_problems:\n                     problem_segments.extend(more_problems)\n \n-            data_for_storage \u003d []\n-            for seg_data in data_for_validation:\n-                if seg_data is None:\n-                    data_for_storage.append(None)\n-                    continue\n-                stored_seg_data \u003d dict(seg_data)\n-                stored_seg_data.pop(\u0027headers\u0027, None)\n-                data_for_storage.append(stored_seg_data)\n-\n             if problem_segments:\n                 err \u003d HTTPBadRequest(content_type\u003dout_content_type)\n                 resp_dict \u003d {}\n@@ -1551,7 +1542,9 @@ class StaticLargeObject(object):\n                 return\n \n             slo_etag \u003d md5(usedforsecurity\u003dFalse)\n-            for seg_data in data_for_storage:\n+            for seg_data in data_for_validation:\n+                # we only reach here is all seg_data are valid dicts\n+                seg_data.pop(\u0027headers\u0027, None)\n                 if \u0027data\u0027 in seg_data:\n                     raw_data \u003d base64.b64decode(seg_data[\u0027data\u0027])\n                     r \u003d md5(raw_data, usedforsecurity\u003dFalse).hexdigest()\n@@ -1581,7 +1574,7 @@ class StaticLargeObject(object):\n                         yield chunk\n                 return\n \n-            json_data \u003d json.dumps(data_for_storage).encode(\u0027utf-8\u0027)\n+            json_data \u003d json.dumps(data_for_validation).encode(\u0027utf-8\u0027)\n             req.body \u003d json_data\n             req.headers.update({\n                 SYSMETA_SLO_ETAG: slo_etag,\n\n```","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":true,"context_lines":[{"line_number":1532,"context_line":"                    continue"},{"line_number":1533,"context_line":"                stored_seg_data \u003d dict(seg_data)"},{"line_number":1534,"context_line":"                stored_seg_data.pop(\u0027headers\u0027, None)"},{"line_number":1535,"context_line":"                data_for_storage.append(stored_seg_data)"},{"line_number":1536,"context_line":""},{"line_number":1537,"context_line":"            if problem_segments:"},{"line_number":1538,"context_line":"                err \u003d HTTPBadRequest(content_type\u003dout_content_type)"}],"source_content_type":"text/x-python","patch_set":22,"id":"f8e37e50_5a1ad2dd","line":1535,"in_reply_to":"20ca0aad_8c01640e","updated":"2026-08-07 18:33:30.000000000","message":"Yea I think these are all valid claims, lets do them!","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0fa2b1dbf2b7ce31f47ee8fd3e4be9fd3e155cfc","unresolved":false,"context_lines":[{"line_number":1532,"context_line":"                    continue"},{"line_number":1533,"context_line":"                stored_seg_data \u003d dict(seg_data)"},{"line_number":1534,"context_line":"                stored_seg_data.pop(\u0027headers\u0027, None)"},{"line_number":1535,"context_line":"                data_for_storage.append(stored_seg_data)"},{"line_number":1536,"context_line":""},{"line_number":1537,"context_line":"            if problem_segments:"},{"line_number":1538,"context_line":"                err \u003d HTTPBadRequest(content_type\u003dout_content_type)"}],"source_content_type":"text/x-python","patch_set":22,"id":"8797e60e_432b230c","line":1535,"in_reply_to":"f8e37e50_5a1ad2dd","updated":"2026-08-27 16:33:01.000000000","message":"Done","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"3055991eaea288b14ce62b6c4ac5943121ac61e7","unresolved":false,"context_lines":[{"line_number":1532,"context_line":"                    continue"},{"line_number":1533,"context_line":"                stored_seg_data \u003d dict(seg_data)"},{"line_number":1534,"context_line":"                stored_seg_data.pop(\u0027headers\u0027, None)"},{"line_number":1535,"context_line":"                data_for_storage.append(stored_seg_data)"},{"line_number":1536,"context_line":""},{"line_number":1537,"context_line":"            if problem_segments:"},{"line_number":1538,"context_line":"                err \u003d HTTPBadRequest(content_type\u003dout_content_type)"}],"source_content_type":"text/x-python","patch_set":22,"id":"b2aa946a_fbc8433d","line":1535,"in_reply_to":"f8e37e50_5a1ad2dd","updated":"2026-08-19 23:44:40.000000000","message":"Done","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0fa2b1dbf2b7ce31f47ee8fd3e4be9fd3e155cfc","unresolved":true,"context_lines":[{"line_number":1466,"context_line":"                \u0027hash\u0027: head_seg_resp.etag,"},{"line_number":1467,"context_line":"                \u0027content_type\u0027: head_seg_resp.content_type,"},{"line_number":1468,"context_line":"                \u0027last_modified\u0027: last_modified_formatted,"},{"line_number":1469,"context_line":"                \u0027headers\u0027: HeaderKeyDict(head_seg_resp.headers),"},{"line_number":1470,"context_line":"            }"},{"line_number":1471,"context_line":"            if seg_dict.get(\u0027range\u0027):"},{"line_number":1472,"context_line":"                seg_data[\u0027range\u0027] \u003d seg_dict[\u0027range\u0027]"}],"source_content_type":"text/x-python","patch_set":46,"id":"ccc671f0_2f42b568","line":1469,"updated":"2026-08-27 16:33:01.000000000","message":"this could be conditional on hook not being None","commit_id":"09a4bc1dc7b69321bbe59797d3b494717c623838"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"48a70b78fde691513a28de6638cf75aceca69bc9","unresolved":true,"context_lines":[{"line_number":1466,"context_line":"                \u0027hash\u0027: head_seg_resp.etag,"},{"line_number":1467,"context_line":"                \u0027content_type\u0027: head_seg_resp.content_type,"},{"line_number":1468,"context_line":"                \u0027last_modified\u0027: last_modified_formatted,"},{"line_number":1469,"context_line":"                \u0027headers\u0027: HeaderKeyDict(head_seg_resp.headers),"},{"line_number":1470,"context_line":"            }"},{"line_number":1471,"context_line":"            if seg_dict.get(\u0027range\u0027):"},{"line_number":1472,"context_line":"                seg_data[\u0027range\u0027] \u003d seg_dict[\u0027range\u0027]"}],"source_content_type":"text/x-python","patch_set":46,"id":"d15c856f_67330466","line":1469,"in_reply_to":"ccc671f0_2f42b568","updated":"2026-08-27 17:26:47.000000000","message":"Yea I think we could make that happen","commit_id":"09a4bc1dc7b69321bbe59797d3b494717c623838"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"da302f58621b83843683f3c3c8519256a4783f72","unresolved":false,"context_lines":[{"line_number":1466,"context_line":"                \u0027hash\u0027: head_seg_resp.etag,"},{"line_number":1467,"context_line":"                \u0027content_type\u0027: head_seg_resp.content_type,"},{"line_number":1468,"context_line":"                \u0027last_modified\u0027: last_modified_formatted,"},{"line_number":1469,"context_line":"                \u0027headers\u0027: HeaderKeyDict(head_seg_resp.headers),"},{"line_number":1470,"context_line":"            }"},{"line_number":1471,"context_line":"            if seg_dict.get(\u0027range\u0027):"},{"line_number":1472,"context_line":"                seg_data[\u0027range\u0027] \u003d seg_dict[\u0027range\u0027]"}],"source_content_type":"text/x-python","patch_set":46,"id":"a39c8596_3b02f8c7","line":1469,"in_reply_to":"d15c856f_67330466","updated":"2026-08-27 22:02:11.000000000","message":"Done","commit_id":"09a4bc1dc7b69321bbe59797d3b494717c623838"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4eb843de863a022bec57d17c20f17d1ae41b1ea4","unresolved":true,"context_lines":[{"line_number":1469,"context_line":"                \u0027content_type\u0027: head_seg_resp.content_type,"},{"line_number":1470,"context_line":"                \u0027last_modified\u0027: last_modified_formatted,"},{"line_number":1471,"context_line":"            }"},{"line_number":1472,"context_line":"            if hook:"},{"line_number":1473,"context_line":"                seg_data[\u0027headers\u0027] \u003d HeaderKeyDict(head_seg_resp.headers)"},{"line_number":1474,"context_line":"            if seg_dict.get(\u0027range\u0027):"},{"line_number":1475,"context_line":"                seg_data[\u0027range\u0027] \u003d seg_dict[\u0027range\u0027]"}],"source_content_type":"text/x-python","patch_set":52,"id":"8e1f8c6f_e4a689f4","line":1472,"updated":"2026-09-11 17:54:40.000000000","message":"Do we need to make this conditional on `hook`? The `pop(\u0027headers\u0027, None)` isn\u0027t.","commit_id":"c71ada227565ce0457925e8a0b1cc1e4583a8abd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"07d82293664b02f2e38f2c90cdd23bbad7c0e2f1","unresolved":true,"context_lines":[{"line_number":1469,"context_line":"                \u0027content_type\u0027: head_seg_resp.content_type,"},{"line_number":1470,"context_line":"                \u0027last_modified\u0027: last_modified_formatted,"},{"line_number":1471,"context_line":"            }"},{"line_number":1472,"context_line":"            if hook:"},{"line_number":1473,"context_line":"                seg_data[\u0027headers\u0027] \u003d HeaderKeyDict(head_seg_resp.headers)"},{"line_number":1474,"context_line":"            if seg_dict.get(\u0027range\u0027):"},{"line_number":1475,"context_line":"                seg_data[\u0027range\u0027] \u003d seg_dict[\u0027range\u0027]"}],"source_content_type":"text/x-python","patch_set":52,"id":"1224b60e_08cdca50","line":1472,"in_reply_to":"8e1f8c6f_e4a689f4","updated":"2026-09-14 08:25:20.000000000","message":"blame LLMs for this one - I definitely remember this being an LLM comment that there was potentially a bunch of wasted copies (O(1000) dicts per request).\n\nSmall thing, but the ``if hook`` also serves as a hint to future us as to why the headers get included in the seg_data. So I\u0027m inclined to leave it there.","commit_id":"c71ada227565ce0457925e8a0b1cc1e4583a8abd"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4eb843de863a022bec57d17c20f17d1ae41b1ea4","unresolved":false,"context_lines":[{"line_number":1470,"context_line":"                \u0027last_modified\u0027: last_modified_formatted,"},{"line_number":1471,"context_line":"            }"},{"line_number":1472,"context_line":"            if hook:"},{"line_number":1473,"context_line":"                seg_data[\u0027headers\u0027] \u003d HeaderKeyDict(head_seg_resp.headers)"},{"line_number":1474,"context_line":"            if seg_dict.get(\u0027range\u0027):"},{"line_number":1475,"context_line":"                seg_data[\u0027range\u0027] \u003d seg_dict[\u0027range\u0027]"},{"line_number":1476,"context_line":"            if config_true_value("}],"source_content_type":"text/x-python","patch_set":52,"id":"8369159c_65ab0f6d","line":1473,"range":{"start_line":1473,"start_character":38,"end_line":1473,"end_character":51},"updated":"2026-09-11 17:54:40.000000000","message":"Should [already be a `HeaderKeyDict`](https://github.com/openstack/swift/blob/2.38.1/swift/common/swob.py#L1251), yeah? I guess the copy might still be good, though, in case there are multiple references to the same segment; then if the hook modifies one as it processes, it won\u0027t update the other...","commit_id":"c71ada227565ce0457925e8a0b1cc1e4583a8abd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"07d82293664b02f2e38f2c90cdd23bbad7c0e2f1","unresolved":true,"context_lines":[{"line_number":1470,"context_line":"                \u0027last_modified\u0027: last_modified_formatted,"},{"line_number":1471,"context_line":"            }"},{"line_number":1472,"context_line":"            if hook:"},{"line_number":1473,"context_line":"                seg_data[\u0027headers\u0027] \u003d HeaderKeyDict(head_seg_resp.headers)"},{"line_number":1474,"context_line":"            if seg_dict.get(\u0027range\u0027):"},{"line_number":1475,"context_line":"                seg_data[\u0027range\u0027] \u003d seg_dict[\u0027range\u0027]"},{"line_number":1476,"context_line":"            if config_true_value("}],"source_content_type":"text/x-python","patch_set":52,"id":"60659ed4_e571eb3e","line":1473,"range":{"start_line":1473,"start_character":38,"end_line":1473,"end_character":51},"in_reply_to":"8369159c_65ab0f6d","updated":"2026-09-14 08:25:20.000000000","message":"hmmm, I have a feeling I picked up on this copy in an earlier review. It is defensive coding (although SLO doesn\u0027t care about the headers).","commit_id":"c71ada227565ce0457925e8a0b1cc1e4583a8abd"}],"test/unit/common/middleware/test_slo.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b4e8d74eaa8ef81ac5f045d69dd1eb1adc5ca563","unresolved":true,"context_lines":[{"line_number":1103,"context_line":"        ])"},{"line_number":1104,"context_line":""},{"line_number":1105,"context_line":"    def test_handle_multipart_put_with_validator_callback(self):"},{"line_number":1106,"context_line":"        def complainer(manifest, _segment_head_headers):"},{"line_number":1107,"context_line":"            \"\"\"Return a validation problem for every manifest segment.\"\"\""},{"line_number":1108,"context_line":"            return [(item[\u0027name\u0027], \"Don\u0027t wanna\") for item in manifest]"},{"line_number":1109,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"a631cfb4_9f6b614a","line":1106,"updated":"2026-07-21 18:12:07.000000000","message":"this is the kind of change we can expect out-of-tree callers to have to make - it\u0027s obviously aggregious","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"f77f5d8aa794296a718d2885cf991f8eb42d3e20","unresolved":false,"context_lines":[{"line_number":1103,"context_line":"        ])"},{"line_number":1104,"context_line":""},{"line_number":1105,"context_line":"    def test_handle_multipart_put_with_validator_callback(self):"},{"line_number":1106,"context_line":"        def complainer(manifest, _segment_head_headers):"},{"line_number":1107,"context_line":"            \"\"\"Return a validation problem for every manifest segment.\"\"\""},{"line_number":1108,"context_line":"            return [(item[\u0027name\u0027], \"Don\u0027t wanna\") for item in manifest]"},{"line_number":1109,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"197661af_2e8fc991","line":1106,"in_reply_to":"a631cfb4_9f6b614a","updated":"2026-07-21 22:18:37.000000000","message":"Acknowledged","commit_id":"a363efdae189c94c6a1d7a58845ee7322997be31"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e5f667d222585ec8c00fdb10b51d8a620ab02bc7","unresolved":true,"context_lines":[{"line_number":993,"context_line":"             \u0027X-Object-Sysmeta-S3api-Checksum-Value\u0027: \u0027checksum-b\u0027}, None)"},{"line_number":994,"context_line":"        captured_manifest \u003d []"},{"line_number":995,"context_line":""},{"line_number":996,"context_line":"        def capture_head_headers(manifest):"},{"line_number":997,"context_line":"            \"\"\"Capture the manifest with its transient segment HEAD headers.\"\"\""},{"line_number":998,"context_line":"            captured_manifest.extend("},{"line_number":999,"context_line":"                dict(item) if item is not None else None"}],"source_content_type":"text/x-python","patch_set":22,"id":"7d17a9ce_591acad7","line":996,"updated":"2026-08-07 15:18:45.000000000","message":"nit: it\u0027s actually capturing the whole emanifest","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"3055991eaea288b14ce62b6c4ac5943121ac61e7","unresolved":false,"context_lines":[{"line_number":993,"context_line":"             \u0027X-Object-Sysmeta-S3api-Checksum-Value\u0027: \u0027checksum-b\u0027}, None)"},{"line_number":994,"context_line":"        captured_manifest \u003d []"},{"line_number":995,"context_line":""},{"line_number":996,"context_line":"        def capture_head_headers(manifest):"},{"line_number":997,"context_line":"            \"\"\"Capture the manifest with its transient segment HEAD headers.\"\"\""},{"line_number":998,"context_line":"            captured_manifest.extend("},{"line_number":999,"context_line":"                dict(item) if item is not None else None"}],"source_content_type":"text/x-python","patch_set":22,"id":"4266eaa2_fdaa376c","line":996,"in_reply_to":"7b24bf31_a8911789","updated":"2026-08-19 23:44:40.000000000","message":"Done","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":true,"context_lines":[{"line_number":993,"context_line":"             \u0027X-Object-Sysmeta-S3api-Checksum-Value\u0027: \u0027checksum-b\u0027}, None)"},{"line_number":994,"context_line":"        captured_manifest \u003d []"},{"line_number":995,"context_line":""},{"line_number":996,"context_line":"        def capture_head_headers(manifest):"},{"line_number":997,"context_line":"            \"\"\"Capture the manifest with its transient segment HEAD headers.\"\"\""},{"line_number":998,"context_line":"            captured_manifest.extend("},{"line_number":999,"context_line":"                dict(item) if item is not None else None"}],"source_content_type":"text/x-python","patch_set":22,"id":"7b24bf31_a8911789","line":996,"in_reply_to":"7d17a9ce_591acad7","updated":"2026-08-07 18:33:30.000000000","message":"Yea updating this to `get_manifest` could be better here, `capture_manifest` would be too similar to L994 IMHO","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e5f667d222585ec8c00fdb10b51d8a620ab02bc7","unresolved":true,"context_lines":[{"line_number":1020,"context_line":"        ], [item.get(\u0027name\u0027) for item in captured_manifest])"},{"line_number":1021,"context_line":"        self.assertEqual(["},{"line_number":1022,"context_line":"            \u0027b\u0027, None, \u0027a\u0027, \u0027b\u0027,"},{"line_number":1023,"context_line":"        ], [item.get(\u0027headers\u0027, {}).get(\u0027etag\u0027) if item is not None else None"},{"line_number":1024,"context_line":"            for item in captured_manifest])"},{"line_number":1025,"context_line":"        self.assertEqual(["},{"line_number":1026,"context_line":"            \u0027checksum-b\u0027, None, \u0027checksum-a\u0027, \u0027checksum-b\u0027,"}],"source_content_type":"text/x-python","patch_set":22,"id":"308d2472_adf46965","line":1023,"range":{"start_line":1023,"start_character":48,"end_line":1023,"end_character":77},"updated":"2026-08-07 15:18:45.000000000","message":"if any ``item`` is None then line 1018 will blow up I think? so I think this is unnecessary\n\nsame below","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":true,"context_lines":[{"line_number":1020,"context_line":"        ], [item.get(\u0027name\u0027) for item in captured_manifest])"},{"line_number":1021,"context_line":"        self.assertEqual(["},{"line_number":1022,"context_line":"            \u0027b\u0027, None, \u0027a\u0027, \u0027b\u0027,"},{"line_number":1023,"context_line":"        ], [item.get(\u0027headers\u0027, {}).get(\u0027etag\u0027) if item is not None else None"},{"line_number":1024,"context_line":"            for item in captured_manifest])"},{"line_number":1025,"context_line":"        self.assertEqual(["},{"line_number":1026,"context_line":"            \u0027checksum-b\u0027, None, \u0027checksum-a\u0027, \u0027checksum-b\u0027,"}],"source_content_type":"text/x-python","patch_set":22,"id":"f4a5cb22_d249e9ee","line":1023,"range":{"start_line":1023,"start_character":48,"end_line":1023,"end_character":77},"in_reply_to":"308d2472_adf46965","updated":"2026-08-07 18:33:30.000000000","message":"Yea good catch on this! Thanks! I\u0027ll clean these up","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"3055991eaea288b14ce62b6c4ac5943121ac61e7","unresolved":false,"context_lines":[{"line_number":1020,"context_line":"        ], [item.get(\u0027name\u0027) for item in captured_manifest])"},{"line_number":1021,"context_line":"        self.assertEqual(["},{"line_number":1022,"context_line":"            \u0027b\u0027, None, \u0027a\u0027, \u0027b\u0027,"},{"line_number":1023,"context_line":"        ], [item.get(\u0027headers\u0027, {}).get(\u0027etag\u0027) if item is not None else None"},{"line_number":1024,"context_line":"            for item in captured_manifest])"},{"line_number":1025,"context_line":"        self.assertEqual(["},{"line_number":1026,"context_line":"            \u0027checksum-b\u0027, None, \u0027checksum-a\u0027, \u0027checksum-b\u0027,"}],"source_content_type":"text/x-python","patch_set":22,"id":"6e39c5ed_2737a09d","line":1023,"range":{"start_line":1023,"start_character":48,"end_line":1023,"end_character":77},"in_reply_to":"f4a5cb22_d249e9ee","updated":"2026-08-19 23:44:40.000000000","message":"Done","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e5f667d222585ec8c00fdb10b51d8a620ab02bc7","unresolved":true,"context_lines":[{"line_number":1041,"context_line":"            for item in captured_manifest])"},{"line_number":1042,"context_line":"        self.assertNotIn(\u0027headers\u0027, captured_manifest[1])"},{"line_number":1043,"context_line":"        self.assertIsNot("},{"line_number":1044,"context_line":"            captured_manifest[0][\u0027headers\u0027], captured_manifest[3][\u0027headers\u0027])"},{"line_number":1045,"context_line":"        self.assertEqual(["},{"line_number":1046,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/a_1\u0027),"},{"line_number":1047,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/b_2\u0027),"}],"source_content_type":"text/x-python","patch_set":22,"id":"8635a719_c7b7ae77","line":1044,"updated":"2026-08-07 15:18:45.000000000","message":"these dissected manifest assertions are pretty hard to grok, how about just spelling out what is expected in one go:\n\n```\ndiff --git a/test/unit/common/middleware/test_slo.py b/test/unit/common/middleware/test_slo.py\nindex 4672def75..77bc23611 100644\n--- a/test/unit/common/middleware/test_slo.py\n+++ b/test/unit/common/middleware/test_slo.py\n@@ -20,6 +20,7 @@ import json\n import time\n import unittest\n import string\n+from unittest import mock\n \n from unittest.mock import patch\n \n@@ -979,18 +980,22 @@ class TestSloPutManifest(SloTestCase):\n         self.assertEqual(\u0027b\u0027, manifest_data[1][\u0027hash\u0027])\n \n     def test_handle_multipart_put_callback_receives_head_headers(self):\n+        headers1 \u003d {\u0027Content-Length\u0027: \u00271\u0027, \u0027Etag\u0027: \u0027a\u0027,\n+                    \u0027Content-Type\u0027: \u0027text/html; charset\u003dUTF-8\u0027,\n+                    \u0027X-Object-Meta-Hook-Test\u0027: \u0027hook-a\u0027,\n+                    \u0027X-Object-Sysmeta-S3Api-Checksum-Upload-Id\u0027: \u0027upload-a\u0027,\n+                    \u0027X-Object-Sysmeta-S3Api-Checksum-Value\u0027: \u0027checksum-a\u0027}\n         self.app.register(\n             \u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/a_1\u0027, swob.HTTPOk,\n-            {\u0027Content-Length\u0027: \u00271\u0027, \u0027Etag\u0027: \u0027a\u0027,\n-             \u0027X-Object-Meta-Hook-Test\u0027: \u0027hook-a\u0027,\n-             \u0027X-Object-Sysmeta-S3api-Checksum-Upload-Id\u0027: \u0027upload-a\u0027,\n-             \u0027X-Object-Sysmeta-S3api-Checksum-Value\u0027: \u0027checksum-a\u0027}, None)\n+            dict(headers1), None)\n+        headers2 \u003d {\u0027Content-Length\u0027: \u00272\u0027, \u0027Etag\u0027: \u0027b\u0027,\n+                    \u0027Content-Type\u0027: \u0027text/html; charset\u003dUTF-8\u0027,\n+                    \u0027X-Object-Meta-Hook-Test\u0027: \u0027hook-b\u0027,\n+                    \u0027X-Object-Sysmeta-S3Api-Checksum-Upload-Id\u0027: \u0027upload-b\u0027,\n+                    \u0027X-Object-Sysmeta-S3Api-Checksum-Value\u0027: \u0027checksum-b\u0027}\n         self.app.register(\n             \u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/b_2\u0027, swob.HTTPOk,\n-            {\u0027Content-Length\u0027: \u00272\u0027, \u0027Etag\u0027: \u0027b\u0027,\n-             \u0027X-Object-Meta-Hook-Test\u0027: \u0027hook-b\u0027,\n-             \u0027X-Object-Sysmeta-S3api-Checksum-Upload-Id\u0027: \u0027upload-b\u0027,\n-             \u0027X-Object-Sysmeta-S3api-Checksum-Value\u0027: \u0027checksum-b\u0027}, None)\n+            dict(headers2), None)\n         captured_manifest \u003d []\n \n         def capture_head_headers(manifest):\n@@ -1015,33 +1020,28 @@ class TestSloPutManifest(SloTestCase):\n         status, headers, body \u003d self.call_slo(req)\n \n         self.assertEqual((\u0027201 Created\u0027, b\u0027\u0027), (status, body))\n-        self.assertEqual([\n-            \u0027/checktest/b_2\u0027, None, \u0027/checktest/a_1\u0027, \u0027/checktest/b_2\u0027,\n-        ], [item.get(\u0027name\u0027) for item in captured_manifest])\n-        self.assertEqual([\n-            \u0027b\u0027, None, \u0027a\u0027, \u0027b\u0027,\n-        ], [item.get(\u0027headers\u0027, {}).get(\u0027etag\u0027) if item is not None else None\n-            for item in captured_manifest])\n-        self.assertEqual([\n-            \u0027checksum-b\u0027, None, \u0027checksum-a\u0027, \u0027checksum-b\u0027,\n-        ], [item.get(\u0027headers\u0027, {}).get(\n-            \u0027x-object-sysmeta-s3api-checksum-value\u0027)\n-            if item is not None else None\n-            for item in captured_manifest])\n-        self.assertEqual([\n-            \u0027upload-b\u0027, None, \u0027upload-a\u0027, \u0027upload-b\u0027,\n-        ], [item.get(\u0027headers\u0027, {}).get(\n-            \u0027x-object-sysmeta-s3api-checksum-upload-id\u0027)\n-            if item is not None else None\n-            for item in captured_manifest])\n-        self.assertEqual([\n-            \u0027hook-b\u0027, None, \u0027hook-a\u0027, \u0027hook-b\u0027,\n-        ], [item.get(\u0027headers\u0027, {}).get(\u0027x-object-meta-hook-test\u0027)\n-            if item is not None else None\n-            for item in captured_manifest])\n-        self.assertNotIn(\u0027headers\u0027, captured_manifest[1])\n-        self.assertIsNot(\n-            captured_manifest[0][\u0027headers\u0027], captured_manifest[3][\u0027headers\u0027])\n+        self.assertEqual([{\u0027bytes\u0027: 2,\n+                           \u0027content_type\u0027: \u0027text/html\u0027,\n+                           \u0027last_modified\u0027: mock.ANY,\n+                           \u0027hash\u0027: \u0027b\u0027,\n+                           \u0027name\u0027: \u0027/checktest/b_2\u0027,\n+                           \u0027headers\u0027: headers2},\n+                          {\u0027data\u0027: \u0027WA\u003d\u003d\u0027},\n+                          {\u0027bytes\u0027: 1,\n+                           \u0027content_type\u0027: \u0027text/html\u0027,\n+                           \u0027last_modified\u0027: mock.ANY,\n+                           \u0027hash\u0027: \u0027a\u0027,\n+                           \u0027name\u0027: \u0027/checktest/a_1\u0027,\n+                           \u0027headers\u0027: headers1,},\n+                          {\u0027bytes\u0027: 2,\n+                           \u0027content_type\u0027: \u0027text/html\u0027,\n+                           \u0027last_modified\u0027: mock.ANY,\n+                           \u0027hash\u0027: \u0027b\u0027,\n+                           \u0027name\u0027: \u0027/checktest/b_2\u0027,\n+                           \u0027headers\u0027: headers2,},\n+                          ],\n+                         captured_manifest)\n+\n         self.assertEqual([\n             (\u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/a_1\u0027),\n             (\u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/b_2\u0027),\n```","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"0d4e9153005b8f062a6ce0a5caa606fa84e460ba","unresolved":true,"context_lines":[{"line_number":1041,"context_line":"            for item in captured_manifest])"},{"line_number":1042,"context_line":"        self.assertNotIn(\u0027headers\u0027, captured_manifest[1])"},{"line_number":1043,"context_line":"        self.assertIsNot("},{"line_number":1044,"context_line":"            captured_manifest[0][\u0027headers\u0027], captured_manifest[3][\u0027headers\u0027])"},{"line_number":1045,"context_line":"        self.assertEqual(["},{"line_number":1046,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/a_1\u0027),"},{"line_number":1047,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/b_2\u0027),"}],"source_content_type":"text/x-python","patch_set":22,"id":"c59c9427_fd9db23b","line":1044,"in_reply_to":"8635a719_c7b7ae77","updated":"2026-08-07 18:33:30.000000000","message":"Yes I think these are better, thank you so much! much clearer too from a reviewer perspective","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"3055991eaea288b14ce62b6c4ac5943121ac61e7","unresolved":false,"context_lines":[{"line_number":1041,"context_line":"            for item in captured_manifest])"},{"line_number":1042,"context_line":"        self.assertNotIn(\u0027headers\u0027, captured_manifest[1])"},{"line_number":1043,"context_line":"        self.assertIsNot("},{"line_number":1044,"context_line":"            captured_manifest[0][\u0027headers\u0027], captured_manifest[3][\u0027headers\u0027])"},{"line_number":1045,"context_line":"        self.assertEqual(["},{"line_number":1046,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/a_1\u0027),"},{"line_number":1047,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/checktest/b_2\u0027),"}],"source_content_type":"text/x-python","patch_set":22,"id":"f29e012d_e9ffdf22","line":1044,"in_reply_to":"c59c9427_fd9db23b","updated":"2026-08-19 23:44:40.000000000","message":"Done","commit_id":"3d306cbf558658121dc8c828a3f8101e41658074"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"65e2dc7d665ca654fe6cd549d27dc213063eb51c","unresolved":false,"context_lines":[{"line_number":999,"context_line":"        captured_manifest \u003d []"},{"line_number":1000,"context_line":""},{"line_number":1001,"context_line":"        def get_manifest(manifest):"},{"line_number":1002,"context_line":"            \"\"\"Capture the manifest with its validation-only segment HEAD headers.\"\"\""},{"line_number":1003,"context_line":"            captured_manifest.extend("},{"line_number":1004,"context_line":"                dict(item) if item is not None else None"},{"line_number":1005,"context_line":"                for item in manifest)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3b2b710b_367729e2","line":1002,"updated":"2026-08-07 19:45:54.000000000","message":"pep8: E501 line too long (85 \u003e 79 characters)","commit_id":"37ccf9a8cb5da449e649d65feec6a7a1535356fd"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4eb843de863a022bec57d17c20f17d1ae41b1ea4","unresolved":false,"context_lines":[{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"    def test_handle_multipart_put_with_manipulator_callback(self):"},{"line_number":1152,"context_line":"        def data_inserter(manifest):"},{"line_number":1153,"context_line":"            \"\"\"Insert inline data before, between, and after the segments.\"\"\""},{"line_number":1154,"context_line":"            for i in range(len(manifest), -1, -1):"},{"line_number":1155,"context_line":"                manifest.insert(i, {\u0027data\u0027: \u0027WA\u003d\u003d\u0027})"},{"line_number":1156,"context_line":""}],"source_content_type":"text/x-python","patch_set":52,"id":"4bf88e53_36a5da9d","line":1153,"updated":"2026-09-11 17:54:40.000000000","message":"Poor, poor [TLO](https://review.opendev.org/c/openstack/swift/+/499260)","commit_id":"c71ada227565ce0457925e8a0b1cc1e4583a8abd"}]}
