)]}'
{"/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":"nmartes@NVIDIA.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"}],"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":"nmartes@NVIDIA.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":"nmartes@NVIDIA.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":"nmartes@NVIDIA.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"}],"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":"nmartes@NVIDIA.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"}]}
