)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b1c9dcb1ce8c156ad67993cf9b3ab9100b2338","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"43cd0981_ad1e01f8","updated":"2025-02-21 09:00:10.000000000","message":"LGTM after rebase but someone else should approve","commit_id":"a75329b4205e37938c15e40c7ab8b4508487762a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5d9a544749b0786a147ab03fb9ee4c3bd3e5b2fa","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"65eb68b8_77da52c5","updated":"2025-02-25 10:18:35.000000000","message":"recheck\n\nthe dsvm tests failed with \n```\nTask \nCreate primary S3 user\n  failed running on host \ncontroller\nopenstack --os-auth-url http://localhost/identity --os-project-domain-id default --os-project-name admin --os-user-domain-id default --os-username admin --os-password secretadmin credential create --type ec2 --project swiftprojecttest1 swiftusertest1 \u0027{\"access\": \"s3-user1\", \"secret\": \"s3-secret1\"}\u0027\nnon-zero return code\nBadRequestException: 400: Client Error for url: http://[2001:4802:7805:104:be76:4eff:fe20:123c]/identity/v3/credentials, Invalid input for field/attribute credential. Value: {\u0027type\u0027: \u0027ec2\u0027, \u0027blob\u0027: \u0027{\"access\": \"s3-user1\", \"secret\": \"s3-secret1\"}\u0027}. \u0027user_id\u0027 is a required property\n```","commit_id":"a75329b4205e37938c15e40c7ab8b4508487762a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7132dfd4760770e898460c1a67f6b9102be7cc73","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"c595e0c1_c62d004d","updated":"2025-02-25 19:38:44.000000000","message":"Boo! Simple `Depends-On` isn\u0027t enough; will need to wait for a release and then an update to upper-constraints...","commit_id":"a0d101113c414e841abc4fb041a5d06a3f7f3790"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0704b97f94f5df311a61d5cce8a19a02bac431a2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"b810640f_744f23af","updated":"2025-02-25 18:33:12.000000000","message":"Going to need the OSC change to land to unblock the gate, but this still LGTM.","commit_id":"a0d101113c414e841abc4fb041a5d06a3f7f3790"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6d4021b5386c42690d584e599aa7ceef985bf032","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"21fb2d16_c2f99447","updated":"2025-02-26 16:39:06.000000000","message":"Alternate tack: push for a revert to `python-openstackclient\u003d\u003d7.2.1`. Fix has landed, but IDK when they\u0027re planning another release -- seems like there are some other issues getting addressed with Neutron? Either way we\u0027ll be waiting on a `requirements` change, so let\u0027s try to avoid waiting on a `releases` change *as well*.","commit_id":"fa22e0c08429ecc9630a22e6709303ed331ac8a4"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b5c0ed051c38b24bd28d9d4d29d281ce2bb7de9e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"d08f244f_d19de4b5","updated":"2025-03-02 22:39:47.000000000","message":"recheck","commit_id":"e4cc228ed09eb30a4e186515f801d9cde0140c4d"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee24f7ecab900505d42b99c3953c84b33a50dad8","unresolved":true,"context_lines":[{"line_number":155,"context_line":"        self._hasher.update(chunk)"},{"line_number":156,"context_line":"        self._to_read -\u003d len(chunk)"},{"line_number":157,"context_line":"        if requested_size is None:"},{"line_number":158,"context_line":"            short_read \u003d bool(chunk)"},{"line_number":159,"context_line":"        else:"},{"line_number":160,"context_line":"            short_read \u003d len(chunk) \u003c requested_size"},{"line_number":161,"context_line":"        if self._to_read \u003c 0 or (short_read and self._to_read) or ("}],"source_content_type":"text/x-python","patch_set":1,"id":"8a7edb84_f7f70f0c","line":158,"updated":"2025-01-23 20:14:11.000000000","message":"Off-topic: Something about the rephrasing makes me realize this feels off -- like it should probably be `short_read \u003d bool(self._to_read)` and below we can simplify to `... or short_read or ...`\n\n... at least, assuming `read` -- as for `readline`... 🤔","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"531036bf6526012ebb645e6f0221df426c065cd3","unresolved":false,"context_lines":[{"line_number":155,"context_line":"        self._hasher.update(chunk)"},{"line_number":156,"context_line":"        self._to_read -\u003d len(chunk)"},{"line_number":157,"context_line":"        if requested_size is None:"},{"line_number":158,"context_line":"            short_read \u003d bool(chunk)"},{"line_number":159,"context_line":"        else:"},{"line_number":160,"context_line":"            short_read \u003d len(chunk) \u003c requested_size"},{"line_number":161,"context_line":"        if self._to_read \u003c 0 or (short_read and self._to_read) or ("}],"source_content_type":"text/x-python","patch_set":1,"id":"301619a3_9092d3e2","line":158,"in_reply_to":"47a7208c_10583b8f","updated":"2025-01-28 12:25:06.000000000","message":"Done","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa0454d34e4fc38dbdbeb8be7b5efa2381e21a0a","unresolved":true,"context_lines":[{"line_number":155,"context_line":"        self._hasher.update(chunk)"},{"line_number":156,"context_line":"        self._to_read -\u003d len(chunk)"},{"line_number":157,"context_line":"        if requested_size is None:"},{"line_number":158,"context_line":"            short_read \u003d bool(chunk)"},{"line_number":159,"context_line":"        else:"},{"line_number":160,"context_line":"            short_read \u003d len(chunk) \u003c requested_size"},{"line_number":161,"context_line":"        if self._to_read \u003c 0 or (short_read and self._to_read) or ("}],"source_content_type":"text/x-python","patch_set":1,"id":"47a7208c_10583b8f","line":158,"in_reply_to":"8a7edb84_f7f70f0c","updated":"2025-01-24 13:08:40.000000000","message":"I\u0027m going to try re-phrasing this - we also ought to re-use self.bytes_received\n\n``short-read`` is a misnomer because when size is None the read is only short if it also turns out that there are more expected bytes, which I think is what you\u0027re saying too","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c525c56491b205b2db641add538c05853d6fb45b","unresolved":true,"context_lines":[{"line_number":133,"context_line":"        self.computed \u003d computed"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"class HashingInput(InputProxy):"},{"line_number":137,"context_line":"    \"\"\""},{"line_number":138,"context_line":"    wsgi.input wrapper to verify the hash of the input as it\u0027s read."},{"line_number":139,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"ecf28b06_1a3883a8","line":136,"updated":"2025-01-24 17:22:40.000000000","message":"this has never supported readline, so I guess we never call it in this context, but should we make that lack of support explicit by over-riding readline() in this subclass?","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63ef512809df59ba4abcf7f8984f2a235575874f","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        self.computed \u003d computed"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"class HashingInput(InputProxy):"},{"line_number":137,"context_line":"    \"\"\""},{"line_number":138,"context_line":"    wsgi.input wrapper to verify the hash of the input as it\u0027s read."},{"line_number":139,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"826a0c1e_c03541bc","line":136,"in_reply_to":"7875c5ff_eeaf32ee","updated":"2025-01-29 10:17:48.000000000","message":"Done","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fbe4677c11c2b3596d48a6c662336137df4a614b","unresolved":true,"context_lines":[{"line_number":133,"context_line":"        self.computed \u003d computed"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"class HashingInput(InputProxy):"},{"line_number":137,"context_line":"    \"\"\""},{"line_number":138,"context_line":"    wsgi.input wrapper to verify the hash of the input as it\u0027s read."},{"line_number":139,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"fcb137f8_48ec2591","line":136,"in_reply_to":"ecf28b06_1a3883a8","updated":"2025-01-24 18:49:20.000000000","message":"I\u0027m torn about it -- on the one hand, we depend upon `readline` not being called, or we\u0027ll get a false-positive when we check `len(chunk) \u003c requested_size`; on the other, if we\u0027re offering it as a wsgi.input, it really _should_ have a `readline`...","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed1c540f7372982bd8e48aaf3a5d348cb5d45917","unresolved":true,"context_lines":[{"line_number":133,"context_line":"        self.computed \u003d computed"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"class HashingInput(InputProxy):"},{"line_number":137,"context_line":"    \"\"\""},{"line_number":138,"context_line":"    wsgi.input wrapper to verify the hash of the input as it\u0027s read."},{"line_number":139,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"7875c5ff_eeaf32ee","line":136,"in_reply_to":"fcb137f8_48ec2591","updated":"2025-01-28 12:24:08.000000000","message":"moot if we can detect eof in either case","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fbe4677c11c2b3596d48a6c662336137df4a614b","unresolved":true,"context_lines":[{"line_number":155,"context_line":"        self._hasher.update(chunk)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":158,"context_line":"            error \u003d (requested_size is None) or (len(chunk) \u003c requested_size)"},{"line_number":159,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":160,"context_line":"            error \u003d self._hasher.hexdigest() !\u003d self._expected_hash.lower()"},{"line_number":161,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"05fd1163_c687c905","line":158,"updated":"2025-01-24 18:49:20.000000000","message":"So this is where the `read`/`readline` behavior difference really comes in -- I wonder if we could change the extra arg to be a boolean indicating whether the `InputProxy` thinks we\u0027re at EOF?\n\nThen `read` would check for something like `size is None or len(chunk) \u003c size`\n\nAnd `readline` would check for `chunk[-1] !\u003d \u0027\\n\u0027 and len(chunk) !\u003d size`","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed1c540f7372982bd8e48aaf3a5d348cb5d45917","unresolved":true,"context_lines":[{"line_number":155,"context_line":"        self._hasher.update(chunk)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":158,"context_line":"            error \u003d (requested_size is None) or (len(chunk) \u003c requested_size)"},{"line_number":159,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":160,"context_line":"            error \u003d self._hasher.hexdigest() !\u003d self._expected_hash.lower()"},{"line_number":161,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"0845975a_53dd7779","line":158,"in_reply_to":"05fd1163_c687c905","updated":"2025-01-28 12:24:08.000000000","message":"I tried to pass an eof arg in my first draft but gave up because I was trying to detect it in the call when the final bytes were read, which isn\u0027t possible when the request size equals the remaining bytes. But now I see we can detect it on the call *after* the final bytes have been read (which I think is same as the existing short_read stuff).","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63ef512809df59ba4abcf7f8984f2a235575874f","unresolved":false,"context_lines":[{"line_number":155,"context_line":"        self._hasher.update(chunk)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":158,"context_line":"            error \u003d (requested_size is None) or (len(chunk) \u003c requested_size)"},{"line_number":159,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":160,"context_line":"            error \u003d self._hasher.hexdigest() !\u003d self._expected_hash.lower()"},{"line_number":161,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"5efc7d11_7faeaa7e","line":158,"in_reply_to":"0845975a_53dd7779","updated":"2025-01-29 10:17:48.000000000","message":"Done","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fbe4677c11c2b3596d48a6c662336137df4a614b","unresolved":true,"context_lines":[{"line_number":159,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":160,"context_line":"            error \u003d self._hasher.hexdigest() !\u003d self._expected_hash.lower()"},{"line_number":161,"context_line":"        else:"},{"line_number":162,"context_line":"            error \u003d self.bytes_received \u003e self._expected_length"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"        if error:"},{"line_number":165,"context_line":"            self.close()"}],"source_content_type":"text/x-python","patch_set":3,"id":"cc4d0a3e_e38e3fa1","line":162,"range":{"start_line":162,"start_character":20,"end_line":162,"end_character":63},"updated":"2025-01-24 18:49:20.000000000","message":"This is just `True`, right?","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6b7bc92093f7c3a54d9b27fbf4c3a1cd9427fafe","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":160,"context_line":"            error \u003d self._hasher.hexdigest() !\u003d self._expected_hash.lower()"},{"line_number":161,"context_line":"        else:"},{"line_number":162,"context_line":"            error \u003d self.bytes_received \u003e self._expected_length"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"        if error:"},{"line_number":165,"context_line":"            self.close()"}],"source_content_type":"text/x-python","patch_set":3,"id":"53e9407e_13cc73a0","line":162,"range":{"start_line":162,"start_character":20,"end_line":162,"end_character":63},"in_reply_to":"0adefd95_9e4dc4df","updated":"2025-01-29 02:33:57.000000000","message":"Done","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed1c540f7372982bd8e48aaf3a5d348cb5d45917","unresolved":true,"context_lines":[{"line_number":159,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":160,"context_line":"            error \u003d self._hasher.hexdigest() !\u003d self._expected_hash.lower()"},{"line_number":161,"context_line":"        else:"},{"line_number":162,"context_line":"            error \u003d self.bytes_received \u003e self._expected_length"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"        if error:"},{"line_number":165,"context_line":"            self.close()"}],"source_content_type":"text/x-python","patch_set":3,"id":"0adefd95_9e4dc4df","line":162,"range":{"start_line":162,"start_character":20,"end_line":162,"end_character":63},"in_reply_to":"cc4d0a3e_e38e3fa1","updated":"2025-01-28 12:24:08.000000000","message":"duh, of course","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"}],"swift/common/utils/__init__.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee24f7ecab900505d42b99c3953c84b33a50dad8","unresolved":true,"context_lines":[{"line_number":505,"context_line":"        read([size]) -\u003e read at most size bytes, returned as a bytes string."},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"        If the size argument is negative or omitted, read until EOF is reached."},{"line_number":508,"context_line":"        Notice that when in non-blocking mode, less data than what was"},{"line_number":509,"context_line":"        requested may be returned, even if no size parameter was given."},{"line_number":510,"context_line":"        \"\"\""},{"line_number":511,"context_line":"        size \u003d -1 if size is None else size"},{"line_number":512,"context_line":"        if self.closed:"}],"source_content_type":"text/x-python","patch_set":1,"id":"92c3c4ab_ebc3b954","line":509,"range":{"start_line":508,"start_character":47,"end_line":509,"end_character":70},"updated":"2025-01-23 20:14:11.000000000","message":"Off-topic: I don\u0027t understand what this means. If no size parameter was given, then we didn\u0027t actually \"request\" any particular amount, so how can we receive \"less data than what was requested\"?\n\nEven if we take the absence of a size parameter to mean that we requested to read until EOF is reached... I don\u0027t see what would cause us to return less data than that.","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa0454d34e4fc38dbdbeb8be7b5efa2381e21a0a","unresolved":true,"context_lines":[{"line_number":505,"context_line":"        read([size]) -\u003e read at most size bytes, returned as a bytes string."},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"        If the size argument is negative or omitted, read until EOF is reached."},{"line_number":508,"context_line":"        Notice that when in non-blocking mode, less data than what was"},{"line_number":509,"context_line":"        requested may be returned, even if no size parameter was given."},{"line_number":510,"context_line":"        \"\"\""},{"line_number":511,"context_line":"        size \u003d -1 if size is None else size"},{"line_number":512,"context_line":"        if self.closed:"}],"source_content_type":"text/x-python","patch_set":1,"id":"d423d7e0_d25fc1f3","line":509,"range":{"start_line":508,"start_character":47,"end_line":509,"end_character":70},"in_reply_to":"92c3c4ab_ebc3b954","updated":"2025-01-24 13:08:40.000000000","message":"My guess is that this text was inpsired by some (old) python interface e.g. https://python-reference.readthedocs.io/en/latest/docs/file/read.html says \"Also note that when in non-blocking mode, less data than was requested may be returned, even if no size parameter was given.\"\n\nIn a non-blocking context, and given that size means read until EOF, it does make sense that you may get back less than you asked for. But that\u0027s no the context here.\n\nI\u0027ll try to re-word, and update the docstring formatting","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"531036bf6526012ebb645e6f0221df426c065cd3","unresolved":false,"context_lines":[{"line_number":505,"context_line":"        read([size]) -\u003e read at most size bytes, returned as a bytes string."},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"        If the size argument is negative or omitted, read until EOF is reached."},{"line_number":508,"context_line":"        Notice that when in non-blocking mode, less data than what was"},{"line_number":509,"context_line":"        requested may be returned, even if no size parameter was given."},{"line_number":510,"context_line":"        \"\"\""},{"line_number":511,"context_line":"        size \u003d -1 if size is None else size"},{"line_number":512,"context_line":"        if self.closed:"}],"source_content_type":"text/x-python","patch_set":1,"id":"8e3a0060_9e89e149","line":509,"range":{"start_line":508,"start_character":47,"end_line":509,"end_character":70},"in_reply_to":"d423d7e0_d25fc1f3","updated":"2025-01-28 12:25:06.000000000","message":"Done","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee24f7ecab900505d42b99c3953c84b33a50dad8","unresolved":true,"context_lines":[{"line_number":2527,"context_line":"        self.bytes_received \u003d 0"},{"line_number":2528,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2529,"context_line":""},{"line_number":2530,"context_line":"    def chunk_update(self, chunk, requested_size\u003dNone, *args, **kwargs):"},{"line_number":2531,"context_line":"        # subclasses may override this method; either the given chunk or an"},{"line_number":2532,"context_line":"        # alternative chunk value should be returned"},{"line_number":2533,"context_line":"        return chunk"}],"source_content_type":"text/x-python","patch_set":1,"id":"059670c9_4130fe16","line":2530,"range":{"start_line":2530,"start_character":34,"end_line":2530,"end_character":53},"updated":"2025-01-23 20:14:11.000000000","message":"I feel like this isn\u0027t going to be enough information -- the `requested_size` means very different things depending on whether you\u0027re calling `read` or `readline`:\n- with `read`, we try to read exactly `requested_size` bytes and should only return smaller `chunk`s because of EOFs or timeouts, but\n- with `readline`, we want to read _up to_ `requested_size` bytes while looking for a newline, and should fairly often return smaller `chunk`s","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa0454d34e4fc38dbdbeb8be7b5efa2381e21a0a","unresolved":true,"context_lines":[{"line_number":2527,"context_line":"        self.bytes_received \u003d 0"},{"line_number":2528,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2529,"context_line":""},{"line_number":2530,"context_line":"    def chunk_update(self, chunk, requested_size\u003dNone, *args, **kwargs):"},{"line_number":2531,"context_line":"        # subclasses may override this method; either the given chunk or an"},{"line_number":2532,"context_line":"        # alternative chunk value should be returned"},{"line_number":2533,"context_line":"        return chunk"}],"source_content_type":"text/x-python","patch_set":1,"id":"cfa11654_714ec0ef","line":2530,"range":{"start_line":2530,"start_character":34,"end_line":2530,"end_character":53},"in_reply_to":"059670c9_4130fe16","updated":"2025-01-24 13:08:40.000000000","message":"I\u0027ll add a docstring here to be clear that requested_size is simply whatever size was passed in to read or readline. There\u0027s no claim as to it\u0027s usefulness.\n\nIt\u0027s up to a subclass to decide what to do with ``requested_size``. In the case of the HashingInput it assumes that readline is not called (in fact on master readline is not even implemented). Maybe I should override readline in that class to raise NotImplemented ??","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed1c540f7372982bd8e48aaf3a5d348cb5d45917","unresolved":true,"context_lines":[{"line_number":2527,"context_line":"        self.bytes_received \u003d 0"},{"line_number":2528,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2529,"context_line":""},{"line_number":2530,"context_line":"    def chunk_update(self, chunk, requested_size\u003dNone, *args, **kwargs):"},{"line_number":2531,"context_line":"        # subclasses may override this method; either the given chunk or an"},{"line_number":2532,"context_line":"        # alternative chunk value should be returned"},{"line_number":2533,"context_line":"        return chunk"}],"source_content_type":"text/x-python","patch_set":1,"id":"842f4ce9_3123c00d","line":2530,"range":{"start_line":2530,"start_character":34,"end_line":2530,"end_character":53},"in_reply_to":"350ab22d_cbe25d9e","updated":"2025-01-28 12:24:08.000000000","message":"My point was that it may be (and in fact is) useful to subclasses but the superclass doesn\u0027t need to demonstrate or document it\u0027s usefulness.\n\nBut, moot if we pass an eof flag instead","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63ef512809df59ba4abcf7f8984f2a235575874f","unresolved":false,"context_lines":[{"line_number":2527,"context_line":"        self.bytes_received \u003d 0"},{"line_number":2528,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2529,"context_line":""},{"line_number":2530,"context_line":"    def chunk_update(self, chunk, requested_size\u003dNone, *args, **kwargs):"},{"line_number":2531,"context_line":"        # subclasses may override this method; either the given chunk or an"},{"line_number":2532,"context_line":"        # alternative chunk value should be returned"},{"line_number":2533,"context_line":"        return chunk"}],"source_content_type":"text/x-python","patch_set":1,"id":"24cb198e_84b162b0","line":2530,"range":{"start_line":2530,"start_character":34,"end_line":2530,"end_character":53},"in_reply_to":"842f4ce9_3123c00d","updated":"2025-01-29 10:17:48.000000000","message":"Done","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fbe4677c11c2b3596d48a6c662336137df4a614b","unresolved":true,"context_lines":[{"line_number":2527,"context_line":"        self.bytes_received \u003d 0"},{"line_number":2528,"context_line":"        self.client_disconnect \u003d False"},{"line_number":2529,"context_line":""},{"line_number":2530,"context_line":"    def chunk_update(self, chunk, requested_size\u003dNone, *args, **kwargs):"},{"line_number":2531,"context_line":"        # subclasses may override this method; either the given chunk or an"},{"line_number":2532,"context_line":"        # alternative chunk value should be returned"},{"line_number":2533,"context_line":"        return chunk"}],"source_content_type":"text/x-python","patch_set":1,"id":"350ab22d_cbe25d9e","line":2530,"range":{"start_line":2530,"start_character":34,"end_line":2530,"end_character":53},"in_reply_to":"cfa11654_714ec0ef","updated":"2025-01-24 18:49:20.000000000","message":"\u003e There\u0027s no claim as to it\u0027s usefulness.\n\nFeels like we should tinker with what we could offer as an API until it *is* something useful 😉\n\nMaybe `def chunk_update(self, chunk, eof: bool):`?","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee24f7ecab900505d42b99c3953c84b33a50dad8","unresolved":true,"context_lines":[{"line_number":2556,"context_line":"            self.client_disconnect \u003d True"},{"line_number":2557,"context_line":"            raise"},{"line_number":2558,"context_line":"        self.bytes_received +\u003d len(line)"},{"line_number":2559,"context_line":"        return self.chunk_update(line, requested_size\u003dNone)"},{"line_number":2560,"context_line":""},{"line_number":2561,"context_line":"    def close(self):"},{"line_number":2562,"context_line":"        close_if_possible(self.wsgi_input)"}],"source_content_type":"text/x-python","patch_set":1,"id":"e3971031_e51a7406","line":2559,"range":{"start_line":2559,"start_character":39,"end_line":2559,"end_character":58},"updated":"2025-01-23 20:14:11.000000000","message":"Always `None`? But [the spec says](https://peps.python.org/pep-3333/#input-and-error-streams)\n\n\u003e Servers **should** support the optional “size” argument to `readline()`\n\nIf the application sent a size, and we pass it through, why are we lying about it here?","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"531036bf6526012ebb645e6f0221df426c065cd3","unresolved":false,"context_lines":[{"line_number":2556,"context_line":"            self.client_disconnect \u003d True"},{"line_number":2557,"context_line":"            raise"},{"line_number":2558,"context_line":"        self.bytes_received +\u003d len(line)"},{"line_number":2559,"context_line":"        return self.chunk_update(line, requested_size\u003dNone)"},{"line_number":2560,"context_line":""},{"line_number":2561,"context_line":"    def close(self):"},{"line_number":2562,"context_line":"        close_if_possible(self.wsgi_input)"}],"source_content_type":"text/x-python","patch_set":1,"id":"b50aa9cd_4d7af182","line":2559,"range":{"start_line":2559,"start_character":39,"end_line":2559,"end_character":58},"in_reply_to":"d29f30ea_9ec05588","updated":"2025-01-28 12:25:06.000000000","message":"Done","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa0454d34e4fc38dbdbeb8be7b5efa2381e21a0a","unresolved":true,"context_lines":[{"line_number":2556,"context_line":"            self.client_disconnect \u003d True"},{"line_number":2557,"context_line":"            raise"},{"line_number":2558,"context_line":"        self.bytes_received +\u003d len(line)"},{"line_number":2559,"context_line":"        return self.chunk_update(line, requested_size\u003dNone)"},{"line_number":2560,"context_line":""},{"line_number":2561,"context_line":"    def close(self):"},{"line_number":2562,"context_line":"        close_if_possible(self.wsgi_input)"}],"source_content_type":"text/x-python","patch_set":1,"id":"d29f30ea_9ec05588","line":2559,"range":{"start_line":2559,"start_character":39,"end_line":2559,"end_character":58},"in_reply_to":"e3971031_e51a7406","updated":"2025-01-24 13:08:40.000000000","message":"fixed","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fbe4677c11c2b3596d48a6c662336137df4a614b","unresolved":true,"context_lines":[{"line_number":592,"context_line":""},{"line_number":593,"context_line":"    def close(self):"},{"line_number":594,"context_line":"        \"\"\""},{"line_number":595,"context_line":"        Close the iter."},{"line_number":596,"context_line":""},{"line_number":597,"context_line":"        Once close() has been called the iter cannot be used for further I/O"},{"line_number":598,"context_line":"        operations. close() may be called more than once without error."}],"source_content_type":"text/x-python","patch_set":3,"id":"fb382618_7877e87a","line":595,"updated":"2025-01-24 18:49:20.000000000","message":"I wonder if we should have a `close_if_possible(self.iterator)`...","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6b7bc92093f7c3a54d9b27fbf4c3a1cd9427fafe","unresolved":true,"context_lines":[{"line_number":592,"context_line":""},{"line_number":593,"context_line":"    def close(self):"},{"line_number":594,"context_line":"        \"\"\""},{"line_number":595,"context_line":"        Close the iter."},{"line_number":596,"context_line":""},{"line_number":597,"context_line":"        Once close() has been called the iter cannot be used for further I/O"},{"line_number":598,"context_line":"        operations. close() may be called more than once without error."}],"source_content_type":"text/x-python","patch_set":3,"id":"83080140_62e5e5bd","line":595,"in_reply_to":"2d95fad5_afc73165","updated":"2025-01-29 02:33:57.000000000","message":"In that case, touching `FileLikeIter` at all feels out-of-scope 😜","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63ef512809df59ba4abcf7f8984f2a235575874f","unresolved":true,"context_lines":[{"line_number":592,"context_line":""},{"line_number":593,"context_line":"    def close(self):"},{"line_number":594,"context_line":"        \"\"\""},{"line_number":595,"context_line":"        Close the iter."},{"line_number":596,"context_line":""},{"line_number":597,"context_line":"        Once close() has been called the iter cannot be used for further I/O"},{"line_number":598,"context_line":"        operations. close() may be called more than once without error."}],"source_content_type":"text/x-python","patch_set":3,"id":"71f4a9df_219d5a99","line":595,"in_reply_to":"83080140_62e5e5bd","updated":"2025-01-29 10:17:48.000000000","message":"The changes in FileLikeIter are necessary to support InputProxy wrapping FileLikeIter (which happens in some tests e.g. test_encrypter). InputProxy passes ``size\u003dNone`` with read, the EncInputWrapper in encrypter.py did not.\n\nPEP3333 https://peps.python.org/pep-3333/#input-and-error-streams unhelpfully doesn\u0027t specify the default value of ``size`` but says that semantics are as per python, which AFAICT defines default ``size\u003d-1``. So perhaps Swift has the read() signature wrong in a bunch of places, but in practice ``size\u003dNone`` is accepted by all the python io streams I tried.","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed1c540f7372982bd8e48aaf3a5d348cb5d45917","unresolved":true,"context_lines":[{"line_number":592,"context_line":""},{"line_number":593,"context_line":"    def close(self):"},{"line_number":594,"context_line":"        \"\"\""},{"line_number":595,"context_line":"        Close the iter."},{"line_number":596,"context_line":""},{"line_number":597,"context_line":"        Once close() has been called the iter cannot be used for further I/O"},{"line_number":598,"context_line":"        operations. close() may be called more than once without error."}],"source_content_type":"text/x-python","patch_set":3,"id":"2d95fad5_afc73165","line":595,"in_reply_to":"fb382618_7877e87a","updated":"2025-01-28 12:24:08.000000000","message":"probably, but I\u0027m going to draw a line on the scope of this patch (one line change but more tests)","commit_id":"ff8ec22d9591fc5d9a8ce22b9c15e471ecce2462"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6b7bc92093f7c3a54d9b27fbf4c3a1cd9427fafe","unresolved":true,"context_lines":[{"line_number":2541,"context_line":"        Called each time a chunk of bytes is read from the wrapped input."},{"line_number":2542,"context_line":""},{"line_number":2543,"context_line":"        :param chunk: the chunk of bytes that has been read."},{"line_number":2544,"context_line":"        :param eof: ``True`` if there are no more bytes to read from the"},{"line_number":2545,"context_line":"            wrapped input, ``False`` otherwise. If ``read()`` has been called"},{"line_number":2546,"context_line":"            this will be ``True`` when the size of ``chunk`` is less than the"},{"line_number":2547,"context_line":"            requested size or the requested size is None. If ``readline`` has"}],"source_content_type":"text/x-python","patch_set":4,"id":"547e3bac_903900a6","line":2544,"updated":"2025-01-29 02:33:57.000000000","message":"Docs build is failing with warnings here, but I\u0027m having trouble making sense of them:\n```\n/home/zuul/src/opendev.org/openstack/swift/swift/common/utils/__init__.py:docstring of swift.common.utils.InputProxy.chunk_update:4: WARNING: Inline literal start-string without end-string. [docutils]\n/home/zuul/src/opendev.org/openstack/swift/swift/common/utils/__init__.py:docstring of swift.common.utils.InputProxy.chunk_update:10: WARNING: Block quote ends without a blank line; unexpected unindent. [docutils]\n/home/zuul/src/opendev.org/openstack/swift/swift/common/utils/__init__.py:docstring of swift.common.utils.InputProxy.chunk_update:10: WARNING: Inline literal start-string without end-string. [docutils]\n```\nMaybe we want `r\"\"\"` at the start, so the `\\n` isn\u0027t taken to be an actual newline?","commit_id":"7c9b1b8f6d1318d5dc394bca8a1a2130df0a14e4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63ef512809df59ba4abcf7f8984f2a235575874f","unresolved":false,"context_lines":[{"line_number":2541,"context_line":"        Called each time a chunk of bytes is read from the wrapped input."},{"line_number":2542,"context_line":""},{"line_number":2543,"context_line":"        :param chunk: the chunk of bytes that has been read."},{"line_number":2544,"context_line":"        :param eof: ``True`` if there are no more bytes to read from the"},{"line_number":2545,"context_line":"            wrapped input, ``False`` otherwise. If ``read()`` has been called"},{"line_number":2546,"context_line":"            this will be ``True`` when the size of ``chunk`` is less than the"},{"line_number":2547,"context_line":"            requested size or the requested size is None. If ``readline`` has"}],"source_content_type":"text/x-python","patch_set":4,"id":"5d9fb467_fb3529a7","line":2544,"in_reply_to":"547e3bac_903900a6","updated":"2025-01-29 10:17:48.000000000","message":"\u0027\\\u0027 needs escaping","commit_id":"7c9b1b8f6d1318d5dc394bca8a1a2130df0a14e4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6b7bc92093f7c3a54d9b27fbf4c3a1cd9427fafe","unresolved":true,"context_lines":[{"line_number":2546,"context_line":"            this will be ``True`` when the size of ``chunk`` is less than the"},{"line_number":2547,"context_line":"            requested size or the requested size is None. If ``readline`` has"},{"line_number":2548,"context_line":"            been called this will be ``True`` when an incomplete line is read"},{"line_number":2549,"context_line":"            (i.e. not ending with ``b\\n``) whose length is less than the"},{"line_number":2550,"context_line":"            requested size or the requested size is None."},{"line_number":2551,"context_line":"        \"\"\""},{"line_number":2552,"context_line":"        # subclasses may override this method; either the given chunk or an"}],"source_content_type":"text/x-python","patch_set":4,"id":"f8a7e1bd_56ed3fb2","line":2549,"range":{"start_line":2549,"start_character":34,"end_line":2549,"end_character":41},"updated":"2025-01-29 02:33:57.000000000","message":"```\n``b\u0027\\n\u0027``\n```\n? Or\n```\n``b\"\\n\"``\n```","commit_id":"7c9b1b8f6d1318d5dc394bca8a1a2130df0a14e4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63ef512809df59ba4abcf7f8984f2a235575874f","unresolved":false,"context_lines":[{"line_number":2546,"context_line":"            this will be ``True`` when the size of ``chunk`` is less than the"},{"line_number":2547,"context_line":"            requested size or the requested size is None. If ``readline`` has"},{"line_number":2548,"context_line":"            been called this will be ``True`` when an incomplete line is read"},{"line_number":2549,"context_line":"            (i.e. not ending with ``b\\n``) whose length is less than the"},{"line_number":2550,"context_line":"            requested size or the requested size is None."},{"line_number":2551,"context_line":"        \"\"\""},{"line_number":2552,"context_line":"        # subclasses may override this method; either the given chunk or an"}],"source_content_type":"text/x-python","patch_set":4,"id":"55816076_da061a41","line":2549,"range":{"start_line":2549,"start_character":34,"end_line":2549,"end_character":41},"in_reply_to":"f8a7e1bd_56ed3fb2","updated":"2025-01-29 10:17:48.000000000","message":"Done","commit_id":"7c9b1b8f6d1318d5dc394bca8a1a2130df0a14e4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6b7bc92093f7c3a54d9b27fbf4c3a1cd9427fafe","unresolved":true,"context_lines":[{"line_number":2547,"context_line":"            requested size or the requested size is None. If ``readline`` has"},{"line_number":2548,"context_line":"            been called this will be ``True`` when an incomplete line is read"},{"line_number":2549,"context_line":"            (i.e. not ending with ``b\\n``) whose length is less than the"},{"line_number":2550,"context_line":"            requested size or the requested size is None."},{"line_number":2551,"context_line":"        \"\"\""},{"line_number":2552,"context_line":"        # subclasses may override this method; either the given chunk or an"},{"line_number":2553,"context_line":"        # alternative chunk value should be returned"}],"source_content_type":"text/x-python","patch_set":4,"id":"49991fb5_8d58e81c","line":2550,"updated":"2025-01-29 02:33:57.000000000","message":"Might be worth calling out that if `read` is called requesting the exact number of bytes remaining, `eof` will still be `False` (at least on the happy-path).\n\nI.e. subclasses may still need to compare `bytes_received` vs `Content-Length`.","commit_id":"7c9b1b8f6d1318d5dc394bca8a1a2130df0a14e4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63ef512809df59ba4abcf7f8984f2a235575874f","unresolved":false,"context_lines":[{"line_number":2547,"context_line":"            requested size or the requested size is None. If ``readline`` has"},{"line_number":2548,"context_line":"            been called this will be ``True`` when an incomplete line is read"},{"line_number":2549,"context_line":"            (i.e. not ending with ``b\\n``) whose length is less than the"},{"line_number":2550,"context_line":"            requested size or the requested size is None."},{"line_number":2551,"context_line":"        \"\"\""},{"line_number":2552,"context_line":"        # subclasses may override this method; either the given chunk or an"},{"line_number":2553,"context_line":"        # alternative chunk value should be returned"}],"source_content_type":"text/x-python","patch_set":4,"id":"88ce6570_9fd6c521","line":2550,"in_reply_to":"49991fb5_8d58e81c","updated":"2025-01-29 10:17:48.000000000","message":"Done","commit_id":"7c9b1b8f6d1318d5dc394bca8a1a2130df0a14e4"}],"test/unit/common/middleware/s3api/test_s3request.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"05025e252525db050b43d83240a89138a250aeef","unresolved":true,"context_lines":[{"line_number":1475,"context_line":"    def test_good_readline(self):"},{"line_number":1476,"context_line":"        raw \u003d b\u002712345\\n6789\u0027"},{"line_number":1477,"context_line":"        wrapped \u003d HashingInput("},{"line_number":1478,"context_line":"            BytesIO(raw), 10, lambda: md5(usedforsecurity\u003dFalse),"},{"line_number":1479,"context_line":"            md5(raw, usedforsecurity\u003dFalse).hexdigest())"},{"line_number":1480,"context_line":"        self.assertEqual(b\u002712345\\n\u0027, wrapped.readline())"},{"line_number":1481,"context_line":"        self.assertEqual(b\u00276789\u0027, wrapped.readline())"}],"source_content_type":"text/x-python","patch_set":6,"id":"168be609_19078e9e","line":1478,"range":{"start_line":1478,"start_character":30,"end_line":1478,"end_character":64},"updated":"2025-02-21 04:00:56.000000000","message":"The hasher is not being passed in anymore","commit_id":"e64f2ead8e2fee4bb6bfd3ff013642466966d38b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"05025e252525db050b43d83240a89138a250aeef","unresolved":true,"context_lines":[{"line_number":1476,"context_line":"        raw \u003d b\u002712345\\n6789\u0027"},{"line_number":1477,"context_line":"        wrapped \u003d HashingInput("},{"line_number":1478,"context_line":"            BytesIO(raw), 10, lambda: md5(usedforsecurity\u003dFalse),"},{"line_number":1479,"context_line":"            md5(raw, usedforsecurity\u003dFalse).hexdigest())"},{"line_number":1480,"context_line":"        self.assertEqual(b\u002712345\\n\u0027, wrapped.readline())"},{"line_number":1481,"context_line":"        self.assertEqual(b\u00276789\u0027, wrapped.readline())"},{"line_number":1482,"context_line":"        self.assertEqual(b\u0027\u0027, wrapped.readline())"}],"source_content_type":"text/x-python","patch_set":6,"id":"21e68347_e65fff28","line":1479,"range":{"start_line":1479,"start_character":12,"end_line":1479,"end_character":55},"updated":"2025-02-21 04:00:56.000000000","message":"This needs to be a sha256 now right (and the same for the testss below)","commit_id":"e64f2ead8e2fee4bb6bfd3ff013642466966d38b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"05025e252525db050b43d83240a89138a250aeef","unresolved":true,"context_lines":[{"line_number":1520,"context_line":"    def test_too_short_read_all(self):"},{"line_number":1521,"context_line":"        raw \u003d b\u0027123456789\u0027"},{"line_number":1522,"context_line":"        wrapped \u003d HashingInput("},{"line_number":1523,"context_line":"            BytesIO(raw), 10, lambda: md5(usedforsecurity\u003dFalse),"},{"line_number":1524,"context_line":"            md5(raw, usedforsecurity\u003dFalse).hexdigest())"},{"line_number":1525,"context_line":"        with self.assertRaises(S3InputSHA256Mismatch):"},{"line_number":1526,"context_line":"            wrapped.read()"}],"source_content_type":"text/x-python","patch_set":6,"id":"0db1f400_fdada613","line":1523,"range":{"start_line":1523,"start_character":30,"end_line":1523,"end_character":64},"updated":"2025-02-21 04:00:56.000000000","message":"Same here","commit_id":"e64f2ead8e2fee4bb6bfd3ff013642466966d38b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"05025e252525db050b43d83240a89138a250aeef","unresolved":true,"context_lines":[{"line_number":1547,"context_line":"    def test_bad_hash_readline(self):"},{"line_number":1548,"context_line":"        raw \u003d b\u002712345\\n6789\u0027"},{"line_number":1549,"context_line":"        wrapped \u003d HashingInput("},{"line_number":1550,"context_line":"            BytesIO(raw), 10, lambda: md5(usedforsecurity\u003dFalse),"},{"line_number":1551,"context_line":"            md5(raw[:-3], usedforsecurity\u003dFalse).hexdigest())"},{"line_number":1552,"context_line":"        self.assertEqual(b\u002712345\\n\u0027, wrapped.readline())"},{"line_number":1553,"context_line":"        with self.assertRaises(S3InputSHA256Mismatch):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3bb2b359_8979fe40","line":1550,"range":{"start_line":1550,"start_character":30,"end_line":1550,"end_character":64},"updated":"2025-02-21 04:00:56.000000000","message":"And here","commit_id":"e64f2ead8e2fee4bb6bfd3ff013642466966d38b"}],"test/unit/common/middleware/test_formpost.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fe8dfe18c74c05dcec8e87f4904740e54c19542f","unresolved":true,"context_lines":[{"line_number":1945,"context_line":"                                 (\u0027201 Created\u0027, {}, b\u0027\u0027)]))"},{"line_number":1946,"context_line":"        self.auth \u003d tempauth.filter_factory({})(self.app)"},{"line_number":1947,"context_line":"        self.formpost \u003d formpost.filter_factory({})(self.auth)"},{"line_number":1948,"context_line":"        self.formpost.logger \u003d debug_logger()"},{"line_number":1949,"context_line":"        status \u003d [None]"},{"line_number":1950,"context_line":"        headers \u003d [None]"},{"line_number":1951,"context_line":"        exc_info \u003d [None]"}],"source_content_type":"text/x-python","patch_set":1,"id":"d5df6c7f_f9e0299e","line":1948,"updated":"2025-01-23 17:34:21.000000000","message":"oops, not strictly necessary change","commit_id":"755bbfee2fea360a32da572fdafbbe87c49795fa"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6b7bc92093f7c3a54d9b27fbf4c3a1cd9427fafe","unresolved":true,"context_lines":[{"line_number":3137,"context_line":"            ip.read(1)"},{"line_number":3138,"context_line":"            ip.read(1)"},{"line_number":3139,"context_line":"        self.assertEqual([mock.call(b\u0027a\u0027, False),"},{"line_number":3140,"context_line":"                          mock.call(b\u0027bc\u0027, False),"},{"line_number":3141,"context_line":"                          mock.call(b\u0027\u0027, True),"},{"line_number":3142,"context_line":"                          mock.call(b\u0027\u0027, True)], mocked.call_args_list)"},{"line_number":3143,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"292a5f78_a2545f12","line":3140,"updated":"2025-01-29 02:33:57.000000000","message":"This is the subtle part -- if a caller knows *exactly* how many bytes to expect, `eof` may never get tripped. I seem to remember 1space having some trouble tripping 499s or something because of something similar.\n\nIt makes checksum validation a little tricky...","commit_id":"7c9b1b8f6d1318d5dc394bca8a1a2130df0a14e4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"63ef512809df59ba4abcf7f8984f2a235575874f","unresolved":false,"context_lines":[{"line_number":3137,"context_line":"            ip.read(1)"},{"line_number":3138,"context_line":"            ip.read(1)"},{"line_number":3139,"context_line":"        self.assertEqual([mock.call(b\u0027a\u0027, False),"},{"line_number":3140,"context_line":"                          mock.call(b\u0027bc\u0027, False),"},{"line_number":3141,"context_line":"                          mock.call(b\u0027\u0027, True),"},{"line_number":3142,"context_line":"                          mock.call(b\u0027\u0027, True)], mocked.call_args_list)"},{"line_number":3143,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"df1b36fb_0c2698b6","line":3140,"in_reply_to":"292a5f78_a2545f12","updated":"2025-01-29 10:17:48.000000000","message":"Acknowledged","commit_id":"7c9b1b8f6d1318d5dc394bca8a1a2130df0a14e4"}]}
