)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":7,"context_line":"s3api: Add checksum module"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Move checksum functions into a singular module so that when we add"},{"line_number":10,"context_line":"more checksum features in the s3api, we have one place to find them."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I1cdb0e6e4cf98d6ef13c92922bed59db08201737"},{"line_number":13,"context_line":"Assisted-by: Codex:gpt-5.6"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"ca78ae24_b8802907","line":10,"updated":"2026-08-21 13:26:20.000000000","message":"also adds tests for ChecksummingInput","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":7,"context_line":"s3api: Add checksum module"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Move checksum functions into a singular module so that when we add"},{"line_number":10,"context_line":"more checksum features in the s3api, we have one place to find them."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I1cdb0e6e4cf98d6ef13c92922bed59db08201737"},{"line_number":13,"context_line":"Assisted-by: Codex:gpt-5.6"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"e8d17d56_5a605a32","line":10,"in_reply_to":"ca78ae24_b8802907","updated":"2026-08-21 17:46:03.000000000","message":"Yea it might be good to say that tests were added here too","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":7,"context_line":"s3api: Add checksum module"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Move checksum functions into a singular module so that when we add"},{"line_number":10,"context_line":"more checksum features in the s3api, we have one place to find them."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I1cdb0e6e4cf98d6ef13c92922bed59db08201737"},{"line_number":13,"context_line":"Assisted-by: Codex:gpt-5.6"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"635d177e_f34f9b44","line":10,"in_reply_to":"e8d17d56_5a605a32","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"061631f210daab007691365994c38d8221b1f4de","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"d9976149_28145a4d","updated":"2026-08-14 15:04:32.000000000","message":"LGTM except for the module name clash, I\u0027d prefer a different name for clarity","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"63c3aa56f8da8a698c86a8d562789864a44b10d4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"3a297df1_a041ee18","updated":"2026-08-11 18:12:09.000000000","message":"This patch is mainly just to save our butts in the feature from\nthe despair of circular imports and we do have a lot of checksum code to add, good to put it all in one place","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"e2ca6dba2499b8e04313b4e11f9964553c661da8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"ce760d79_804b8ac3","updated":"2026-08-18 15:21:41.000000000","message":"Please see my inline comment","commit_id":"d183b92560e1771cb88f16bb9414e43e89813913"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9aba46ebea6db3c252b882a1d0df8bdf2c2dc78e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"fc50f5ac_0097d0cc","updated":"2026-08-19 14:42:31.000000000","message":"I\u0027m not convinced (yet) by the change to ChecksummingInput, and regardless it shouldn\u0027t be a drive-by fix in what is otherwise a refactor.","commit_id":"dbf87c6022b4fbe020f61b271bf2e91841c2e550"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"09f4e0cedb327f198aa0cec77535bc64e45681bf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"25aee278_c60fc1a9","updated":"2026-08-19 16:20:37.000000000","message":"Reverted this to patchset 3, which was good before, will defer behavior changes to 999457: s3api: Recompute Checksums for CopyObject and UploadPartCopy | https://review.opendev.org/c/openstack/swift/+/999457","commit_id":"67ae15cd881767429046eb62e6b29f3149975c96"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"85cff8e2_f3ed3983","updated":"2026-08-21 13:26:20.000000000","message":"-1 for the scope of the try/except in s3request and changes to comments\n\nIMHO it would be helpful for this patch to change as little as possible other than faithfully moving code and adding tests","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"435f8ef4d936bb96405205d58e411e2cedbf18f9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"3dc52c28_338263ab","updated":"2026-08-24 18:38:30.000000000","message":"looks good functionality wise; just feel like some things can be moved around/condensed! good module","commit_id":"d33cc271cc0dde8e8c4962a33f217fb30c3eb86b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63d9d1486aa639d545abc93052e139ca6a31cda1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"e5a9bbec_56eeb6f3","updated":"2026-08-25 11:37:54.000000000","message":"I think it\u0027s worth dropping the unnecessary _validate_checksum_value alias, but it could be a follow-up. If you do need to push another patchset then pls squash this one in:\n\ns3request: remove unnecessary import alias  https://review.opendev.org/c/openstack/swift/+/1002261\n\nClaude suggested some more test coverage but IMHO that is out of scope for this refactor patch, I\u0027ll also propose it separately. Don\u0027t squash this one:\n\nopenstack/swift master: s3checksum: add test coverage  https://review.opendev.org/c/openstack/swift/+/1002262","commit_id":"177ce23ddcdd28f9b63a7f3f2e6ae5cc48016fa2"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"7e4ec97a7bdd84d44ba5277f855e43509300e639","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"2eba783d_3a60a21e","updated":"2026-08-25 13:12:55.000000000","message":"LGTM. Let\u0027s get this rolling!","commit_id":"177ce23ddcdd28f9b63a7f3f2e6ae5cc48016fa2"}],"swift/common/middleware/s3api/checksum.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"061631f210daab007691365994c38d8221b1f4de","unresolved":true,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from swift.common.middleware.s3api.exception import \\"},{"line_number":19,"context_line":"    S3InputChecksumMismatch, S3InputChecksumTrailerInvalid"},{"line_number":20,"context_line":"from swift.common.utils import checksum, InputProxy, strict_b64decode"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"CHECKSUMS_BY_HEADER \u003d {"}],"source_content_type":"text/x-python","patch_set":1,"id":"b429c62b_a8bb0ce8","line":20,"range":{"start_line":20,"start_character":31,"end_line":20,"end_character":39},"updated":"2026-08-14 15:04:32.000000000","message":"we already have a ``checksum.py``, could we name this new module ``s3checksum.py``","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"15bd9b99cab3ef5e74901b9831890df3574d109e","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from swift.common.middleware.s3api.exception import \\"},{"line_number":19,"context_line":"    S3InputChecksumMismatch, S3InputChecksumTrailerInvalid"},{"line_number":20,"context_line":"from swift.common.utils import checksum, InputProxy, strict_b64decode"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"CHECKSUMS_BY_HEADER \u003d {"}],"source_content_type":"text/x-python","patch_set":1,"id":"16054324_c83f7a41","line":20,"range":{"start_line":20,"start_character":31,"end_line":20,"end_character":39},"in_reply_to":"a36941aa_a4ea487d","updated":"2026-08-19 23:43:00.000000000","message":"Done","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"099116c670c17ecdad0bc7e8de860ef470af29d5","unresolved":true,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from swift.common.middleware.s3api.exception import \\"},{"line_number":19,"context_line":"    S3InputChecksumMismatch, S3InputChecksumTrailerInvalid"},{"line_number":20,"context_line":"from swift.common.utils import checksum, InputProxy, strict_b64decode"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"CHECKSUMS_BY_HEADER \u003d {"}],"source_content_type":"text/x-python","patch_set":1,"id":"a36941aa_a4ea487d","line":20,"range":{"start_line":20,"start_character":31,"end_line":20,"end_character":39},"in_reply_to":"b429c62b_a8bb0ce8","updated":"2026-08-14 23:59:10.000000000","message":"Yea I think this a good idea","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"061631f210daab007691365994c38d8221b1f4de","unresolved":true,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"def get_checksum_hasher(header):"},{"line_number":33,"context_line":"    \"\"\"Return a checksum hasher for an x-amz-checksum-* header.\"\"\""},{"line_number":34,"context_line":"    try:"},{"line_number":35,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":36,"context_line":"    except (KeyError, NotImplementedError):"}],"source_content_type":"text/x-python","patch_set":1,"id":"00442a57_12da0c13","line":33,"updated":"2026-08-14 15:04:32.000000000","message":"nit: add a ``:raises:`` file in docstring","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"099116c670c17ecdad0bc7e8de860ef470af29d5","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"def get_checksum_hasher(header):"},{"line_number":33,"context_line":"    \"\"\"Return a checksum hasher for an x-amz-checksum-* header.\"\"\""},{"line_number":34,"context_line":"    try:"},{"line_number":35,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":36,"context_line":"    except (KeyError, NotImplementedError):"}],"source_content_type":"text/x-python","patch_set":1,"id":"f9b51e25_57ebfe2d","line":33,"in_reply_to":"00442a57_12da0c13","updated":"2026-08-14 23:59:10.000000000","message":"Done","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"061631f210daab007691365994c38d8221b1f4de","unresolved":true,"context_lines":[{"line_number":47,"context_line":"    )"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"class ChecksummingInput(InputProxy):"},{"line_number":51,"context_line":"    \"\"\""},{"line_number":52,"context_line":"    Calculate and validate the X-Amz-Checksum-* of an input as it is read."},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9d0be74a_2db4b903","line":50,"updated":"2026-08-14 15:04:32.000000000","message":"I think moving this out of s3request is probably justified because later we\u0027ll want to use it for an object copy hook, correct? Plus, it\u0027s to do with checksums","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"099116c670c17ecdad0bc7e8de860ef470af29d5","unresolved":true,"context_lines":[{"line_number":47,"context_line":"    )"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"class ChecksummingInput(InputProxy):"},{"line_number":51,"context_line":"    \"\"\""},{"line_number":52,"context_line":"    Calculate and validate the X-Amz-Checksum-* of an input as it is read."},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"739ebcd6_2700ab54","line":50,"in_reply_to":"9d0be74a_2db4b903","updated":"2026-08-14 23:59:10.000000000","message":"Yes in the future, we will end up wrapping this class over a generic Swift `Request` class to handle the copying. It wouldn\u0027t feel right to like expose `ChecksummingInput` from `S3Request` and use it on a request that is NOT a `S3Request`... so I think this is the best approach","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"}],"swift/common/middleware/s3api/s3checksum.py":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"e2ca6dba2499b8e04313b4e11f9964553c661da8","unresolved":true,"context_lines":[{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # Wrapped input is likely to have timed out before this clause is"},{"line_number":84,"context_line":"            # reached with eof\u003dTrue, but just in case."},{"line_number":85,"context_line":"            error \u003d eof"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."},{"line_number":88,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_key)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7307d502_0aaf4610","line":85,"updated":"2026-08-18 15:21:41.000000000","message":"This needs to be: `error \u003d eof and not chunk`\n\nA copy can fail with 400 BadDigest even though the client sent no checksum. ChecksummingInput stops at the first short read, but the copy source returns one chunk per read, so the checksum only covers part of the body. \n\nNoticed the issue later in the patch series when testing on a SAIO; the bug can\u0027t be reproduced on a SAIO here (only later - on 999457), but it makes sense to fix it here.\n\nShorter reproducer, fails without the fix - might be a good candidate for another test:\n\n```\nfrom swift.common.utils import FileLikeIter\nfrom swift.common.middleware.s3api.s3checksum import ChecksummingInput, get_checksum_hasher\nH \u003d \u0027x-amz-checksum-crc32\u0027\nsrc \u003d FileLikeIter(iter([b\u0027a\u0027 * 100, b\u0027b\u0027 * 100]))\ninp \u003d ChecksummingInput(src, 200, get_checksum_hasher(H), H, None)\nwhile inp.read(150):\n    pass\n  \n```","commit_id":"d183b92560e1771cb88f16bb9414e43e89813913"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"71db19afd9d0494929e71ae9611fee80dcad1220","unresolved":true,"context_lines":[{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # Wrapped input is likely to have timed out before this clause is"},{"line_number":84,"context_line":"            # reached with eof\u003dTrue, but just in case."},{"line_number":85,"context_line":"            error \u003d eof"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."},{"line_number":88,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_key)"}],"source_content_type":"text/x-python","patch_set":3,"id":"f75063e9_184c0bd9","line":85,"in_reply_to":"7307d502_0aaf4610","updated":"2026-08-18 18:53:15.000000000","message":"Yes I think this is needed earlier, I can write up a unit test to address this along with the fix, thanks!\n\nI think it will be useful to write a test case in 999457 to showcase this aswell","commit_id":"d183b92560e1771cb88f16bb9414e43e89813913"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"15bd9b99cab3ef5e74901b9831890df3574d109e","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # Wrapped input is likely to have timed out before this clause is"},{"line_number":84,"context_line":"            # reached with eof\u003dTrue, but just in case."},{"line_number":85,"context_line":"            error \u003d eof"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."},{"line_number":88,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_key)"}],"source_content_type":"text/x-python","patch_set":3,"id":"4668e3b4_c8d72c90","line":85,"in_reply_to":"f75063e9_184c0bd9","updated":"2026-08-19 23:43:00.000000000","message":"Done https://review.opendev.org/c/openstack/swift/+/999457/26/swift/common/middleware/s3api/s3checksum.py#197","commit_id":"d183b92560e1771cb88f16bb9414e43e89813913"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9aba46ebea6db3c252b882a1d0df8bdf2c2dc78e","unresolved":true,"context_lines":[{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # A non-empty short read may be one chunk from an iterable-backed"},{"line_number":84,"context_line":"            # input rather than the end of the input."},{"line_number":85,"context_line":"            error \u003d eof and not chunk"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."},{"line_number":88,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_key)"}],"source_content_type":"text/x-python","patch_set":5,"id":"89e6e0c7_260f13e2","line":85,"range":{"start_line":85,"start_character":12,"end_line":85,"end_character":37},"updated":"2026-08-19 14:42:31.000000000","message":"wait, this is a behavioral change sneaked into what is ostensibly a refactor. Where does InputProxy wrap an iterable? It\u0027s docstring says it is to be used with file like objects. If a read cannot satisfy the requested bytes then we should be at eof.\n\nIf we do have a bug then please address it separately from moving the class to this module.","commit_id":"dbf87c6022b4fbe020f61b271bf2e91841c2e550"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"d66b6a5fa51c4b1a70fa8da7e2c7bdad2572a0b0","unresolved":true,"context_lines":[{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # A non-empty short read may be one chunk from an iterable-backed"},{"line_number":84,"context_line":"            # input rather than the end of the input."},{"line_number":85,"context_line":"            error \u003d eof and not chunk"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."},{"line_number":88,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_key)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a4b4f1f_401dd42c","line":85,"range":{"start_line":85,"start_character":12,"end_line":85,"end_character":37},"in_reply_to":"10bb5cc5_16808802","updated":"2026-08-19 16:12:52.000000000","message":"\u003e There is no bug today AFAICT. It becomes a bug in in 999457\n\nYes\n\nI can move this out into the Copy patch!","commit_id":"dbf87c6022b4fbe020f61b271bf2e91841c2e550"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"15bd9b99cab3ef5e74901b9831890df3574d109e","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # A non-empty short read may be one chunk from an iterable-backed"},{"line_number":84,"context_line":"            # input rather than the end of the input."},{"line_number":85,"context_line":"            error \u003d eof and not chunk"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."},{"line_number":88,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_key)"}],"source_content_type":"text/x-python","patch_set":5,"id":"184d8a4f_65fa78cf","line":85,"range":{"start_line":85,"start_character":12,"end_line":85,"end_character":37},"in_reply_to":"7a4b4f1f_401dd42c","updated":"2026-08-19 23:43:00.000000000","message":"Done","commit_id":"dbf87c6022b4fbe020f61b271bf2e91841c2e550"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"ed748296acbbe8ff96eb24d7e20464ce46a61872","unresolved":true,"context_lines":[{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # A non-empty short read may be one chunk from an iterable-backed"},{"line_number":84,"context_line":"            # input rather than the end of the input."},{"line_number":85,"context_line":"            error \u003d eof and not chunk"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."},{"line_number":88,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_key)"}],"source_content_type":"text/x-python","patch_set":5,"id":"10bb5cc5_16808802","line":85,"range":{"start_line":85,"start_character":12,"end_line":85,"end_character":37},"in_reply_to":"89e6e0c7_260f13e2","updated":"2026-08-19 15:00:34.000000000","message":"@alistairncoles@gmail.com: Sorry, this on is on me - I asked Nate to change this in my earlier comment.\n\nThere is no bug today AFAICT. It becomes a bug in in 999457. I recommended to fix it here, but you\u0027re right that this is the wrong location because this is mostly moving code.\n\nIn swift/common/middleware/copy.py:476 we use `wsgi.input \u003d FileLikeIter(source_resp.app_iter)`. FileLikeIter.read(size) returns one chunk of the iterable, but it does not fill up to size, and InputProxy.read() calls that eof.","commit_id":"dbf87c6022b4fbe020f61b271bf2e91841c2e550"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    try:"},{"line_number":39,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":40,"context_line":"    except (KeyError, NotImplementedError):"},{"line_number":41,"context_line":"        # Only if we could just raise S3NotImplemented instead..."},{"line_number":42,"context_line":"        raise NotImplementedError("},{"line_number":43,"context_line":"            \u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"f9bfd1ad_d8b368a8","line":41,"updated":"2026-08-21 13:26:20.000000000","message":"I\u0027m not sure this comment is helpful. For a future reader it provides no information as to why the code is as it is.  Either drop it or say why e.g.\n\n```\nWe don\u0027t want to import s3response in this module so we cannot raise S3NotImplemented here.\n```","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    try:"},{"line_number":39,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":40,"context_line":"    except (KeyError, NotImplementedError):"},{"line_number":41,"context_line":"        # Only if we could just raise S3NotImplemented instead..."},{"line_number":42,"context_line":"        raise NotImplementedError("},{"line_number":43,"context_line":"            \u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"e665f66c_6f6b55ec","line":41,"in_reply_to":"668eac7a_acd5edaf","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    try:"},{"line_number":39,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":40,"context_line":"    except (KeyError, NotImplementedError):"},{"line_number":41,"context_line":"        # Only if we could just raise S3NotImplemented instead..."},{"line_number":42,"context_line":"        raise NotImplementedError("},{"line_number":43,"context_line":"            \u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"668eac7a_acd5edaf","line":41,"in_reply_to":"f9bfd1ad_d8b368a8","updated":"2026-08-21 17:46:03.000000000","message":"Yes I think this is a much better comment. thanks!","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":51,"context_line":"    )"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"class ChecksummingInput(InputProxy):"},{"line_number":55,"context_line":"    \"\"\""},{"line_number":56,"context_line":"    Calculate and validate the X-Amz-Checksum-* of an input as it is read."},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"65344464_586b92dc","line":54,"updated":"2026-08-21 13:26:20.000000000","message":"the refactor has changed the doc strings and comments in this class and in some cases I feel we have lost useful commentary.\n\nI don\u0027t have a problem with simple grammar fixes (capitalisation and end-of-sentence periods) but otherwise perhaps don\u0027t change unless something is wrong or misleading.","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    )"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"class ChecksummingInput(InputProxy):"},{"line_number":55,"context_line":"    \"\"\""},{"line_number":56,"context_line":"    Calculate and validate the X-Amz-Checksum-* of an input as it is read."},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"e503fa66_3f64fde6","line":54,"in_reply_to":"4b03c352_254b5485","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":51,"context_line":"    )"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"class ChecksummingInput(InputProxy):"},{"line_number":55,"context_line":"    \"\"\""},{"line_number":56,"context_line":"    Calculate and validate the X-Amz-Checksum-* of an input as it is read."},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"4b03c352_254b5485","line":54,"in_reply_to":"65344464_586b92dc","updated":"2026-08-21 17:46:03.000000000","message":"Good point, I\u0027ll look over these and make sure they are all how they were mostly!","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":81,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # Wrapped input is likely to have timed out before this clause is"},{"line_number":84,"context_line":"            # reached with eof\u003dTrue, but just in case."},{"line_number":85,"context_line":"            error \u003d eof"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."}],"source_content_type":"text/x-python","patch_set":8,"id":"22ce2700_e5fffc6c","line":84,"range":{"start_line":84,"start_character":53,"end_line":84,"end_character":54},"updated":"2026-08-21 13:26:20.000000000","message":"sorry to be pedantic but the ellipsis ``...`` made sense here because it implies that the comment is trailing off to following the code. We use that style a lot to imply a reference to what is coming on the next line.","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":81,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # Wrapped input is likely to have timed out before this clause is"},{"line_number":84,"context_line":"            # reached with eof\u003dTrue, but just in case."},{"line_number":85,"context_line":"            error \u003d eof"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."}],"source_content_type":"text/x-python","patch_set":8,"id":"debadd4e_7ece602d","line":84,"range":{"start_line":84,"start_character":53,"end_line":84,"end_character":54},"in_reply_to":"22ce2700_e5fffc6c","updated":"2026-08-21 17:46:03.000000000","message":"OH I see, thats neat, will keep them in!","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":82,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":83,"context_line":"            # Wrapped input is likely to have timed out before this clause is"},{"line_number":84,"context_line":"            # reached with eof\u003dTrue, but just in case."},{"line_number":85,"context_line":"            error \u003d eof"},{"line_number":86,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":87,"context_line":"            # Lazy fetch checksum value because it may have come in trailers."}],"source_content_type":"text/x-python","patch_set":8,"id":"f84ef72c_ffbbc06e","line":84,"range":{"start_line":84,"start_character":53,"end_line":84,"end_character":54},"in_reply_to":"debadd4e_7ece602d","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":91,"context_line":"                    self._checksum_hasher, b64digest)"},{"line_number":92,"context_line":"            except ValueError:"},{"line_number":93,"context_line":"                # Header values were validated before reading the body, so an"},{"line_number":94,"context_line":"                # invalid value here must have come from a trailer."},{"line_number":95,"context_line":"                raise S3InputChecksumTrailerInvalid(self._checksum_key)"},{"line_number":96,"context_line":"            error \u003d self._checksum_hasher.digest() !\u003d expected_raw_checksum"},{"line_number":97,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"81c29eb3_62f83bdd","line":94,"updated":"2026-08-21 13:26:20.000000000","message":"here in particular I\u0027d prefer to keep the original comment.\n\nI can see that it may become less accurate when the ChecksummingInput is re-used in a copy hook, but that hasn\u0027t happened yet and when it does perhaps we can find a way to preserve the useful information.","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":91,"context_line":"                    self._checksum_hasher, b64digest)"},{"line_number":92,"context_line":"            except ValueError:"},{"line_number":93,"context_line":"                # Header values were validated before reading the body, so an"},{"line_number":94,"context_line":"                # invalid value here must have come from a trailer."},{"line_number":95,"context_line":"                raise S3InputChecksumTrailerInvalid(self._checksum_key)"},{"line_number":96,"context_line":"            error \u003d self._checksum_hasher.digest() !\u003d expected_raw_checksum"},{"line_number":97,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"bf83f6a5_27bc8f5b","line":94,"in_reply_to":"81c29eb3_62f83bdd","updated":"2026-08-21 17:46:03.000000000","message":"Will do!","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":91,"context_line":"                    self._checksum_hasher, b64digest)"},{"line_number":92,"context_line":"            except ValueError:"},{"line_number":93,"context_line":"                # Header values were validated before reading the body, so an"},{"line_number":94,"context_line":"                # invalid value here must have come from a trailer."},{"line_number":95,"context_line":"                raise S3InputChecksumTrailerInvalid(self._checksum_key)"},{"line_number":96,"context_line":"            error \u003d self._checksum_hasher.digest() !\u003d expected_raw_checksum"},{"line_number":97,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"fccce80d_2d7fc256","line":94,"in_reply_to":"bf83f6a5_27bc8f5b","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"435f8ef4d936bb96405205d58e411e2cedbf18f9","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    try:"},{"line_number":39,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":40,"context_line":"    except (KeyError, NotImplementedError):"},{"line_number":41,"context_line":"        # We don\u0027t want to import s3response in this module"},{"line_number":42,"context_line":"        # so we cannot raise S3NotImplemented here."},{"line_number":43,"context_line":"        raise NotImplementedError("},{"line_number":44,"context_line":"            \u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"8c6fd1d2_415ae4b6","line":42,"range":{"start_line":41,"start_character":0,"end_line":42,"end_character":51},"updated":"2026-08-24 18:38:30.000000000","message":"Off the top of my dome, I don\u0027t think using s3response would cause a cyclical error of sorts... so why not? stylistic choices? or future proofing from an *eventual* potential s3response import?\n\nnvm! i checked this patch further in the chain https://review.opendev.org/c/openstack/swift/+/999457 and it seems that s3response DOES import s3checksum in there which would fulfill the future proofing thing. fair...\n\nAll of the err stuff in s3response shouldn\u0027t be moved ofc so ignoring that; we already import CHECKSUMS_BY_HEADER in s3request, so realistically can\u0027t we define this as something like\n\n```\ndef get_checksum_hasher(header):\n    return CHECKSUMS_BY_HEADER[header]()\n```\n\nand then in _get_checksum_hasher tweak the except block to \n```\nexcept KeyError as err:\n    raise S3NotImplemented(\u0027The %s algorithm is not supported.\u0027 % header)\n```\n\nnot world ending but would reduce complexity a wee bit methinks...","commit_id":"d33cc271cc0dde8e8c4962a33f217fb30c3eb86b"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"f2798cbddcb32f73d60f6095f87e98fd9713caa4","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    try:"},{"line_number":39,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":40,"context_line":"    except (KeyError, NotImplementedError):"},{"line_number":41,"context_line":"        # We don\u0027t want to import s3response in this module"},{"line_number":42,"context_line":"        # so we cannot raise S3NotImplemented here."},{"line_number":43,"context_line":"        raise NotImplementedError("},{"line_number":44,"context_line":"            \u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"6ee95088_70d97899","line":42,"range":{"start_line":41,"start_character":0,"end_line":42,"end_character":51},"in_reply_to":"5894c68f_a382f4f9","updated":"2026-08-25 02:26:39.000000000","message":"ah icic, lower in the call stack checksum has the potential to throw notimpl... Ok I think you could keep it.\n\n\nOn that note then I think it\u0027d be preferable we raise blankly\n\n```\ndef get_checksum_hasher():\n    ...\n    raise NotImplementedError\n```\n\nand populate the msg in s3request\n\n```\ndef _get_checksum_hasher(header):\n    ...\n    except NotImplementedError:\n        raise S3NotImplemented(\u0027The %s algorithm is not supported.\u0027 % header)\n```","commit_id":"d33cc271cc0dde8e8c4962a33f217fb30c3eb86b"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"64404f6163118a6f7c05e6525682b8f46c5c5151","unresolved":true,"context_lines":[{"line_number":38,"context_line":"    try:"},{"line_number":39,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":40,"context_line":"    except (KeyError, NotImplementedError):"},{"line_number":41,"context_line":"        # We don\u0027t want to import s3response in this module"},{"line_number":42,"context_line":"        # so we cannot raise S3NotImplemented here."},{"line_number":43,"context_line":"        raise NotImplementedError("},{"line_number":44,"context_line":"            \u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":45,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"5894c68f_a382f4f9","line":42,"range":{"start_line":41,"start_character":0,"end_line":42,"end_character":51},"in_reply_to":"8c6fd1d2_415ae4b6","updated":"2026-08-24 23:32:05.000000000","message":"The only thing I see with `get_checksum_hasher` in `s3checksum.py` not handling errors anymore (assuming what the first code block means) \nis that we won\u0027t be handling `NotImplementedError` anymore for this. Which I think it is probably easier to handle 1 exception (`NotImplementedError` \u0026 `KeyError` converging to `NotImplementedError` then having to handle both on there own)","commit_id":"d33cc271cc0dde8e8c4962a33f217fb30c3eb86b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63d9d1486aa639d545abc93052e139ca6a31cda1","unresolved":true,"context_lines":[{"line_number":44,"context_line":"            \u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"def validate_checksum_value(checksum_hasher, b64digest):"},{"line_number":48,"context_line":"    \"\"\"Decode a checksum value with the exact size required by its hasher.\"\"\""},{"line_number":49,"context_line":"    return strict_b64decode("},{"line_number":50,"context_line":"        b64digest,"}],"source_content_type":"text/x-python","patch_set":13,"id":"f9080018_4477a1ea","line":47,"updated":"2026-08-25 11:37:54.000000000","message":"ok. I briefly wondered if this ought to be a generic helper in utils/checksum.py, but the b64 decoding makes the validation less generic, more closely related to s3api.","commit_id":"177ce23ddcdd28f9b63a7f3f2e6ae5cc48016fa2"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"061631f210daab007691365994c38d8221b1f4de","unresolved":true,"context_lines":[{"line_number":116,"context_line":"))"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"def _validate_checksum_header_cardinality(num_checksum_headers,"},{"line_number":120,"context_line":"                                          headers_and_trailer\u003dFalse):"},{"line_number":121,"context_line":"    if num_checksum_headers \u003e 1:"},{"line_number":122,"context_line":"        # inconsistent messaging for AWS compatibility..."}],"source_content_type":"text/x-python","patch_set":1,"id":"eaddc924_8d19ecc9","line":119,"updated":"2026-08-14 15:04:32.000000000","message":"good call, leave this where it is","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"099116c670c17ecdad0bc7e8de860ef470af29d5","unresolved":false,"context_lines":[{"line_number":116,"context_line":"))"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"def _validate_checksum_header_cardinality(num_checksum_headers,"},{"line_number":120,"context_line":"                                          headers_and_trailer\u003dFalse):"},{"line_number":121,"context_line":"    if num_checksum_headers \u003e 1:"},{"line_number":122,"context_line":"        # inconsistent messaging for AWS compatibility..."}],"source_content_type":"text/x-python","patch_set":1,"id":"9478c55c_83ee1d27","line":119,"in_reply_to":"eaddc924_8d19ecc9","updated":"2026-08-14 23:59:10.000000000","message":"Acknowledged","commit_id":"c35f73a79a48646b3b1b9126f44fc201a2281173"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":145,"context_line":"    return strict_b64decode("},{"line_number":146,"context_line":"        b64digest,"},{"line_number":147,"context_line":"        exact_size\u003dchecksum_hasher.digest_size,"},{"line_number":148,"context_line":"    )"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"def _validate_checksum_header_cardinality(num_checksum_headers,"}],"source_content_type":"text/x-python","patch_set":8,"id":"c94afcb1_ac633f58","side":"PARENT","line":148,"updated":"2026-08-21 13:26:20.000000000","message":"ok, moved with only change being the raised exception in _get_checksum_hasher","commit_id":"e19c896da0eeaf09419726106c46acc3e8bdce39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63d9d1486aa639d545abc93052e139ca6a31cda1","unresolved":false,"context_lines":[{"line_number":145,"context_line":"    return strict_b64decode("},{"line_number":146,"context_line":"        b64digest,"},{"line_number":147,"context_line":"        exact_size\u003dchecksum_hasher.digest_size,"},{"line_number":148,"context_line":"    )"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"def _validate_checksum_header_cardinality(num_checksum_headers,"}],"source_content_type":"text/x-python","patch_set":8,"id":"40934493_9c610652","side":"PARENT","line":148,"in_reply_to":"c94afcb1_ac633f58","updated":"2026-08-25 11:37:54.000000000","message":"Acknowledged","commit_id":"e19c896da0eeaf09419726106c46acc3e8bdce39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":1534,"context_line":"            else:"},{"line_number":1535,"context_line":"                checksum_hasher \u003d checksum_header \u003d checksum_trailer \u003d None"},{"line_number":1536,"context_line":"        except NotImplementedError as err:"},{"line_number":1537,"context_line":"            raise S3NotImplemented(str(err))"},{"line_number":1538,"context_line":""},{"line_number":1539,"context_line":"        checksum_algo \u003d self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027)"},{"line_number":1540,"context_line":"        if checksum_algo:"}],"source_content_type":"text/x-python","patch_set":8,"id":"9c0d7e0b_4de564a1","line":1537,"updated":"2026-08-21 13:26:20.000000000","message":"the scope of the try/except is large. We should keep a _get_checksum_hasher function in this module that forwards to the s3checksum function and translates the exception. Then this code would be unchanged.","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":1534,"context_line":"            else:"},{"line_number":1535,"context_line":"                checksum_hasher \u003d checksum_header \u003d checksum_trailer \u003d None"},{"line_number":1536,"context_line":"        except NotImplementedError as err:"},{"line_number":1537,"context_line":"            raise S3NotImplemented(str(err))"},{"line_number":1538,"context_line":""},{"line_number":1539,"context_line":"        checksum_algo \u003d self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027)"},{"line_number":1540,"context_line":"        if checksum_algo:"}],"source_content_type":"text/x-python","patch_set":8,"id":"5cfdd54c_ca9d48a6","line":1537,"in_reply_to":"087639cb_1889614d","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":1534,"context_line":"            else:"},{"line_number":1535,"context_line":"                checksum_hasher \u003d checksum_header \u003d checksum_trailer \u003d None"},{"line_number":1536,"context_line":"        except NotImplementedError as err:"},{"line_number":1537,"context_line":"            raise S3NotImplemented(str(err))"},{"line_number":1538,"context_line":""},{"line_number":1539,"context_line":"        checksum_algo \u003d self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027)"},{"line_number":1540,"context_line":"        if checksum_algo:"}],"source_content_type":"text/x-python","patch_set":8,"id":"087639cb_1889614d","line":1537,"in_reply_to":"9c0d7e0b_4de564a1","updated":"2026-08-21 17:46:03.000000000","message":"I agree and that would be better and match what we are doing in later patches with MPUs","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63d9d1486aa639d545abc93052e139ca6a31cda1","unresolved":true,"context_lines":[{"line_number":46,"context_line":""},{"line_number":47,"context_line":"from swift.common.middleware.s3api.s3checksum import CHECKSUMS_BY_HEADER, \\"},{"line_number":48,"context_line":"    ChecksummingInput, get_checksum_hasher, \\"},{"line_number":49,"context_line":"    validate_checksum_value as _validate_checksum_value"},{"line_number":50,"context_line":"from swift.common.middleware.s3api.controllers import ServiceController, \\"},{"line_number":51,"context_line":"    ObjectController, AclController, MultiObjectDeleteController, \\"},{"line_number":52,"context_line":"    LocationController, LoggingStatusController, PartController, \\"}],"source_content_type":"text/x-python","patch_set":13,"id":"c9fff942_54835f8a","line":49,"range":{"start_line":49,"start_character":4,"end_line":49,"end_character":55},"updated":"2026-08-25 11:37:54.000000000","message":"this does not need to be aliased, we can just change the call site to use the imported name without underscore","commit_id":"177ce23ddcdd28f9b63a7f3f2e6ae5cc48016fa2"}],"test/unit/common/middleware/s3api/test_s3checksum.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9aba46ebea6db3c252b882a1d0df8bdf2c2dc78e","unresolved":true,"context_lines":[{"line_number":53,"context_line":"            FileLikeIter(iter(body_chunks)), len(body), checksum.crc32(),"},{"line_number":54,"context_line":"            \u0027x-amz-checksum-crc32\u0027, checksum_source)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        self.assertEqual(body_chunks[0], wrapped.read(150))"},{"line_number":57,"context_line":"        self.assertEqual(body_chunks[1], wrapped.read(150))"},{"line_number":58,"context_line":"        self.assertEqual(b\u0027\u0027, wrapped.read(150))"},{"line_number":59,"context_line":"        self.assertFalse(wrapped.wsgi_input.closed)"}],"source_content_type":"text/x-python","patch_set":5,"id":"23eb6142_2f47822f","line":56,"updated":"2026-08-19 14:42:31.000000000","message":"this is asserting that it is ok for the stream to return only 100 bytes when asked for 150, and yet the stream has 200 bytes. That seems wrong for a file like stream.","commit_id":"dbf87c6022b4fbe020f61b271bf2e91841c2e550"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"15bd9b99cab3ef5e74901b9831890df3574d109e","unresolved":false,"context_lines":[{"line_number":53,"context_line":"            FileLikeIter(iter(body_chunks)), len(body), checksum.crc32(),"},{"line_number":54,"context_line":"            \u0027x-amz-checksum-crc32\u0027, checksum_source)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        self.assertEqual(body_chunks[0], wrapped.read(150))"},{"line_number":57,"context_line":"        self.assertEqual(body_chunks[1], wrapped.read(150))"},{"line_number":58,"context_line":"        self.assertEqual(b\u0027\u0027, wrapped.read(150))"},{"line_number":59,"context_line":"        self.assertFalse(wrapped.wsgi_input.closed)"}],"source_content_type":"text/x-python","patch_set":5,"id":"bfe155fe_6412e174","line":56,"in_reply_to":"23eb6142_2f47822f","updated":"2026-08-19 23:43:00.000000000","message":"Pushed in https://review.opendev.org/c/openstack/swift/+/999457/25..26/test/unit/common/middleware/s3api/test_s3checksum.py#51","commit_id":"dbf87c6022b4fbe020f61b271bf2e91841c2e550"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":25,"context_line":"from swift.common.utils import checksum"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TestChecksummingInput(unittest.TestCase):"},{"line_number":29,"context_line":"    def test_matching_checksum(self):"},{"line_number":30,"context_line":"        body \u003d b\u0027123456789\u0027"},{"line_number":31,"context_line":"        expected_checksum \u003d base64.b64encode("}],"source_content_type":"text/x-python","patch_set":8,"id":"7e20e878_46cb44d7","line":28,"updated":"2026-08-21 13:26:20.000000000","message":"looks like these tests are new; worth calling out in the commit message","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":25,"context_line":"from swift.common.utils import checksum"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TestChecksummingInput(unittest.TestCase):"},{"line_number":29,"context_line":"    def test_matching_checksum(self):"},{"line_number":30,"context_line":"        body \u003d b\u0027123456789\u0027"},{"line_number":31,"context_line":"        expected_checksum \u003d base64.b64encode("}],"source_content_type":"text/x-python","patch_set":8,"id":"62cf45aa_9a493fea","line":28,"in_reply_to":"3d746780_139ecf8f","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":25,"context_line":"from swift.common.utils import checksum"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TestChecksummingInput(unittest.TestCase):"},{"line_number":29,"context_line":"    def test_matching_checksum(self):"},{"line_number":30,"context_line":"        body \u003d b\u0027123456789\u0027"},{"line_number":31,"context_line":"        expected_checksum \u003d base64.b64encode("}],"source_content_type":"text/x-python","patch_set":8,"id":"3d746780_139ecf8f","line":28,"in_reply_to":"7e20e878_46cb44d7","updated":"2026-08-21 17:46:03.000000000","message":"Will do","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        with self.assertRaises(S3InputChecksumTrailerInvalid) as raised:"},{"line_number":69,"context_line":"            wrapped.read()"},{"line_number":70,"context_line":"        self.assertEqual(\u0027x-amz-checksum-crc32\u0027, raised.exception.trailer)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_empty_body(self):"},{"line_number":73,"context_line":"        expected_checksum \u003d base64.b64encode("}],"source_content_type":"text/x-python","patch_set":8,"id":"5c2d6ec3_85ee8a7e","line":70,"updated":"2026-08-21 13:26:20.000000000","message":"claude suggests adding\n\n```\ndiff --git a/test/unit/common/middleware/s3api/test_s3checksum.py b/test/unit/common/middleware/s3api/test_s3checksum.py\nindex a6fcd8f1d..af30d998d 100644\n--- a/test/unit/common/middleware/s3api/test_s3checksum.py\n+++ b/test/unit/common/middleware/s3api/test_s3checksum.py\n@@ -69,6 +69,17 @@ class TestChecksummingInput(unittest.TestCase):\n             wrapped.read()\n         self.assertEqual(\u0027x-amz-checksum-crc32\u0027, raised.exception.trailer)\n \n+    def test_missing_checksum_source(self):\n+        # the client promised a checksum trailer but never sent one\n+        body \u003d b\u0027123456789\u0027\n+        wrapped \u003d ChecksummingInput(\n+            BytesIO(body), len(body), checksum.crc32(),\n+            \u0027x-amz-checksum-crc32\u0027, {})\n+\n+        with self.assertRaises(S3InputChecksumTrailerInvalid) as raised:\n+            wrapped.read()\n+        self.assertEqual(\u0027x-amz-checksum-crc32\u0027, raised.exception.trailer)\n+\n     def test_empty_body(self):\n         expected_checksum \u003d base64.b64encode(\n             checksum.crc32(b\u0027\u0027).digest()).decode(\u0027ascii\u0027)\n\n```","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        with self.assertRaises(S3InputChecksumTrailerInvalid) as raised:"},{"line_number":69,"context_line":"            wrapped.read()"},{"line_number":70,"context_line":"        self.assertEqual(\u0027x-amz-checksum-crc32\u0027, raised.exception.trailer)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_empty_body(self):"},{"line_number":73,"context_line":"        expected_checksum \u003d base64.b64encode("}],"source_content_type":"text/x-python","patch_set":8,"id":"b0279ea1_7d68b42e","line":70,"in_reply_to":"5c2d6ec3_85ee8a7e","updated":"2026-08-21 17:46:03.000000000","message":"I guess this could be good perhaps... I\u0027ll throw it in, thanks Al and Claude!","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        with self.assertRaises(S3InputChecksumTrailerInvalid) as raised:"},{"line_number":69,"context_line":"            wrapped.read()"},{"line_number":70,"context_line":"        self.assertEqual(\u0027x-amz-checksum-crc32\u0027, raised.exception.trailer)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_empty_body(self):"},{"line_number":73,"context_line":"        expected_checksum \u003d base64.b64encode("}],"source_content_type":"text/x-python","patch_set":8,"id":"273299de_b40d7a99","line":70,"in_reply_to":"b0279ea1_7d68b42e","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":113,"context_line":"        self.assertTrue(wrapped.wsgi_input.closed)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":117,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":118,"context_line":"        for algorithm in (\u0027crc32\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":119,"context_line":"            with self.subTest(algorithm\u003dalgorithm):"}],"source_content_type":"text/x-python","patch_set":8,"id":"ebb46457_628636f9","line":116,"updated":"2026-08-21 13:26:20.000000000","message":"please just copy the tests over exactly as they were. That makes it straightforwrad to sign off on the patch.","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":113,"context_line":"        self.assertTrue(wrapped.wsgi_input.closed)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":117,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":118,"context_line":"        for algorithm in (\u0027crc32\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":119,"context_line":"            with self.subTest(algorithm\u003dalgorithm):"}],"source_content_type":"text/x-python","patch_set":8,"id":"ee8d11e6_bc629e24","line":116,"in_reply_to":"6ae86ce1_1b092655","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":113,"context_line":"        self.assertTrue(wrapped.wsgi_input.closed)"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":117,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":118,"context_line":"        for algorithm in (\u0027crc32\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":119,"context_line":"            with self.subTest(algorithm\u003dalgorithm):"}],"source_content_type":"text/x-python","patch_set":8,"id":"6ae86ce1_1b092655","line":116,"in_reply_to":"ebb46457_628636f9","updated":"2026-08-21 17:46:03.000000000","message":"Agree, will be done.","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":115,"context_line":""},{"line_number":116,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":117,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":118,"context_line":"        for algorithm in (\u0027crc32\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":119,"context_line":"            with self.subTest(algorithm\u003dalgorithm):"},{"line_number":120,"context_line":"                hasher \u003d get_checksum_hasher("},{"line_number":121,"context_line":"                    \u0027x-amz-checksum-%s\u0027 % algorithm)"}],"source_content_type":"text/x-python","patch_set":8,"id":"2dc408f6_848d9033","line":118,"updated":"2026-08-21 13:26:20.000000000","message":"I preferred the original rather than using subTest","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":115,"context_line":""},{"line_number":116,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":117,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":118,"context_line":"        for algorithm in (\u0027crc32\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":119,"context_line":"            with self.subTest(algorithm\u003dalgorithm):"},{"line_number":120,"context_line":"                hasher \u003d get_checksum_hasher("},{"line_number":121,"context_line":"                    \u0027x-amz-checksum-%s\u0027 % algorithm)"}],"source_content_type":"text/x-python","patch_set":8,"id":"e9f735a2_c1e2cceb","line":118,"in_reply_to":"2dc408f6_848d9033","updated":"2026-08-21 17:46:03.000000000","message":"Yea these subtests don\u0027t look the best","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":115,"context_line":""},{"line_number":116,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":117,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":118,"context_line":"        for algorithm in (\u0027crc32\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":119,"context_line":"            with self.subTest(algorithm\u003dalgorithm):"},{"line_number":120,"context_line":"                hasher \u003d get_checksum_hasher("},{"line_number":121,"context_line":"                    \u0027x-amz-checksum-%s\u0027 % algorithm)"}],"source_content_type":"text/x-python","patch_set":8,"id":"b7a213c5_afe8ef76","line":118,"in_reply_to":"e9f735a2_c1e2cceb","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1481642b2b4c27ad538b133fcf2c00dc88a9a450","unresolved":true,"context_lines":[{"line_number":124,"context_line":"        try:"},{"line_number":125,"context_line":"            checksum._select_crc32c_impl()"},{"line_number":126,"context_line":"        except NotImplementedError:"},{"line_number":127,"context_line":"            # Some distributions do not provide a usable implementation."},{"line_number":128,"context_line":"            pass"},{"line_number":129,"context_line":"        else:"},{"line_number":130,"context_line":"            hasher \u003d get_checksum_hasher(\u0027x-amz-checksum-crc32c\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"9c1d6efb_2aed90d7","line":127,"updated":"2026-08-21 13:26:20.000000000","message":"we lost information here","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"a43a364444fd7383ec766c701e32714d7cc48661","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        try:"},{"line_number":125,"context_line":"            checksum._select_crc32c_impl()"},{"line_number":126,"context_line":"        except NotImplementedError:"},{"line_number":127,"context_line":"            # Some distributions do not provide a usable implementation."},{"line_number":128,"context_line":"            pass"},{"line_number":129,"context_line":"        else:"},{"line_number":130,"context_line":"            hasher \u003d get_checksum_hasher(\u0027x-amz-checksum-crc32c\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"2ad7ecee_c8b279a8","line":127,"in_reply_to":"1f52b936_3c727f9d","updated":"2026-08-21 17:47:43.000000000","message":"Done","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"6e581ef33b863d49e6527dcf7eb7f098cad43b84","unresolved":true,"context_lines":[{"line_number":124,"context_line":"        try:"},{"line_number":125,"context_line":"            checksum._select_crc32c_impl()"},{"line_number":126,"context_line":"        except NotImplementedError:"},{"line_number":127,"context_line":"            # Some distributions do not provide a usable implementation."},{"line_number":128,"context_line":"            pass"},{"line_number":129,"context_line":"        else:"},{"line_number":130,"context_line":"            hasher \u003d get_checksum_hasher(\u0027x-amz-checksum-crc32c\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"1f52b936_3c727f9d","line":127,"in_reply_to":"9c1d6efb_2aed90d7","updated":"2026-08-21 17:46:03.000000000","message":"Will revert","commit_id":"eb0c8f697f409d6632aefbb59b05731c458c215c"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"435f8ef4d936bb96405205d58e411e2cedbf18f9","unresolved":true,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":130,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":131,"context_line":"        def do_test(crc):"},{"line_number":132,"context_line":"            hasher \u003d _get_checksum_hasher(\u0027x-amz-checksum-%s\u0027 % crc)"},{"line_number":133,"context_line":"            self.assertEqual(crc, hasher.name)"}],"source_content_type":"text/x-python","patch_set":11,"id":"78aeedb8_7f822830","line":130,"range":{"start_line":130,"start_character":0,"end_line":130,"end_character":39},"updated":"2026-08-24 18:38:30.000000000","message":"so it seems we\u0027re testing an s3request func in s3checksum... not sure this should be here?","commit_id":"d33cc271cc0dde8e8c4962a33f217fb30c3eb86b"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"231b22ed6bf15705ca43c4d3ce5153a565f4c70a","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":130,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":131,"context_line":"        def do_test(crc):"},{"line_number":132,"context_line":"            hasher \u003d _get_checksum_hasher(\u0027x-amz-checksum-%s\u0027 % crc)"},{"line_number":133,"context_line":"            self.assertEqual(crc, hasher.name)"}],"source_content_type":"text/x-python","patch_set":11,"id":"089de7ac_f981b9d8","line":130,"range":{"start_line":130,"start_character":0,"end_line":130,"end_character":39},"in_reply_to":"15863faa_49e2282c","updated":"2026-08-24 23:32:16.000000000","message":"Done","commit_id":"d33cc271cc0dde8e8c4962a33f217fb30c3eb86b"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"315844013db3cbbfd5971454619f70e13ef7fb9a","unresolved":true,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":130,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":131,"context_line":"        def do_test(crc):"},{"line_number":132,"context_line":"            hasher \u003d _get_checksum_hasher(\u0027x-amz-checksum-%s\u0027 % crc)"},{"line_number":133,"context_line":"            self.assertEqual(crc, hasher.name)"}],"source_content_type":"text/x-python","patch_set":11,"id":"807535c0_eb15f741","line":130,"range":{"start_line":130,"start_character":0,"end_line":130,"end_character":39},"in_reply_to":"78aeedb8_7f822830","updated":"2026-08-24 18:39:57.000000000","message":"not sure these\\*","commit_id":"d33cc271cc0dde8e8c4962a33f217fb30c3eb86b"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"natemartes09@gmail.com","username":"nmartes"},"change_message_id":"64404f6163118a6f7c05e6525682b8f46c5c5151","unresolved":true,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"class TestModuleFunctions(unittest.TestCase):"},{"line_number":130,"context_line":"    def test_get_checksum_hasher(self):"},{"line_number":131,"context_line":"        def do_test(crc):"},{"line_number":132,"context_line":"            hasher \u003d _get_checksum_hasher(\u0027x-amz-checksum-%s\u0027 % crc)"},{"line_number":133,"context_line":"            self.assertEqual(crc, hasher.name)"}],"source_content_type":"text/x-python","patch_set":11,"id":"15863faa_49e2282c","line":130,"range":{"start_line":130,"start_character":0,"end_line":130,"end_character":39},"in_reply_to":"807535c0_eb15f741","updated":"2026-08-24 23:32:05.000000000","message":"Oh good point, fixed!","commit_id":"d33cc271cc0dde8e8c4962a33f217fb30c3eb86b"}]}
