)]}'
{"swiftclient/client.py":[{"author":{"_account_id":9216,"name":"Joel Wright","email":"joel.wright@gmail.com","username":"jjw-sohonet"},"change_message_id":"84aea50591783c614d2283928e2bbe45b1d39352","unresolved":false,"context_lines":[{"line_number":1514,"context_line":"            if self.retries \u003e 0:"},{"line_number":1515,"context_line":"                tell \u003d getattr(contents, \u0027tell\u0027, None)"},{"line_number":1516,"context_line":"                seek \u003d getattr(contents, \u0027seek\u0027, None)"},{"line_number":1517,"context_line":"                resettable \u003d getattr(contents, \u0027resettable\u0027, False)"},{"line_number":1518,"context_line":"                if tell and seek:"},{"line_number":1519,"context_line":"                    orig_pos \u003d tell()"},{"line_number":1520,"context_line":"                    reset_func \u003d lambda *a, **k: seek(orig_pos)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_b985bccf","line":1517,"updated":"2015-11-18 23:41:17.000000000","message":"nit: I really don\u0027t like this mix of styles. Why do the getattr calls for \u0027tell\u0027 and \u0027seek\u0027 default to None, while the call for \u0027resettable\u0027 defaults to False?\n\nMy preference would be to fix the \u0027tell\u0027 and \u0027seek\u0027 calls and stop using the falsiness of None, but the least we can do is be consistent.","commit_id":"2c1ae6139bf65b134e3e03af8f10c283223b9166"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d968d3728d1f38300cf3421fc95bae0ae3243d","unresolved":false,"context_lines":[{"line_number":1514,"context_line":"            if self.retries \u003e 0:"},{"line_number":1515,"context_line":"                tell \u003d getattr(contents, \u0027tell\u0027, None)"},{"line_number":1516,"context_line":"                seek \u003d getattr(contents, \u0027seek\u0027, None)"},{"line_number":1517,"context_line":"                resettable \u003d getattr(contents, \u0027resettable\u0027, False)"},{"line_number":1518,"context_line":"                if tell and seek:"},{"line_number":1519,"context_line":"                    orig_pos \u003d tell()"},{"line_number":1520,"context_line":"                    reset_func \u003d lambda *a, **k: seek(orig_pos)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_1c8e3679","line":1517,"in_reply_to":"ba8a016a_b985bccf","updated":"2015-11-19 22:45:28.000000000","message":"\u0027resettable\u0027 is expected to be a boolean property (if True, there should be a callable attribute named \u0027reset\u0027, and calling it should get us back to the start of the stream and *totally* not error), while \u0027seek\u0027 and \u0027tell\u0027 are expected to be callables (or just not present).\n\nI could twist this so the presence or absence of \u0027reset\u0027 alone is sufficient to say whether we can use it in reset_func, but it\u0027d get weird and probably run afowl of Clay\u0027s stance on dynamism :P","commit_id":"2c1ae6139bf65b134e3e03af8f10c283223b9166"}],"swiftclient/utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d362a640496491db5e4633de0f56f24aa307ae4f","unresolved":false,"context_lines":[{"line_number":230,"context_line":"        self._remaining -\u003d len(chunk)"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"        try:"},{"line_number":233,"context_line":"            self.md5sum.update(chunk)"},{"line_number":234,"context_line":"        except TypeError:"},{"line_number":235,"context_line":"            self.md5sum.update(chunk.encode())"},{"line_number":236,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7a2fa921_ab140ff5","line":233,"updated":"2015-10-06 13:43:17.000000000","message":"what happens to md5sum after a seek? We must end up updating hash with retried content twice ?","commit_id":"b27856c276030d02fadb34733d57f011be72e96a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e139aef969a9d81be2939b192166b01ee453375c","unresolved":false,"context_lines":[{"line_number":230,"context_line":"        self._remaining -\u003d len(chunk)"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"        try:"},{"line_number":233,"context_line":"            self.md5sum.update(chunk)"},{"line_number":234,"context_line":"        except TypeError:"},{"line_number":235,"context_line":"            self.md5sum.update(chunk.encode())"},{"line_number":236,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7a2fa921_6fca7ca3","line":233,"in_reply_to":"7a2fa921_ab140ff5","updated":"2015-10-06 16:03:54.000000000","message":"Yeah, that should get reset after a seek to the original position. This also means we should probably raise an error (ValueError, I suppose?) if you try to seek anywhere other than the original position.","commit_id":"b27856c276030d02fadb34733d57f011be72e96a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d362a640496491db5e4633de0f56f24aa307ae4f","unresolved":false,"context_lines":[{"line_number":237,"context_line":"        return chunk"},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"    @property"},{"line_number":240,"context_line":"    def seek(self):"},{"line_number":241,"context_line":"        return self._readable.seek"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a2fa921_0b6d0398","line":240,"updated":"2015-10-06 13:43:17.000000000","message":"but self._remaining is not reset so read may return \u0027\u0027 after a seek backwards","commit_id":"b27856c276030d02fadb34733d57f011be72e96a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e139aef969a9d81be2939b192166b01ee453375c","unresolved":false,"context_lines":[{"line_number":237,"context_line":"        return chunk"},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"    @property"},{"line_number":240,"context_line":"    def seek(self):"},{"line_number":241,"context_line":"        return self._readable.seek"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a2fa921_afd3b437","line":240,"in_reply_to":"7a2fa921_0b6d0398","updated":"2015-10-06 16:03:54.000000000","message":"Also a good point. Will fix.","commit_id":"b27856c276030d02fadb34733d57f011be72e96a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2871966573e69ca24ff336227f005dda6df40c8a","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            raise TypeError(\u0027an integer is required\u0027)"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        if type(pos) is not int:"},{"line_number":250,"context_line":"            raise TypeError(\u0027%r object cannot be interpretted as an index\u0027 %"},{"line_number":251,"context_line":"                            type(pos).__name__)"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        old_pos \u003d self._readable.tell()"}],"source_content_type":"text/x-python","patch_set":3,"id":"7a2fa921_0c75f296","line":250,"updated":"2015-10-07 10:03:52.000000000","message":"s/interpretted/interpreted/","commit_id":"40156bb7e3b04e14380a666e9c2e72c838ce9a5c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e99a57734104eb6019876086ee075f0733418e6d","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            raise TypeError(\u0027an integer is required\u0027)"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        if type(pos) is not int:"},{"line_number":250,"context_line":"            raise TypeError(\u0027%r object cannot be interpretted as an index\u0027 %"},{"line_number":251,"context_line":"                            type(pos).__name__)"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        old_pos \u003d self._readable.tell()"}],"source_content_type":"text/x-python","patch_set":3,"id":"7a2fa921_fd59345b","line":250,"in_reply_to":"7a2fa921_0c75f296","updated":"2015-10-07 18:21:28.000000000","message":"Done","commit_id":"40156bb7e3b04e14380a666e9c2e72c838ce9a5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2871966573e69ca24ff336227f005dda6df40c8a","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            raise IOError(\u0027Invalid argument\u0027)"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"        if type(self.md5sum) is not NoopMD5:"},{"line_number":270,"context_line":"            self.md5sum \u003d hashlib.md5() if new_pos \u003d\u003d self._start else None"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"        self._remaining \u003d self._start + self._length - new_pos"},{"line_number":273,"context_line":"        return self._readable.seek(new_pos)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7a2fa921_ccab7a88","line":270,"updated":"2015-10-07 10:03:52.000000000","message":"Nice. new_pos \u003d\u003d self._start is the *likely* scenario in case of retry, correct? - when used for a segment upload then the LengthWrapper is wrapping a *segment* only so the retry would rewind to the start of the segment and this md5sum reset works.","commit_id":"40156bb7e3b04e14380a666e9c2e72c838ce9a5c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e99a57734104eb6019876086ee075f0733418e6d","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            raise IOError(\u0027Invalid argument\u0027)"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"        if type(self.md5sum) is not NoopMD5:"},{"line_number":270,"context_line":"            self.md5sum \u003d hashlib.md5() if new_pos \u003d\u003d self._start else None"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"        self._remaining \u003d self._start + self._length - new_pos"},{"line_number":273,"context_line":"        return self._readable.seek(new_pos)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7a2fa921_3897ba49","line":270,"in_reply_to":"7a2fa921_ccab7a88","updated":"2015-10-07 18:21:28.000000000","message":"Yes. In swiftclient.client we have it reset to what the readable reported via tell() before we did any reads (which should now be 0 for both objects and segments - i.e., new_post \u003d\u003d self._start when dealing with LengthWrappers); and in requests [1], they explicitly seek to 0.\n\n[1] https://github.com/kennethreitz/requests/blob/v2.7.0/requests/models.py#L474","commit_id":"40156bb7e3b04e14380a666e9c2e72c838ce9a5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2871966573e69ca24ff336227f005dda6df40c8a","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            self.md5sum \u003d hashlib.md5() if new_pos \u003d\u003d self._start else None"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"        self._remaining \u003d self._start + self._length - new_pos"},{"line_number":273,"context_line":"        return self._readable.seek(new_pos)"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def _tell(self):"},{"line_number":276,"context_line":"        return self._readable.tell() - self._start"}],"source_content_type":"text/x-python","patch_set":3,"id":"7a2fa921_2c16aea7","line":273,"updated":"2015-10-07 10:03:52.000000000","message":"Maybe this is pure paranoia but should this try the self_readable.seek first then update self._remaining, so if the first raises an Error then the wrapper state is not left inconsistent?","commit_id":"40156bb7e3b04e14380a666e9c2e72c838ce9a5c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e99a57734104eb6019876086ee075f0733418e6d","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            self.md5sum \u003d hashlib.md5() if new_pos \u003d\u003d self._start else None"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"        self._remaining \u003d self._start + self._length - new_pos"},{"line_number":273,"context_line":"        return self._readable.seek(new_pos)"},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"    def _tell(self):"},{"line_number":276,"context_line":"        return self._readable.tell() - self._start"}],"source_content_type":"text/x-python","patch_set":3,"id":"7a2fa921_0e48745a","line":273,"in_reply_to":"7a2fa921_2c16aea7","updated":"2015-10-07 18:21:28.000000000","message":"Some paranoia is healthy. Done, along with the MD5 reset.\n\nAlso, this made me think about the return value some more, which made me notice a couple inconsistencies in Python\u0027s readables (at least in 2.7):\n\nFirst, a return value difference between File Object\u0027s seek (https://docs.python.org/2/library/stdtypes.html#file.seek - always return None) and that of IOBase (https://docs.python.org/2/library/io.html#io.IOBase.seek - return the new position). Having a meaningful return value seems better than None, so I think I\u0027ll do that.\n\nSecond, a behavioral difference when seeking to before the beginning of the file between File Object (raise error) and StringIO (seek to start). I feel like the latter may be the way to go, which would let me drop the new_pos \u003c self._start check; any opposition?","commit_id":"40156bb7e3b04e14380a666e9c2e72c838ce9a5c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"57a5f143b552ff4660304e4cc886e34207d689f9","unresolved":false,"context_lines":[{"line_number":212,"context_line":"        :param md5: Flag to enable calculating the MD5 of the content"},{"line_number":213,"context_line":"                    as it is read."},{"line_number":214,"context_line":"        \"\"\""},{"line_number":215,"context_line":"        self.md5sum \u003d hashlib.md5() if md5 else NoopMD5()"},{"line_number":216,"context_line":"        self._length \u003d self._remaining \u003d length"},{"line_number":217,"context_line":"        self._readable \u003d readable"},{"line_number":218,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_eaedddef","side":"PARENT","line":215,"updated":"2015-10-07 18:56:25.000000000","message":"how about:\n\n    self._new_md5sum \u003d lambda: hashlib.md5() if md5 else NoopMD5()\n    self.md5sum \u003d self._new_md5sum()\n\nand then use that lambda again later instead of the type check?  I\u0027d also find it pretty reasonable for that being an instance method and just keeping the passed in md5 option as state.","commit_id":"c90547b5d4304a3f62ba5aa1e78aa620f7dcc1c5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"57a5f143b552ff4660304e4cc886e34207d689f9","unresolved":false,"context_lines":[{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    def get_md5sum(self):"},{"line_number":227,"context_line":"        if self.md5sum is None:"},{"line_number":228,"context_line":"            raise IOError(\u0027md5 requires a linear read from start to finish\u0027)"},{"line_number":229,"context_line":"        return self.md5sum.hexdigest()"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"    def read(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_8a90e944","line":228,"updated":"2015-10-07 18:56:25.000000000","message":"Does anyone *handle* this IOError?","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d82313b3a55ad1e96395cc0c28dce2d253489169","unresolved":false,"context_lines":[{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    def get_md5sum(self):"},{"line_number":227,"context_line":"        if self.md5sum is None:"},{"line_number":228,"context_line":"            raise IOError(\u0027md5 requires a linear read from start to finish\u0027)"},{"line_number":229,"context_line":"        return self.md5sum.hexdigest()"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"    def read(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_25ff8635","line":228,"in_reply_to":"7a2fa921_8a90e944","updated":"2015-10-07 22:10:26.000000000","message":"Does anyone *trigger* it?","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"57a5f143b552ff4660304e4cc886e34207d689f9","unresolved":false,"context_lines":[{"line_number":251,"context_line":"            raise TypeError(\u0027%r object cannot be interpreted as an index\u0027 %"},{"line_number":252,"context_line":"                            type(pos).__name__)"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"        old_pos \u003d self._readable.tell()"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"        if seek_type \u003d\u003d 0:  # absolute"},{"line_number":257,"context_line":"            new_pos \u003d self._start + pos"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_0a229952","line":254,"updated":"2015-10-07 18:56:25.000000000","message":"this is turning one system call into two - why is this absolutely needed?","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d82313b3a55ad1e96395cc0c28dce2d253489169","unresolved":false,"context_lines":[{"line_number":251,"context_line":"            raise TypeError(\u0027%r object cannot be interpreted as an index\u0027 %"},{"line_number":252,"context_line":"                            type(pos).__name__)"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"        old_pos \u003d self._readable.tell()"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"        if seek_type \u003d\u003d 0:  # absolute"},{"line_number":257,"context_line":"            new_pos \u003d self._start + pos"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_d7e3e931","line":254,"in_reply_to":"7a2fa921_0a229952","updated":"2015-10-07 22:10:26.000000000","message":"So,\n\n old_pos \u003d self._start + self._length - self._remaining\n\n? I think I can buy that. Actually, we should never need to call readable.tell() after the first time, right? (Well, assuming the seek always takes us where we were hoping to go.)","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"57a5f143b552ff4660304e4cc886e34207d689f9","unresolved":false,"context_lines":[{"line_number":260,"context_line":"        elif seek_type \u003d\u003d 2:  # relative from end"},{"line_number":261,"context_line":"            new_pos \u003d self._start + self._length + pos"},{"line_number":262,"context_line":"        else:"},{"line_number":263,"context_line":"            raise IOError(\u0027Invalid argument\u0027)"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        self._readable.seek(max(new_pos, self._start))"},{"line_number":266,"context_line":"        new_pos \u003d self._readable.tell()"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_ca04a1c1","line":263,"updated":"2015-10-07 18:56:25.000000000","message":"Having to reimplement half of this system call in python grosses me out.\n\nIt\u0027s possible that this is a more flexible/complete wrapper for a seekable/tellable that\u0027s scoped to a range over the wrapped readable but it\u0027s not obvious to me that we need all of that as much as just resetting the md5sum and _remaining.","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d82313b3a55ad1e96395cc0c28dce2d253489169","unresolved":false,"context_lines":[{"line_number":260,"context_line":"        elif seek_type \u003d\u003d 2:  # relative from end"},{"line_number":261,"context_line":"            new_pos \u003d self._start + self._length + pos"},{"line_number":262,"context_line":"        else:"},{"line_number":263,"context_line":"            raise IOError(\u0027Invalid argument\u0027)"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"        self._readable.seek(max(new_pos, self._start))"},{"line_number":266,"context_line":"        new_pos \u003d self._readable.tell()"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_77bbf5e5","line":263,"in_reply_to":"7a2fa921_ca04a1c1","updated":"2015-10-07 22:10:26.000000000","message":"Me too. The more I wrote it the more I was getting annoyed at needing to do so.\n\nMaybe the better solution is to just add a reset method and look for that in client.py. That\u0027s the only bit we *actually* care about during uploads.","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"57a5f143b552ff4660304e4cc886e34207d689f9","unresolved":false,"context_lines":[{"line_number":265,"context_line":"        self._readable.seek(max(new_pos, self._start))"},{"line_number":266,"context_line":"        new_pos \u003d self._readable.tell()"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        if type(self.md5sum) is not NoopMD5:"},{"line_number":269,"context_line":"            self.md5sum \u003d hashlib.md5() if new_pos \u003d\u003d self._start else None"},{"line_number":270,"context_line":"        self._remaining \u003d self._start + self._length - new_pos"},{"line_number":271,"context_line":"        return new_pos - self._start"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_ea163df0","line":268,"updated":"2015-10-07 18:56:25.000000000","message":"isinstance maybe - but having to rely on the current type of the property is pretty implicit.","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"57a5f143b552ff4660304e4cc886e34207d689f9","unresolved":false,"context_lines":[{"line_number":266,"context_line":"        new_pos \u003d self._readable.tell()"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        if type(self.md5sum) is not NoopMD5:"},{"line_number":269,"context_line":"            self.md5sum \u003d hashlib.md5() if new_pos \u003d\u003d self._start else None"},{"line_number":270,"context_line":"        self._remaining \u003d self._start + self._length - new_pos"},{"line_number":271,"context_line":"        return new_pos - self._start"},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_ea72bd48","line":269,"updated":"2015-10-07 18:56:25.000000000","message":"When exactly do we ever seek into the middle of a LengthWrapped contents?","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d82313b3a55ad1e96395cc0c28dce2d253489169","unresolved":false,"context_lines":[{"line_number":266,"context_line":"        new_pos \u003d self._readable.tell()"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        if type(self.md5sum) is not NoopMD5:"},{"line_number":269,"context_line":"            self.md5sum \u003d hashlib.md5() if new_pos \u003d\u003d self._start else None"},{"line_number":270,"context_line":"        self._remaining \u003d self._start + self._length - new_pos"},{"line_number":271,"context_line":"        return new_pos - self._start"},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_f73b85cf","line":269,"in_reply_to":"7a2fa921_ea72bd48","updated":"2015-10-07 22:10:26.000000000","message":"Us? Never. Someone else? No idea. I didn\u0027t expect *anyone* else to call seek(), but then requests was using it to get Content-Length.\n\nI was just trying to get a reasonably sane behavior if you *did* seek into the middle.\n\n(As an aside, this calls to mind some of the headaches John was dealing with yesterday from some project in -infra using the low-level API in client.py, checking whether a return value is a Generator, then flipping out if it\u0027s some other type of iterable (like _ObjectBody). We *really* need to define what our API is (and isn\u0027t), what parts of all of this we expect other libraries to interact with, and how they should do so.)","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"},{"author":{"_account_id":9216,"name":"Joel Wright","email":"joel.wright@gmail.com","username":"jjw-sohonet"},"change_message_id":"84aea50591783c614d2283928e2bbe45b1d39352","unresolved":false,"context_lines":[{"line_number":235,"context_line":"            return \u0027\u0027"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"        to_read \u003d self._remaining if size \u003c 0 else min(size, self._remaining)"},{"line_number":238,"context_line":"        chunk \u003d self._readable.read(to_read)[:self._remaining]"},{"line_number":239,"context_line":"        self._remaining -\u003d len(chunk)"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_0654a7fc","line":238,"updated":"2015-11-18 23:41:17.000000000","message":"I might be being stupid, but I really don\u0027t see the purpose of the\n\n    [:self._remaining]\n\nhere.","commit_id":"2c1ae6139bf65b134e3e03af8f10c283223b9166"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d968d3728d1f38300cf3421fc95bae0ae3243d","unresolved":false,"context_lines":[{"line_number":235,"context_line":"            return \u0027\u0027"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"        to_read \u003d self._remaining if size \u003c 0 else min(size, self._remaining)"},{"line_number":238,"context_line":"        chunk \u003d self._readable.read(to_read)[:self._remaining]"},{"line_number":239,"context_line":"        self._remaining -\u003d len(chunk)"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_99b3189a","line":238,"in_reply_to":"ba8a016a_0654a7fc","updated":"2015-11-19 22:45:28.000000000","message":"Lingering paranoia? Removed.","commit_id":"2c1ae6139bf65b134e3e03af8f10c283223b9166"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2150c4ffff839e8eb34c74c632f55a67c6343562","unresolved":false,"context_lines":[{"line_number":202,"context_line":"    def __init__(self, readable, length, md5\u003dFalse):"},{"line_number":203,"context_line":"        \"\"\""},{"line_number":204,"context_line":"        :param readable: The filelike object to read from."},{"line_number":205,"context_line":"        :param length: The maximum amount of content to that can be read from"},{"line_number":206,"context_line":"                       the filelike object before it is simulated to be"},{"line_number":207,"context_line":"                       empty."},{"line_number":208,"context_line":"        :param md5: Flag to enable calculating the MD5 of the content"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa69d971_0cbcccb9","line":205,"updated":"2016-01-11 15:31:21.000000000","message":"nit: if you need another version maybe you could fix the typo here s/to that/that/","commit_id":"9f79fdc7c8bcc7c7edf065c67e4c0f938775c79f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e5b63f9e04317196188700f08e135f580ba8903f","unresolved":false,"context_lines":[{"line_number":202,"context_line":"    def __init__(self, readable, length, md5\u003dFalse):"},{"line_number":203,"context_line":"        \"\"\""},{"line_number":204,"context_line":"        :param readable: The filelike object to read from."},{"line_number":205,"context_line":"        :param length: The maximum amount of content to that can be read from"},{"line_number":206,"context_line":"                       the filelike object before it is simulated to be"},{"line_number":207,"context_line":"                       empty."},{"line_number":208,"context_line":"        :param md5: Flag to enable calculating the MD5 of the content"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa69d971_95275111","line":205,"in_reply_to":"fa69d971_0cbcccb9","updated":"2016-01-11 19:15:52.000000000","message":"Done","commit_id":"9f79fdc7c8bcc7c7edf065c67e4c0f938775c79f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2150c4ffff839e8eb34c74c632f55a67c6343562","unresolved":false,"context_lines":[{"line_number":242,"context_line":"        return chunk"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    @property"},{"line_number":245,"context_line":"    def resettable(self):"},{"line_number":246,"context_line":"        return self._can_reset"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def reset(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa69d971_2cef50b2","line":245,"updated":"2016-01-11 15:31:21.000000000","message":"nit: I think resettable could be avoided, see my diff.","commit_id":"9f79fdc7c8bcc7c7edf065c67e4c0f938775c79f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e5b63f9e04317196188700f08e135f580ba8903f","unresolved":false,"context_lines":[{"line_number":242,"context_line":"        return chunk"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    @property"},{"line_number":245,"context_line":"    def resettable(self):"},{"line_number":246,"context_line":"        return self._can_reset"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    def reset(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa69d971_f50d6d8f","line":245,"in_reply_to":"fa69d971_2cef50b2","updated":"2016-01-11 19:15:52.000000000","message":"Done, though with slight modifications. I didn\u0027t like that LengthWrapper.reset would always be present, but only sometimes be callable.","commit_id":"9f79fdc7c8bcc7c7edf065c67e4c0f938775c79f"}],"tests/unit/test_swiftclient.py":[{"author":{"_account_id":9216,"name":"Joel Wright","email":"joel.wright@gmail.com","username":"jjw-sohonet"},"change_message_id":"84aea50591783c614d2283928e2bbe45b1d39352","unresolved":false,"context_lines":[{"line_number":1650,"context_line":""},{"line_number":1651,"context_line":"            def send(self, *args, **kwargs):"},{"line_number":1652,"context_line":"                data \u003d kwargs.get(\u0027data\u0027)"},{"line_number":1653,"context_line":"                if data:"},{"line_number":1654,"context_line":"                    if hasattr(data, \u0027read\u0027):"},{"line_number":1655,"context_line":"                        data.read()"},{"line_number":1656,"context_line":"                    else:"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_c6b69ff8","line":1653,"updated":"2015-11-18 23:41:17.000000000","message":"nit: would it not be clearer for line 1653 to be\n\n    if data is not None:","commit_id":"2c1ae6139bf65b134e3e03af8f10c283223b9166"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d968d3728d1f38300cf3421fc95bae0ae3243d","unresolved":false,"context_lines":[{"line_number":1650,"context_line":""},{"line_number":1651,"context_line":"            def send(self, *args, **kwargs):"},{"line_number":1652,"context_line":"                data \u003d kwargs.get(\u0027data\u0027)"},{"line_number":1653,"context_line":"                if data:"},{"line_number":1654,"context_line":"                    if hasattr(data, \u0027read\u0027):"},{"line_number":1655,"context_line":"                        data.read()"},{"line_number":1656,"context_line":"                    else:"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba8a016a_797674d8","line":1653,"in_reply_to":"ba8a016a_c6b69ff8","updated":"2015-11-19 22:45:28.000000000","message":"Done","commit_id":"2c1ae6139bf65b134e3e03af8f10c283223b9166"}],"tests/unit/test_utils.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"57a5f143b552ff4660304e4cc886e34207d689f9","unresolved":false,"context_lines":[{"line_number":234,"context_line":"        self.assertEqual(s, read_data)"},{"line_number":235,"context_line":"        self.assertEqual(md5(s.encode()).hexdigest(), data.get_md5sum())"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"        self.assertEqual(14, data.seek(14, 0))"},{"line_number":238,"context_line":"        read_data \u003d u\u0027\u0027.join(iter(data.read, \u0027\u0027))"},{"line_number":239,"context_line":"        self.assertEqual(28, len(read_data))"},{"line_number":240,"context_line":"        self.assertEqual(s[14:], read_data)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a2fa921_4ab171e0","line":237,"updated":"2015-10-07 18:56:25.000000000","message":"can you use the os.SEEK_* constants for readability?","commit_id":"bf9659d5d7d9aa654aa19f410257e939a0d42ce4"}]}
