)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cfb938baf051e96fd0af6be173c4fa91943737ce","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"775ad1bb_fd4a8a46","updated":"2026-08-13 18:49:19.000000000","message":"There is some issues with the order in which we throw errors... I\u0027ll add some tests to this and fix","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f96f89479f1a841be32a55b54c688df7228914ca","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"24e8f3a1_bda0cd4f","updated":"2026-08-14 14:40:47.000000000","message":"ok so the error precedence is *weird* but we have to be compat.\n\npatch set 6 tries to make the weirdness more \"obvious\"\n\nAlso, calculate the final checksum as we go using pluggable checksum hasher classes","commit_id":"64ec178fb6439b9f98b3e8e0d35d68f843cd9a7e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fef59056b3efe0c64b88fb31fdd4e4292528e01b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"aa0235fd_6fcf8cc2","updated":"2026-08-14 18:36:49.000000000","message":"@Nate FWIW this is Claude\u0027s review *on my last patchset* - you may have already fixed.\n\n```\n Code review(review · 5 findings)\nswift/common/middleware/s3api/controllers/multi_upload.py\n  ●  342 [correctness]   The final-checksum (BadDigest) comparison can run against an incomplete/corrupt hasher digest when a per-part checksum error occurred earlier in the loop.\n  ●  431 [readability]   _FullObjectChecksumHasher\u0027s docstring still documents the old free-function signature (part_checksums param, return value) instead of the new stateful update()/base64digest() interface.\n  ●   91 [best-practice] _FullObjectChecksumHasher.update uses `bytes` as a parameter name, shadowing the builtin type within the method body.\n  ●   58 [readability]   Continuation-line indentation in _CompositeChecksumHasher.base64digest is one column short of aligning under the opening parenthesis.\n  ● 1503 [test-coverage] No test found that exercises BadDigest-vs-InvalidPart precedence when both a completion-time checksum header and a per-part checksum mismatch are present in the same request.\n\nReview of commit 64ec178fb (\"sq? make mpu manifest hook cache errors\") is done. Key takeaway:\n\nMajor (correctness): In _validate_parts (multi_upload.py), when a part fails checksum validation (InvalidPart), the loop skips hasher.update() for that part and continues — but the final BadDigest comparison guard only excludes missing_part_checksum, not checksum_error. So if a client supplies a completion-time x-amz-checksum-* header and a part also has a bad checksum, the code computes hasher.base64digest() from a digest that\u0027s missing that part\u0027s contribution and raises the misleading BadDigest instead of InvalidPart. Fix is one line: also exclude checksum_error from that guard.\n\nAlso flagged: a stale docstring on _FullObjectChecksumHasher, a bytes parameter shadowing the builtin, a pep8 continuation-line misalignment, and a missing test covering the BadDigest/InvalidPart precedence combo that would have caught the major issue\n```","commit_id":"c0cec353f95db6b9853d892bb24374a70e5612c2"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"1d764c92e6239b2040c52ebaa1f1887657759456","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"97380cf0_172a3683","in_reply_to":"aa0235fd_6fcf8cc2","updated":"2026-08-14 19:59:17.000000000","message":"Oh I see, I did NOT fix, I pushed up a new patch with a unit test to fix this case, thanks!","commit_id":"c0cec353f95db6b9853d892bb24374a70e5612c2"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"ed5a4276f7f840aaf4fa9e09425b90d6b25154db","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"1e70de68_498a03fb","updated":"2026-08-14 21:59:14.000000000","message":"I think this is good to squash in now, we are adding a good amount of test cases with this new coverage so we are bringing this closer to getting merged!","commit_id":"2eb8c7f18db63c8030245d7ca5057290deb7e851"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4215f27ad397ce81373224d8ae38e56ffaaf45fd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"0621e471_10d66d34","updated":"2026-08-14 23:27:00.000000000","message":"Squashed in 993193: s3api: Checksum Persistence on MPUs | https://review.opendev.org/c/openstack/swift/+/993193/96\n\nThanks for the work on this @alistairncoles@gmail.com ☺️\nThe diff is +7K 😬 im sure there is some room for cleaning of tests","commit_id":"2eb8c7f18db63c8030245d7ca5057290deb7e851"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cd34d9cc2b305c45262eb0e460c740173b3da992","unresolved":false,"context_lines":[{"line_number":572,"context_line":"            request_checksum_attrs, part_checksums):"},{"line_number":573,"context_line":"        \"\"\"Capture the request-local multipart completion state.\"\"\""},{"line_number":574,"context_line":"        self.min_segment_size \u003d min_segment_size"},{"line_number":575,"context_line":"        self.too_small_message \u003d \\"},{"line_number":576,"context_line":"            \u0027s3api requires that each segment be at least %d bytes\u0027 % \\"},{"line_number":577,"context_line":"            min_segment_size"},{"line_number":578,"context_line":"        self.upload_id \u003d upload_id"}],"source_content_type":"text/x-python","patch_set":1,"id":"d90c0d57_f5688ed1","side":"PARENT","line":575,"range":{"start_line":575,"start_character":0,"end_line":575,"end_character":34},"updated":"2026-08-13 15:46:24.000000000","message":"Yea this is pretty constant so I think its fine if we move this out","commit_id":"1734fb8c60562d4f346cb4fb38612206211c46fe"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cd34d9cc2b305c45262eb0e460c740173b3da992","unresolved":false,"context_lines":[{"line_number":588,"context_line":""},{"line_number":589,"context_line":"    def _validate_checksum_segment_head_headers("},{"line_number":590,"context_line":"            self, segment_head_headers):"},{"line_number":591,"context_line":"        \"\"\"Validate a stored segment checksum.\"\"\""},{"line_number":592,"context_line":"        stored_checksum_value \u003d segment_head_headers.get("},{"line_number":593,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-value\u0027))"},{"line_number":594,"context_line":"        stored_checksum_upload_id \u003d segment_head_headers.get("}],"source_content_type":"text/x-python","patch_set":1,"id":"0dc4b8cf_0c970ff2","line":591,"range":{"start_line":591,"start_character":0,"end_line":591,"end_character":49},"updated":"2026-08-13 15:46:24.000000000","message":"I think this is better, seperating validation and data structure manipulation","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cd34d9cc2b305c45262eb0e460c740173b3da992","unresolved":false,"context_lines":[{"line_number":615,"context_line":"            raise InvalidPart("},{"line_number":616,"context_line":"                upload_id\u003dself.upload_id,"},{"line_number":617,"context_line":"                part_number\u003dpart_checksum[\u0027part_number\u0027])"},{"line_number":618,"context_line":"        return stored_checksum_value"},{"line_number":619,"context_line":""},{"line_number":620,"context_line":"    def _validate_segments(self, manifest):"},{"line_number":621,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"410c1fbf_ba40d60d","line":618,"range":{"start_line":618,"start_character":0,"end_line":618,"end_character":36},"updated":"2026-08-13 15:46:24.000000000","message":"Good call here too, seperating concerns","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cfb938baf051e96fd0af6be173c4fa91943737ce","unresolved":true,"context_lines":[{"line_number":638,"context_line":"                # looking at the manifest that\u0027s about to be written."},{"line_number":639,"context_line":"                if (index \u003c len(manifest) - 1 and"},{"line_number":640,"context_line":"                        manifest_item[\u0027bytes\u0027] \u003c self.min_segment_size):"},{"line_number":641,"context_line":"                    self._errors.append("},{"line_number":642,"context_line":"                        EntityTooSmall("},{"line_number":643,"context_line":"                            \u0027s3api requires that each segment be at least \u0027"},{"line_number":644,"context_line":"                            \u0027%d bytes\u0027 % self.min_segment_size))"}],"source_content_type":"text/x-python","patch_set":1,"id":"cd5e8919_266c1cbc","line":641,"range":{"start_line":641,"start_character":0,"end_line":641,"end_character":40},"updated":"2026-08-13 18:49:19.000000000","message":"Might be good to move this to the last error... see below","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":638,"context_line":"                # looking at the manifest that\u0027s about to be written."},{"line_number":639,"context_line":"                if (index \u003c len(manifest) - 1 and"},{"line_number":640,"context_line":"                        manifest_item[\u0027bytes\u0027] \u003c self.min_segment_size):"},{"line_number":641,"context_line":"                    self._errors.append("},{"line_number":642,"context_line":"                        EntityTooSmall("},{"line_number":643,"context_line":"                            \u0027s3api requires that each segment be at least \u0027"},{"line_number":644,"context_line":"                            \u0027%d bytes\u0027 % self.min_segment_size))"}],"source_content_type":"text/x-python","patch_set":1,"id":"b4c1c7fd_395028b7","line":641,"range":{"start_line":641,"start_character":0,"end_line":641,"end_character":40},"in_reply_to":"cd5e8919_266c1cbc","updated":"2026-08-14 17:47:31.000000000","message":"Acknowledged","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cd34d9cc2b305c45262eb0e460c740173b3da992","unresolved":false,"context_lines":[{"line_number":673,"context_line":"                # response status in the SLO response body, and then the mpu"},{"line_number":674,"context_line":"                # complete response iter can use this stash of errors to"},{"line_number":675,"context_line":"                # rewrite the error response body."},{"line_number":676,"context_line":"                self._errors.append(err)"},{"line_number":677,"context_line":""},{"line_number":678,"context_line":"        return failed_segment"},{"line_number":679,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"6e1c9641_eb4b0cb5","line":676,"range":{"start_line":676,"start_character":0,"end_line":676,"end_character":40},"updated":"2026-08-13 15:46:24.000000000","message":"+1 to the comment","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cfb938baf051e96fd0af6be173c4fa91943737ce","unresolved":true,"context_lines":[{"line_number":673,"context_line":"                # response status in the SLO response body, and then the mpu"},{"line_number":674,"context_line":"                # complete response iter can use this stash of errors to"},{"line_number":675,"context_line":"                # rewrite the error response body."},{"line_number":676,"context_line":"                self._errors.append(err)"},{"line_number":677,"context_line":""},{"line_number":678,"context_line":"        return failed_segment"},{"line_number":679,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"6f93c26b_1927f209","line":676,"range":{"start_line":676,"start_character":0,"end_line":676,"end_character":40},"updated":"2026-08-13 18:49:19.000000000","message":"You know if we only care about the FIRST error... then it might be good to bail out of this function too once we find one...\n\nPerhaps even better why don\u0027t we just have `_validate_segments` raise an exception and catch it in `__call__` and whatever said exception is, translate it into a error segment?\n\nKinda:\n```\ntry:\n  self._validate_segments(manifest)\nexcept ErrorResponse as err:\n  self._errors.append(err)\n  return [(self.upload_id, self.ERROR_MESSAGE)]\n```\n\nOr if `self._errors` does not have to be a list\n```\ntry:\n  self._validate_segments(manifest)\nexcept ErrorResponse as err:\n  self._error \u003d err\n  return [(self.upload_id, self.ERROR_MESSAGE)]\n```","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":673,"context_line":"                # response status in the SLO response body, and then the mpu"},{"line_number":674,"context_line":"                # complete response iter can use this stash of errors to"},{"line_number":675,"context_line":"                # rewrite the error response body."},{"line_number":676,"context_line":"                self._errors.append(err)"},{"line_number":677,"context_line":""},{"line_number":678,"context_line":"        return failed_segment"},{"line_number":679,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"b0b60cc6_97a1ea33","line":676,"range":{"start_line":676,"start_character":0,"end_line":676,"end_character":40},"in_reply_to":"6f93c26b_1927f209","updated":"2026-08-14 17:47:31.000000000","message":"Raised in 1000863: WIP s3api: add multi_upload manifest hook callback class | https://review.opendev.org/c/openstack/swift/+/1000863 too...","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cfb938baf051e96fd0af6be173c4fa91943737ce","unresolved":true,"context_lines":[{"line_number":708,"context_line":"            # body"},{"line_number":709,"context_line":"            return [(self.upload_id, self.ERROR_MESSAGE)]"},{"line_number":710,"context_line":""},{"line_number":711,"context_line":"        if (self.missing_checksum_metadata or failed_segment or"},{"line_number":712,"context_line":"                not self.mpu_checksum_attrs.is_checksum_aware):"},{"line_number":713,"context_line":"            self.final_checksum_value \u003d None"},{"line_number":714,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"91646217_5a79b4b0","line":711,"range":{"start_line":711,"start_character":0,"end_line":711,"end_character":63},"updated":"2026-08-13 18:49:19.000000000","message":"Since we might have errors AND parts with missing checksums this might not be ideal...\n\nFor instance say we have:\n\n```\nServer:\nPart A Data: { }\nPart B Data: { checksum-upload-id: foo, checksum-crc32: good }\n```\n```\nClient:\nPart A Data: { }\nPart B Data: {checksum-crc32, bad}\n```\n\nSince we go through all the segments before falling back, we can encounter a part without checksum metadata, `Part A`, and then we go to check the next segment `Part B` and it has checksum metadata that is valid but what the client gave us doesn\u0027t match. \n\nThat is a checksum error which is good that we caught it, but `Part A` could have only been uploaded via an old proxy, and as we established, if old proxies interfere with MPU, then we have to fallback. Right now we would not fallback and instead error. This is OUR bad since we put a part into the MPU with no checksum and did not fallback.\n\nWe also have ANOTHER edge case if we have parts that are too small and invalid checksum metadata. If we have invalid server checksum metadata, we have to drop raising any checksum errors. If all the part\u0027s checksum meta is good, then we need to raise any checksum errors FIRST, before saying \u0027hey the parts sizes are no good\u0027\n\nI wrote a compat test for this:\n```\nAWS Says:\ntest_complete_composite_too_small_part_with_bad_request_checksum PASSED [100%]\n```\n```\nSwift Says:\nFAILED ... AssertionError: \u0027InvalidPart\u0027 !\u003d \u0027EntityTooSmall\u0027\n```\n\nSo we need to enforce the checksum metadata FIRST, then the part sizes","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":708,"context_line":"            # body"},{"line_number":709,"context_line":"            return [(self.upload_id, self.ERROR_MESSAGE)]"},{"line_number":710,"context_line":""},{"line_number":711,"context_line":"        if (self.missing_checksum_metadata or failed_segment or"},{"line_number":712,"context_line":"                not self.mpu_checksum_attrs.is_checksum_aware):"},{"line_number":713,"context_line":"            self.final_checksum_value \u003d None"},{"line_number":714,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"2f33f92c_25868630","line":711,"range":{"start_line":711,"start_character":0,"end_line":711,"end_character":63},"in_reply_to":"3f6d7f84_0f5d8c6b","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"d5efb234c83303714705f6c23006dfb1cc3e248d","unresolved":true,"context_lines":[{"line_number":708,"context_line":"            # body"},{"line_number":709,"context_line":"            return [(self.upload_id, self.ERROR_MESSAGE)]"},{"line_number":710,"context_line":""},{"line_number":711,"context_line":"        if (self.missing_checksum_metadata or failed_segment or"},{"line_number":712,"context_line":"                not self.mpu_checksum_attrs.is_checksum_aware):"},{"line_number":713,"context_line":"            self.final_checksum_value \u003d None"},{"line_number":714,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f6d7f84_0f5d8c6b","line":711,"range":{"start_line":711,"start_character":0,"end_line":711,"end_character":63},"in_reply_to":"91646217_5a79b4b0","updated":"2026-08-13 19:18:51.000000000","message":"\u003e That is a checksum error which is good that we caught it, but Part A could have only been uploaded via an old proxy, and as we established, if old proxies interfere with MPU, then we have to fallback. Right now we would not fallback and instead error. This is OUR bad since we put a part into the MPU with no checksum and did not fallback.\n\nCORRECTION: actually since `Part B` was uploaded via a new proxy, its alright to validate what the request gave us... this is just false","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cfb938baf051e96fd0af6be173c4fa91943737ce","unresolved":true,"context_lines":[{"line_number":1485,"context_line":"                        elif body[\u0027Response Status\u0027] !\u003d \u0027201 Created\u0027:"},{"line_number":1486,"context_line":"                            for seg, err in body[\u0027Errors\u0027]:"},{"line_number":1487,"context_line":"                                if err \u003d\u003d manifest_hook.ERROR_MESSAGE:"},{"line_number":1488,"context_line":"                                    raise manifest_hook.errors[0]"},{"line_number":1489,"context_line":"                                elif err in (\u0027Etag Mismatch\u0027, \u0027404 Not Found\u0027):"},{"line_number":1490,"context_line":"                                    raise InvalidPart(upload_id\u003dupload_id)"},{"line_number":1491,"context_line":"                            raise InvalidRequest("}],"source_content_type":"text/x-python","patch_set":1,"id":"8db0e748_38acc8b5","line":1488,"range":{"start_line":1488,"start_character":42,"end_line":1488,"end_character":65},"updated":"2026-08-13 18:49:19.000000000","message":"Maybe we don\u0027t need a list for the manifest hook\u0027s errors, since we only care about 1, once we find said error, just write it down in the hook, and return with the static hook problem segment error message","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":true,"context_lines":[{"line_number":1485,"context_line":"                        elif body[\u0027Response Status\u0027] !\u003d \u0027201 Created\u0027:"},{"line_number":1486,"context_line":"                            for seg, err in body[\u0027Errors\u0027]:"},{"line_number":1487,"context_line":"                                if err \u003d\u003d manifest_hook.ERROR_MESSAGE:"},{"line_number":1488,"context_line":"                                    raise manifest_hook.errors[0]"},{"line_number":1489,"context_line":"                                elif err in (\u0027Etag Mismatch\u0027, \u0027404 Not Found\u0027):"},{"line_number":1490,"context_line":"                                    raise InvalidPart(upload_id\u003dupload_id)"},{"line_number":1491,"context_line":"                            raise InvalidRequest("}],"source_content_type":"text/x-python","patch_set":1,"id":"3956d39c_a34e2169","line":1488,"range":{"start_line":1488,"start_character":42,"end_line":1488,"end_character":65},"in_reply_to":"8db0e748_38acc8b5","updated":"2026-08-14 17:47:31.000000000","message":"I raised this question in the original patch 1000863: WIP s3api: add multi_upload manifest hook callback class | https://review.opendev.org/c/openstack/swift/+/1000863 so I\u0027ll just leave this unresolved here too...","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cd34d9cc2b305c45262eb0e460c740173b3da992","unresolved":false,"context_lines":[{"line_number":1517,"context_line":"                yield _make_complete_body("},{"line_number":1518,"context_line":"                    req, s3_etag, yielded_anything,"},{"line_number":1519,"context_line":"                    mpu_checksum_attrs.checksum_header,"},{"line_number":1520,"context_line":"                    manifest_hook.final_checksum_value,"},{"line_number":1521,"context_line":"                    mpu_checksum_attrs.checksum_type)"},{"line_number":1522,"context_line":"            except ErrorResponse as err_resp:"},{"line_number":1523,"context_line":"                if yielded_anything:"}],"source_content_type":"text/x-python","patch_set":1,"id":"bd9baccf_25ba8673","line":1520,"range":{"start_line":1520,"start_character":0,"end_line":1520,"end_character":55},"updated":"2026-08-13 15:46:24.000000000","message":"Yea the value is what really may change, so best to get it from one place","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"018326efb090a777c725a9a195fc21cb14334b71","unresolved":true,"context_lines":[{"line_number":601,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-upload-id\u0027))"},{"line_number":602,"context_line":"        if stored_checksum_upload_id !\u003d self.upload_id:"},{"line_number":603,"context_line":"            # An old proxy may upload a part without the upload-id"},{"line_number":604,"context_line":"            # sentinel. Fall back to completing without a checksum."},{"line_number":605,"context_line":"            return None"},{"line_number":606,"context_line":"        return stored_checksum_value"},{"line_number":607,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"695b9c8a_cf1dfd77","line":604,"updated":"2026-08-14 13:28:38.000000000","message":"but an old proxy wouldn\u0027t persist the checksum value either??\n\nis this to do with part-copy: the copy will indiscriminately copy all sysmeta even if it is a ranged copy, but the upload-id won\u0027t match *this* mpu?","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":601,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-upload-id\u0027))"},{"line_number":602,"context_line":"        if stored_checksum_upload_id !\u003d self.upload_id:"},{"line_number":603,"context_line":"            # An old proxy may upload a part without the upload-id"},{"line_number":604,"context_line":"            # sentinel. Fall back to completing without a checksum."},{"line_number":605,"context_line":"            return None"},{"line_number":606,"context_line":"        return stored_checksum_value"},{"line_number":607,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"533a07f0_ff7894c5","line":604,"in_reply_to":"695b9c8a_cf1dfd77","updated":"2026-08-14 17:47:31.000000000","message":"Yep thats right! The upload-id is only added via a new proxy who can validate the sysmeta. I think it could be good to update this to note that the header may also not be present if the new proxy does not like the checksum meta","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"018326efb090a777c725a9a195fc21cb14334b71","unresolved":true,"context_lines":[{"line_number":607,"context_line":""},{"line_number":608,"context_line":"    def _validate_part_checksum_metadata(self, part_checksum):"},{"line_number":609,"context_line":"        \"\"\"Validate and return the raw checksum for a completed part.\"\"\""},{"line_number":610,"context_line":"        manifest_checksum_value \u003d part_checksum[\u0027manifest_checksum_value\u0027]"},{"line_number":611,"context_line":"        stored_checksum_value \u003d part_checksum[\u0027stored_checksum_value\u0027]"},{"line_number":612,"context_line":""},{"line_number":613,"context_line":"        # FULL_OBJECT completion may omit client-provided per-part"}],"source_content_type":"text/x-python","patch_set":5,"id":"d9836cff_b6be3b5a","line":610,"range":{"start_line":610,"start_character":8,"end_line":610,"end_character":16},"updated":"2026-08-14 13:28:38.000000000","message":"this refers to the request manifest","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":607,"context_line":""},{"line_number":608,"context_line":"    def _validate_part_checksum_metadata(self, part_checksum):"},{"line_number":609,"context_line":"        \"\"\"Validate and return the raw checksum for a completed part.\"\"\""},{"line_number":610,"context_line":"        manifest_checksum_value \u003d part_checksum[\u0027manifest_checksum_value\u0027]"},{"line_number":611,"context_line":"        stored_checksum_value \u003d part_checksum[\u0027stored_checksum_value\u0027]"},{"line_number":612,"context_line":""},{"line_number":613,"context_line":"        # FULL_OBJECT completion may omit client-provided per-part"}],"source_content_type":"text/x-python","patch_set":5,"id":"6205049c_809065f8","line":610,"range":{"start_line":610,"start_character":8,"end_line":610,"end_character":16},"in_reply_to":"321e5439_69444eca","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"1553c13185ab37e9dbf3bb7fdd0368d5fd8e851c","unresolved":true,"context_lines":[{"line_number":607,"context_line":""},{"line_number":608,"context_line":"    def _validate_part_checksum_metadata(self, part_checksum):"},{"line_number":609,"context_line":"        \"\"\"Validate and return the raw checksum for a completed part.\"\"\""},{"line_number":610,"context_line":"        manifest_checksum_value \u003d part_checksum[\u0027manifest_checksum_value\u0027]"},{"line_number":611,"context_line":"        stored_checksum_value \u003d part_checksum[\u0027stored_checksum_value\u0027]"},{"line_number":612,"context_line":""},{"line_number":613,"context_line":"        # FULL_OBJECT completion may omit client-provided per-part"}],"source_content_type":"text/x-python","patch_set":5,"id":"321e5439_69444eca","line":610,"range":{"start_line":610,"start_character":8,"end_line":610,"end_character":16},"in_reply_to":"d9836cff_b6be3b5a","updated":"2026-08-14 17:42:45.000000000","message":"Yes I think we should make this distinction along with make \u0027manifest_checksum_value\u0027 be \u0027req_manifest_checksum_value\u0027","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"018326efb090a777c725a9a195fc21cb14334b71","unresolved":true,"context_lines":[{"line_number":623,"context_line":"                part_number\u003dpart_checksum[\u0027part_number\u0027])"},{"line_number":624,"context_line":"        return stored_checksum_value"},{"line_number":625,"context_line":""},{"line_number":626,"context_line":"    def _validate_segments(self, manifest):"},{"line_number":627,"context_line":"        \"\"\""},{"line_number":628,"context_line":"        Validate all manifest segments in S3 error-precedence order."},{"line_number":629,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"ddc449ae_b50258f0","line":626,"range":{"start_line":626,"start_character":18,"end_line":626,"end_character":26},"updated":"2026-08-14 13:28:38.000000000","message":"in the context of s3api let\u0027s always refer to ``parts``\n\nfor historical reasons we do have some language confusion between parts and segments: SLO has segments, s3api MPUs have parts that are stored as SLO segments","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"018326efb090a777c725a9a195fc21cb14334b71","unresolved":true,"context_lines":[{"line_number":623,"context_line":"                part_number\u003dpart_checksum[\u0027part_number\u0027])"},{"line_number":624,"context_line":"        return stored_checksum_value"},{"line_number":625,"context_line":""},{"line_number":626,"context_line":"    def _validate_segments(self, manifest):"},{"line_number":627,"context_line":"        \"\"\""},{"line_number":628,"context_line":"        Validate all manifest segments in S3 error-precedence order."},{"line_number":629,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"fa944b6d_70fd6e8d","line":626,"range":{"start_line":626,"start_character":33,"end_line":626,"end_character":41},"updated":"2026-08-14 13:28:38.000000000","message":"this refers to the slo manifest\n\nwe need better clarity of which manifest is which, perhaps:\n\n``slo_manifest`` and ``req_manifest``","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":623,"context_line":"                part_number\u003dpart_checksum[\u0027part_number\u0027])"},{"line_number":624,"context_line":"        return stored_checksum_value"},{"line_number":625,"context_line":""},{"line_number":626,"context_line":"    def _validate_segments(self, manifest):"},{"line_number":627,"context_line":"        \"\"\""},{"line_number":628,"context_line":"        Validate all manifest segments in S3 error-precedence order."},{"line_number":629,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"37450518_52fe8569","line":626,"range":{"start_line":626,"start_character":18,"end_line":626,"end_character":26},"in_reply_to":"58c4a595_c5dab2e0","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":623,"context_line":"                part_number\u003dpart_checksum[\u0027part_number\u0027])"},{"line_number":624,"context_line":"        return stored_checksum_value"},{"line_number":625,"context_line":""},{"line_number":626,"context_line":"    def _validate_segments(self, manifest):"},{"line_number":627,"context_line":"        \"\"\""},{"line_number":628,"context_line":"        Validate all manifest segments in S3 error-precedence order."},{"line_number":629,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"dd7d7811_2e096ae6","line":626,"range":{"start_line":626,"start_character":33,"end_line":626,"end_character":41},"in_reply_to":"94bf3753_5b2bb287","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"1553c13185ab37e9dbf3bb7fdd0368d5fd8e851c","unresolved":true,"context_lines":[{"line_number":623,"context_line":"                part_number\u003dpart_checksum[\u0027part_number\u0027])"},{"line_number":624,"context_line":"        return stored_checksum_value"},{"line_number":625,"context_line":""},{"line_number":626,"context_line":"    def _validate_segments(self, manifest):"},{"line_number":627,"context_line":"        \"\"\""},{"line_number":628,"context_line":"        Validate all manifest segments in S3 error-precedence order."},{"line_number":629,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"58c4a595_c5dab2e0","line":626,"range":{"start_line":626,"start_character":18,"end_line":626,"end_character":26},"in_reply_to":"ddc449ae_b50258f0","updated":"2026-08-14 17:42:45.000000000","message":"I think this works better too","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"1553c13185ab37e9dbf3bb7fdd0368d5fd8e851c","unresolved":true,"context_lines":[{"line_number":623,"context_line":"                part_number\u003dpart_checksum[\u0027part_number\u0027])"},{"line_number":624,"context_line":"        return stored_checksum_value"},{"line_number":625,"context_line":""},{"line_number":626,"context_line":"    def _validate_segments(self, manifest):"},{"line_number":627,"context_line":"        \"\"\""},{"line_number":628,"context_line":"        Validate all manifest segments in S3 error-precedence order."},{"line_number":629,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"94bf3753_5b2bb287","line":626,"range":{"start_line":626,"start_character":33,"end_line":626,"end_character":41},"in_reply_to":"fa944b6d_70fd6e8d","updated":"2026-08-14 17:42:45.000000000","message":"Yea this works!","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"018326efb090a777c725a9a195fc21cb14334b71","unresolved":true,"context_lines":[{"line_number":663,"context_line":"                            self._validate_part_checksum_metadata("},{"line_number":664,"context_line":"                                part_checksum)"},{"line_number":665,"context_line":"                        part_checksum[\u0027checksum_raw\u0027] \u003d \\"},{"line_number":666,"context_line":"                            _validate_part_checksum("},{"line_number":667,"context_line":"                                self.mpu_checksum_attrs.checksum_header,"},{"line_number":668,"context_line":"                                stored_checksum_value)"},{"line_number":669,"context_line":"                        part_checksum[\u0027bytes\u0027] \u003d manifest_item[\u0027bytes\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"ce53c540_7b4f7874","line":666,"updated":"2026-08-14 13:28:38.000000000","message":"we shouldn\u0027t need to validate that the value is ok because (a) the request part value was validated on the way in and (b) the stored value was presumably validated during a part upload","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":663,"context_line":"                            self._validate_part_checksum_metadata("},{"line_number":664,"context_line":"                                part_checksum)"},{"line_number":665,"context_line":"                        part_checksum[\u0027checksum_raw\u0027] \u003d \\"},{"line_number":666,"context_line":"                            _validate_part_checksum("},{"line_number":667,"context_line":"                                self.mpu_checksum_attrs.checksum_header,"},{"line_number":668,"context_line":"                                stored_checksum_value)"},{"line_number":669,"context_line":"                        part_checksum[\u0027bytes\u0027] \u003d manifest_item[\u0027bytes\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"e91fd425_545258fa","line":666,"in_reply_to":"7b521a0e_93f67adb","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"1553c13185ab37e9dbf3bb7fdd0368d5fd8e851c","unresolved":true,"context_lines":[{"line_number":663,"context_line":"                            self._validate_part_checksum_metadata("},{"line_number":664,"context_line":"                                part_checksum)"},{"line_number":665,"context_line":"                        part_checksum[\u0027checksum_raw\u0027] \u003d \\"},{"line_number":666,"context_line":"                            _validate_part_checksum("},{"line_number":667,"context_line":"                                self.mpu_checksum_attrs.checksum_header,"},{"line_number":668,"context_line":"                                stored_checksum_value)"},{"line_number":669,"context_line":"                        part_checksum[\u0027bytes\u0027] \u003d manifest_item[\u0027bytes\u0027]"}],"source_content_type":"text/x-python","patch_set":5,"id":"7b521a0e_93f67adb","line":666,"in_reply_to":"ce53c540_7b4f7874","updated":"2026-08-14 17:42:45.000000000","message":"Yea I think you are right with this","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bb6ea6dd5edd70788d5c3a93a3bfa556c737e5cf","unresolved":true,"context_lines":[{"line_number":665,"context_line":"            hasher \u003d None"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"        missing_part_checksum \u003d False"},{"line_number":668,"context_line":"        checksum_error \u003d size_error \u003d False"},{"line_number":669,"context_line":"        for index, (manifest_item, part_checksum) in \\"},{"line_number":670,"context_line":"                enumerate(zip(manifest, self.part_checksums)):"},{"line_number":671,"context_line":"            if manifest_item is None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"4ca81aab_dc2e6e2f","line":668,"range":{"start_line":668,"start_character":8,"end_line":668,"end_character":22},"updated":"2026-08-14 15:50:52.000000000","message":"maybe name this part_checksum_error to clarify from the final checksum","commit_id":"64ec178fb6439b9f98b3e8e0d35d68f843cd9a7e"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"1553c13185ab37e9dbf3bb7fdd0368d5fd8e851c","unresolved":true,"context_lines":[{"line_number":665,"context_line":"            hasher \u003d None"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"        missing_part_checksum \u003d False"},{"line_number":668,"context_line":"        checksum_error \u003d size_error \u003d False"},{"line_number":669,"context_line":"        for index, (manifest_item, part_checksum) in \\"},{"line_number":670,"context_line":"                enumerate(zip(manifest, self.part_checksums)):"},{"line_number":671,"context_line":"            if manifest_item is None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"b3e337e4_d9d86b8f","line":668,"range":{"start_line":668,"start_character":8,"end_line":668,"end_character":22},"in_reply_to":"4ca81aab_dc2e6e2f","updated":"2026-08-14 17:42:45.000000000","message":"Yes I agree here","commit_id":"64ec178fb6439b9f98b3e8e0d35d68f843cd9a7e"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":665,"context_line":"            hasher \u003d None"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"        missing_part_checksum \u003d False"},{"line_number":668,"context_line":"        checksum_error \u003d size_error \u003d False"},{"line_number":669,"context_line":"        for index, (manifest_item, part_checksum) in \\"},{"line_number":670,"context_line":"                enumerate(zip(manifest, self.part_checksums)):"},{"line_number":671,"context_line":"            if manifest_item is None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"0733ff5a_b4a41226","line":668,"range":{"start_line":668,"start_character":8,"end_line":668,"end_character":22},"in_reply_to":"b3e337e4_d9d86b8f","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"64ec178fb6439b9f98b3e8e0d35d68f843cd9a7e"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"f157674f36e3700b33ebfd616d52c59ddc33f047","unresolved":false,"context_lines":[{"line_number":641,"context_line":"            # Don\u0027t do anymore checksum validation for this part"},{"line_number":642,"context_line":"            return None"},{"line_number":643,"context_line":""},{"line_number":644,"context_line":"        req_checksum_value \u003d self._get_req_part_checksum_value(req_part_checksum)"},{"line_number":645,"context_line":"        if req_checksum_value and req_checksum_value !\u003d stored_checksum_value:"},{"line_number":646,"context_line":"            raise InvalidPart("},{"line_number":647,"context_line":"                upload_id\u003dself.upload_id,"}],"source_content_type":"text/x-python","patch_set":8,"id":"971c1126_a56e9b0f","line":644,"updated":"2026-08-14 18:23:06.000000000","message":"pep8: E501 line too long (81 \u003e 79 characters)","commit_id":"c0cec353f95db6b9853d892bb24374a70e5612c2"}],"test/s3api/test_object_checksums.py":[{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"e9696f03951fb49670732f497c75bcd011ef67a9","unresolved":false,"context_lines":[{"line_number":1837,"context_line":"            except botocore.exceptions.ClientError:"},{"line_number":1838,"context_line":"                pass"},{"line_number":1839,"context_line":""},{"line_number":1840,"context_line":"    def test_mpu_complete_bad_request_part_checksum_wins_over_size("},{"line_number":1841,"context_line":"            self):"},{"line_number":1842,"context_line":"        obj_name \u003d self.create_name("},{"line_number":1843,"context_line":"            \u0027mpu-too-small-part-bad-request-checksum\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"68be8b6e_b29f7f53","line":1840,"range":{"start_line":1840,"start_character":0,"end_line":1840,"end_character":67},"updated":"2026-08-13 21:59:22.000000000","message":"I want to preface these tests are chunky... we can probably do some cleanup of them in the sizing, but I think it would be better to do that if we squash them in","commit_id":"3b7cf771813203f03f1120babc40d6735accee9c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"018326efb090a777c725a9a195fc21cb14334b71","unresolved":true,"context_lines":[{"line_number":1992,"context_line":""},{"line_number":1993,"context_line":"            self.assertLess(len(first_body), 5 * 2 ** 20)"},{"line_number":1994,"context_line":"            self.assertNotEqual("},{"line_number":1995,"context_line":"                first_checksum, TestObjectChecksumCRC32.BAD)"},{"line_number":1996,"context_line":"            with self.assertRaises(botocore.exceptions.ClientError) as caught:"},{"line_number":1997,"context_line":"                self.client.complete_multipart_upload("},{"line_number":1998,"context_line":"                    Bucket\u003dself.bucket_name,"}],"source_content_type":"text/x-python","patch_set":5,"id":"57c1a329_dcd3d637","line":1995,"updated":"2026-08-14 13:28:38.000000000","message":"I found these assertions very helpful to confirm what I think the test is exercising. Perhaps add a comment\n\n```\n# here\u0027s the problems:\n```\n\nditto in other tests","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":1992,"context_line":""},{"line_number":1993,"context_line":"            self.assertLess(len(first_body), 5 * 2 ** 20)"},{"line_number":1994,"context_line":"            self.assertNotEqual("},{"line_number":1995,"context_line":"                first_checksum, TestObjectChecksumCRC32.BAD)"},{"line_number":1996,"context_line":"            with self.assertRaises(botocore.exceptions.ClientError) as caught:"},{"line_number":1997,"context_line":"                self.client.complete_multipart_upload("},{"line_number":1998,"context_line":"                    Bucket\u003dself.bucket_name,"}],"source_content_type":"text/x-python","patch_set":5,"id":"68347607_862bbf61","line":1995,"in_reply_to":"57c1a329_dcd3d637","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7024fd3998ed7d50686eab4e94c2089998bb4fee","unresolved":true,"context_lines":[{"line_number":2433,"context_line":"                    Key\u003dobj_name,"},{"line_number":2434,"context_line":"                    UploadId\u003dupload_id)"},{"line_number":2435,"context_line":"            except botocore.exceptions.ClientError:"},{"line_number":2436,"context_line":"                pass"},{"line_number":2437,"context_line":""},{"line_number":2438,"context_line":"    def test_mpu_upload_part_rejects_checksum_algorithm_mismatch(self):"},{"line_number":2439,"context_line":"        algorithm \u003d \u0027CRC32\u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"22b89388_25d6a3c8","line":2436,"updated":"2026-08-14 13:30:52.000000000","message":"do we have cover for\n\n```\ntest_mpu_complete_bad_part_checksum_with_bad_request_final_checksum\n```","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"1553c13185ab37e9dbf3bb7fdd0368d5fd8e851c","unresolved":true,"context_lines":[{"line_number":2433,"context_line":"                    Key\u003dobj_name,"},{"line_number":2434,"context_line":"                    UploadId\u003dupload_id)"},{"line_number":2435,"context_line":"            except botocore.exceptions.ClientError:"},{"line_number":2436,"context_line":"                pass"},{"line_number":2437,"context_line":""},{"line_number":2438,"context_line":"    def test_mpu_upload_part_rejects_checksum_algorithm_mismatch(self):"},{"line_number":2439,"context_line":"        algorithm \u003d \u0027CRC32\u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"fb2b020d_1b3c0ecd","line":2436,"in_reply_to":"22b89388_25d6a3c8","updated":"2026-08-14 17:42:45.000000000","message":"No but we ought too to enforce `BadDigest` over `InvalidPart`","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":2433,"context_line":"                    Key\u003dobj_name,"},{"line_number":2434,"context_line":"                    UploadId\u003dupload_id)"},{"line_number":2435,"context_line":"            except botocore.exceptions.ClientError:"},{"line_number":2436,"context_line":"                pass"},{"line_number":2437,"context_line":""},{"line_number":2438,"context_line":"    def test_mpu_upload_part_rejects_checksum_algorithm_mismatch(self):"},{"line_number":2439,"context_line":"        algorithm \u003d \u0027CRC32\u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"34de05f2_dee0d3b4","line":2436,"in_reply_to":"fb2b020d_1b3c0ecd","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"fcd70336a9aec8bf67eb01440004c14eea5b40ee"}],"test/unit/common/middleware/s3api/test_multi_upload.py":[{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cd34d9cc2b305c45262eb0e460c740173b3da992","unresolved":false,"context_lines":[{"line_number":2680,"context_line":"    def test_complete_checksum_aware_missing_metadata_without_checksums("},{"line_number":2681,"context_line":"            self):"},{"line_number":2682,"context_line":"        # the manifest must be valid w.r.t. the CreateMultipartUpload checksum"},{"line_number":2683,"context_line":"        # attributes, even if there is a stored part without checksum"},{"line_number":2684,"context_line":"        part_one_checksum \u003d base64.b64encode("},{"line_number":2685,"context_line":"            checksum.crc32(b\u0027part one\u0027).digest()).decode(\u0027ascii\u0027)"},{"line_number":2686,"context_line":"        # marker specifies composite CRC32..."}],"source_content_type":"text/x-python","patch_set":1,"id":"6a0846d9_aaaa8ea0","line":2683,"range":{"start_line":2683,"start_character":22,"end_line":2683,"end_character":69},"updated":"2026-08-13 15:46:24.000000000","message":"Yea this is the API of S3, if the manifest is wrong even if we have nothing to validate aganist, we should handle it.","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cd34d9cc2b305c45262eb0e460c740173b3da992","unresolved":true,"context_lines":[{"line_number":4488,"context_line":""},{"line_number":4489,"context_line":"    def test_object_multipart_upload_complete_segment_too_small(self):"},{"line_number":4490,"context_line":"        msg \u003d \u0027some/path: %s\u0027 \\"},{"line_number":4491,"context_line":"              % _CompleteMultipartUploadSloManifestHook.ERROR_MESSAGE"},{"line_number":4492,"context_line":"        self.swift.register(\u0027PUT\u0027, \u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":4493,"context_line":"                            swob.HTTPBadRequest, {}, msg)"},{"line_number":4494,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":1,"id":"621ec6d8_5b2a5c8f","line":4491,"range":{"start_line":4491,"start_character":16,"end_line":4491,"end_character":55},"updated":"2026-08-13 15:46:24.000000000","message":"Maybe this is just for simplicity, but should we be getting variables from private classes?","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cfb938baf051e96fd0af6be173c4fa91943737ce","unresolved":true,"context_lines":[{"line_number":4488,"context_line":""},{"line_number":4489,"context_line":"    def test_object_multipart_upload_complete_segment_too_small(self):"},{"line_number":4490,"context_line":"        msg \u003d \u0027some/path: %s\u0027 \\"},{"line_number":4491,"context_line":"              % _CompleteMultipartUploadSloManifestHook.ERROR_MESSAGE"},{"line_number":4492,"context_line":"        self.swift.register(\u0027PUT\u0027, \u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":4493,"context_line":"                            swob.HTTPBadRequest, {}, msg)"},{"line_number":4494,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":1,"id":"ef7624ac_39d88c32","line":4491,"range":{"start_line":4491,"start_character":16,"end_line":4491,"end_character":55},"in_reply_to":"621ec6d8_5b2a5c8f","updated":"2026-08-13 18:49:19.000000000","message":"Well... actually this is differen\u0027t because it is a generic error message, not a specific one, so we probably do need to know what the excat message is before trying to throw it","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c79736d2cd7af632b52725d92327e0768fb2fb76","unresolved":false,"context_lines":[{"line_number":4488,"context_line":""},{"line_number":4489,"context_line":"    def test_object_multipart_upload_complete_segment_too_small(self):"},{"line_number":4490,"context_line":"        msg \u003d \u0027some/path: %s\u0027 \\"},{"line_number":4491,"context_line":"              % _CompleteMultipartUploadSloManifestHook.ERROR_MESSAGE"},{"line_number":4492,"context_line":"        self.swift.register(\u0027PUT\u0027, \u0027/v1/AUTH_test/bucket/object\u0027,"},{"line_number":4493,"context_line":"                            swob.HTTPBadRequest, {}, msg)"},{"line_number":4494,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":1,"id":"0909aaee_7bc362b4","line":4491,"range":{"start_line":4491,"start_character":16,"end_line":4491,"end_character":55},"in_reply_to":"ef7624ac_39d88c32","updated":"2026-08-14 17:47:31.000000000","message":"Done","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"cd34d9cc2b305c45262eb0e460c740173b3da992","unresolved":false,"context_lines":[{"line_number":4500,"context_line":""},{"line_number":4501,"context_line":"        with mock.patch("},{"line_number":4502,"context_line":"                \u0027swift.common.middleware.s3api.controllers.multi_upload.\u0027"},{"line_number":4503,"context_line":"                \u0027_CompleteMultipartUploadSloManifestHook.errors\u0027,"},{"line_number":4504,"context_line":"                [EntityTooSmall(\u0027whatever\u0027)]):"},{"line_number":4505,"context_line":"            status, headers, body \u003d self.call_s3api(req)"},{"line_number":4506,"context_line":"        self.assertEqual(status.split()[0], \u0027400\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"a1471393_d6ece4fc","line":4503,"range":{"start_line":4503,"start_character":0,"end_line":4503,"end_character":65},"updated":"2026-08-13 15:46:24.000000000","message":"Yea this makes sense for sure","commit_id":"71edf1c5eb6520d6c42b526c26bd210848cdc432"}]}
