)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"080f89dcd24020ef973e7ed35c3496234c3516c0","unresolved":false,"context_lines":[{"line_number":10,"context_line":"you had \"swob.HTTPRequestedRangeNotSatisfiable()\", you\u0027d get a body,"},{"line_number":11,"context_line":"but if you had \"swob.Response(..., conditional_response\u003dTrue)\", then"},{"line_number":12,"context_line":"you\u0027d get a length-0 response body. Now you always get a response"},{"line_number":13,"context_line":"body. It\u0027s just the default \u003chtml\u003e\u003ch1\u003e..., but at it\u0027s always there."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Bonus efficiency: do a little caching of sub-SLO manifests to avoid"},{"line_number":16,"context_line":"needless re-fetches. This kicks in when there are multiple references"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"9a89bdaa_e6fb5377","line":13,"updated":"2016-09-08 03:38:50.000000000","message":"nit: \"but at it\u0027s always there\" probably is a typo.","commit_id":"4bcd3d7f6de53ccd04d42005848060b92e7733ce"}],"swift/common/middleware/slo.py":[{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"1885e386dc80c4a28b23119be9cad45381302096","unresolved":false,"context_lines":[{"line_number":502,"context_line":""},{"line_number":503,"context_line":"                sub_path \u003d get_valid_utf8_str(seg_dict[\u0027name\u0027])"},{"line_number":504,"context_line":"                sub_cont, sub_obj \u003d split_path(sub_path, 2, 2, True)"},{"line_number":505,"context_line":"                if last_sub_path !\u003d sub_path:"},{"line_number":506,"context_line":"                    sub_segments \u003d cached_fetch_sub_slo_segments("},{"line_number":507,"context_line":"                        req, version, account, sub_cont, sub_obj)"},{"line_number":508,"context_line":"                last_sub_path \u003d sub_path"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_ae0bff22","line":505,"updated":"2016-08-11 11:58:28.000000000","message":"This may already be existing prior to the patch - but if this case was not true, then sub_segments would not have a value (which is referenced in Line 511). But if it were never to reach this case, then we probably don\u0027t need this check.","commit_id":"54a06d6567b945199ee36d023d5b77cf8565edb3"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"6473fb1a21591607ef96bcc2d1ef9f24d5557e24","unresolved":false,"context_lines":[{"line_number":502,"context_line":""},{"line_number":503,"context_line":"                sub_path \u003d get_valid_utf8_str(seg_dict[\u0027name\u0027])"},{"line_number":504,"context_line":"                sub_cont, sub_obj \u003d split_path(sub_path, 2, 2, True)"},{"line_number":505,"context_line":"                if last_sub_path !\u003d sub_path:"},{"line_number":506,"context_line":"                    sub_segments \u003d cached_fetch_sub_slo_segments("},{"line_number":507,"context_line":"                        req, version, account, sub_cont, sub_obj)"},{"line_number":508,"context_line":"                last_sub_path \u003d sub_path"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_7b3d2b2a","line":505,"in_reply_to":"9ad45d7e_ae0bff22","updated":"2016-08-11 22:17:58.000000000","message":"last_sub_path starts as None, so I think this code is safe. We\u0027ll always take this branch on the first pass through the outer loop.","commit_id":"54a06d6567b945199ee36d023d5b77cf8565edb3"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"1885e386dc80c4a28b23119be9cad45381302096","unresolved":false,"context_lines":[{"line_number":509,"context_line":""},{"line_number":510,"context_line":"                # Use the existing machinery to slice into the sub-SLO."},{"line_number":511,"context_line":"                for sub_seg_dict, sb, eb in self._byterange_listing_iterator("},{"line_number":512,"context_line":"                        req, version, account, sub_segments,"},{"line_number":513,"context_line":"                        # This adjusts first_byte and last_byte to be"},{"line_number":514,"context_line":"                        # relative to the sub-SLO."},{"line_number":515,"context_line":"                        range_start + max(0, first_byte),"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_ee3857d5","line":512,"updated":"2016-08-11 11:58:28.000000000","message":"sub_segments is referenced before it is assigned a value (as we have a  conditional assignment above).","commit_id":"54a06d6567b945199ee36d023d5b77cf8565edb3"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cb3eb033a8479183e0b500b34bc49a1729ab395e","unresolved":false,"context_lines":[{"line_number":714,"context_line":"                # For some reason, swob.Range.ranges_for_length adds 1 to the"},{"line_number":715,"context_line":"                # last byte\u0027s position."},{"line_number":716,"context_line":"                (start, end - 1) for start, end"},{"line_number":717,"context_line":"                in req.range.ranges_for_length(content_length)]"},{"line_number":718,"context_line":"        else:"},{"line_number":719,"context_line":"            byteranges \u003d []"},{"line_number":720,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_34016006","line":717,"updated":"2016-08-16 23:38:27.000000000","message":"Why\u0027d we stop checking for\n\n len(req.range.ranges_for_length(content_length)) \u003d\u003d 0\n\n? Should we still raise HTTPRequestedRangeNotSatisfiable in that case?","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"e85d88546f56d401a7fa41f007c4770a4304dc85","unresolved":false,"context_lines":[{"line_number":714,"context_line":"                # For some reason, swob.Range.ranges_for_length adds 1 to the"},{"line_number":715,"context_line":"                # last byte\u0027s position."},{"line_number":716,"context_line":"                (start, end - 1) for start, end"},{"line_number":717,"context_line":"                in req.range.ranges_for_length(content_length)]"},{"line_number":718,"context_line":"        else:"},{"line_number":719,"context_line":"            byteranges \u003d []"},{"line_number":720,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_fac69166","line":717,"in_reply_to":"3ac371cc_34016006","updated":"2016-08-17 20:32:48.000000000","message":"We still do, somehow. I think swob takes care of it. There\u0027s a unit test where all n \u003e 1 byteranges are unsatisfiable, and it does get a 416.","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cb3eb033a8479183e0b500b34bc49a1729ab395e","unresolved":false,"context_lines":[{"line_number":716,"context_line":"                (start, end - 1) for start, end"},{"line_number":717,"context_line":"                in req.range.ranges_for_length(content_length)]"},{"line_number":718,"context_line":"        else:"},{"line_number":719,"context_line":"            byteranges \u003d []"},{"line_number":720,"context_line":""},{"line_number":721,"context_line":"        ver, account, _junk \u003d req.split_path(3, 3, rest_with_last\u003dTrue)"},{"line_number":722,"context_line":"        plain_listing_iter \u003d self._segment_listing_iterator("}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_ae26a2cb","line":719,"updated":"2016-08-16 23:38:27.000000000","message":"Why can\u0027t we set this to\n\n [(0, content_length - 1)]\n\n? It feels awkward to use an empty list to denote \"everything\".","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"2168ab4b9ae470908a6d0f5dc7a044c977cfed7a","unresolved":false,"context_lines":[{"line_number":716,"context_line":"                (start, end - 1) for start, end"},{"line_number":717,"context_line":"                in req.range.ranges_for_length(content_length)]"},{"line_number":718,"context_line":"        else:"},{"line_number":719,"context_line":"            byteranges \u003d []"},{"line_number":720,"context_line":""},{"line_number":721,"context_line":"        ver, account, _junk \u003d req.split_path(3, 3, rest_with_last\u003dTrue)"},{"line_number":722,"context_line":"        plain_listing_iter \u003d self._segment_listing_iterator("}],"source_content_type":"text/x-python","patch_set":5,"id":"9a89bdaa_a0886ac6","line":719,"in_reply_to":"3ac371cc_1ae44ddf","updated":"2016-09-28 03:53:27.000000000","message":"I lean towards keeping the empty list because it suggests the user didn\u0027t specify any range header, as Sam mentioned.  At this point in the code, that is more accurate.  Have the name \"byteranges\" implies to me it represents the user specified byte-ranges. If later, that empty list is interpreted as use \"everything\", then that translation happens where it is used in that manner.","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"e85d88546f56d401a7fa41f007c4770a4304dc85","unresolved":false,"context_lines":[{"line_number":716,"context_line":"                (start, end - 1) for start, end"},{"line_number":717,"context_line":"                in req.range.ranges_for_length(content_length)]"},{"line_number":718,"context_line":"        else:"},{"line_number":719,"context_line":"            byteranges \u003d []"},{"line_number":720,"context_line":""},{"line_number":721,"context_line":"        ver, account, _junk \u003d req.split_path(3, 3, rest_with_last\u003dTrue)"},{"line_number":722,"context_line":"        plain_listing_iter \u003d self._segment_listing_iterator("}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_1ae44ddf","line":719,"in_reply_to":"3ac371cc_ae26a2cb","updated":"2016-08-17 20:32:48.000000000","message":"We could do that if you prefer. To me, empty byteranges suggests that the user didn\u0027t specify any Range header, but your suggestion is technically equivalent.\n\nHow strongly do you feel about this?","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"080f89dcd24020ef973e7ed35c3496234c3516c0","unresolved":false,"context_lines":[{"line_number":458,"context_line":"        #"},{"line_number":459,"context_line":"        # 20 is sort of an arbitrary choice; it\u0027s twice our max recursion"},{"line_number":460,"context_line":"        # depth, so we know this won\u0027t expand memory requirements by too"},{"line_number":461,"context_line":"        # much."},{"line_number":462,"context_line":"        cached_fetch_sub_slo_segments \u003d \\"},{"line_number":463,"context_line":"            LRUCache(maxsize\u003d20)(self._fetch_sub_slo_segments)"},{"line_number":464,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a89bdaa_e9cde466","line":461,"updated":"2016-09-08 03:38:50.000000000","message":"I gather that the reason no new assertions about caching or about the limit were made because we already have test_utils:TestLRUCache?  Would it make sense to just assert that utils.get_cached is called at some point in test_multiple_ranges_including_suffix_get_manifest?","commit_id":"4bcd3d7f6de53ccd04d42005848060b92e7733ce"}],"swift/common/request_helpers.py":[{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"13fbbf925e087edd806d59392f92305758143f6e","unresolved":false,"context_lines":[{"line_number":520,"context_line":"        \"\"\""},{"line_number":521,"context_line":"        return self"},{"line_number":522,"context_line":""},{"line_number":523,"context_line":"    def app_iter_ranges(self, ranges, content_type, boundary, content_size):"},{"line_number":524,"context_line":"        \"\"\""},{"line_number":525,"context_line":"        This method assumes that iter(self) yields all the data bytes that"},{"line_number":526,"context_line":"        go into the response, but none of the MIME stuff. For example, if"}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad45d7e_60c0547c","line":523,"updated":"2016-08-10 03:35:18.000000000","message":"I see that there is a testSpliterator.  but maybe add a unit test for this method in test_request_helpers?  I don\u0027t know, could be overkill.","commit_id":"a308b0189c9cd1bbe78032ae0c4c13e0f66b6c6c"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"013e0aad47125a4caaef51845342e98bbc19c1a4","unresolved":false,"context_lines":[{"line_number":520,"context_line":"        \"\"\""},{"line_number":521,"context_line":"        return self"},{"line_number":522,"context_line":""},{"line_number":523,"context_line":"    def app_iter_ranges(self, ranges, content_type, boundary, content_size):"},{"line_number":524,"context_line":"        \"\"\""},{"line_number":525,"context_line":"        This method assumes that iter(self) yields all the data bytes that"},{"line_number":526,"context_line":"        go into the response, but none of the MIME stuff. For example, if"}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad45d7e_ed199d89","line":523,"in_reply_to":"9ad45d7e_60c0547c","updated":"2016-08-11 00:13:48.000000000","message":"Yeah, there aren\u0027t a ton of direct tests for SegmentedIterable. It\u0027s tested indirectly in the SLO and DLO tests since it came about from refactoring some stuff.\n\nFor me, if the response bodies in the SLO/DLO tests are correct, that gives me confidence that this method is correct.","commit_id":"a308b0189c9cd1bbe78032ae0c4c13e0f66b6c6c"}],"swift/common/swob.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"de84be85664beeb5e03dbf652b0c5afe3ad85762","unresolved":false,"context_lines":[{"line_number":1247,"context_line":"                self.status \u003d 416"},{"line_number":1248,"context_line":"                close_if_possible(app_iter)"},{"line_number":1249,"context_line":"                body \u003d None"},{"line_number":1250,"context_line":"                app_iter \u003d None"},{"line_number":1251,"context_line":"            elif ranges:"},{"line_number":1252,"context_line":"                range_size \u003d len(ranges)"},{"line_number":1253,"context_line":"                if range_size \u003e 0:"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8ec9b2_886cff09","line":1250,"updated":"2016-09-20 00:44:01.000000000","message":"Maybe worth having a comment about the magic going on here? Looking at the diff against base, it\u0027s incredibly unintuitive that this code should produce a body.","commit_id":"4bcd3d7f6de53ccd04d42005848060b92e7733ce"}],"swift/common/utils.py":[{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"1885e386dc80c4a28b23119be9cad45381302096","unresolved":false,"context_lines":[{"line_number":3303,"context_line":"    \"abcd\""},{"line_number":3304,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(3))"},{"line_number":3305,"context_line":"    \"efg\""},{"line_number":3306,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(1))"},{"line_number":3307,"context_line":"    \"efg\""},{"line_number":3308,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(3))"},{"line_number":3309,"context_line":"    \"efg\""}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_0e432bb3","line":3306,"updated":"2016-08-11 11:58:28.000000000","message":"This is confusing. Everything from here below results in efg. Test in test_utils asserts it differently (correctly?). This needs to be modified I believe.","commit_id":"54a06d6567b945199ee36d023d5b77cf8565edb3"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"6473fb1a21591607ef96bcc2d1ef9f24d5557e24","unresolved":false,"context_lines":[{"line_number":3303,"context_line":"    \"abcd\""},{"line_number":3304,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(3))"},{"line_number":3305,"context_line":"    \"efg\""},{"line_number":3306,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(1))"},{"line_number":3307,"context_line":"    \"efg\""},{"line_number":3308,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(3))"},{"line_number":3309,"context_line":"    \"efg\""}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_6f7ba57b","line":3306,"in_reply_to":"9ad45d7e_0e432bb3","updated":"2016-08-11 22:17:58.000000000","message":"copy-paste-itis strikes again. :|","commit_id":"54a06d6567b945199ee36d023d5b77cf8565edb3"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cb3eb033a8479183e0b500b34bc49a1729ab395e","unresolved":false,"context_lines":[{"line_number":3299,"context_line":"    from the source."},{"line_number":3300,"context_line":""},{"line_number":3301,"context_line":"    \u003e\u003e\u003e si \u003d Spliterator([\"abcde\", \"fg\", \"hijkl\"])"},{"line_number":3302,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(4))"},{"line_number":3303,"context_line":"    \"abcd\""},{"line_number":3304,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(3))"},{"line_number":3305,"context_line":"    \"efg\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_14a8a48c","line":3302,"range":{"start_line":3302,"start_character":8,"end_line":3302,"end_character":15},"updated":"2016-08-16 23:38:27.000000000","message":"The examples might be more clear if we said\n\n list(si.take(4))\n\ninstead of\n\n \u0027\u0027.join(si.take(4))\n\nMaybe that\u0027s just me though.","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"e85d88546f56d401a7fa41f007c4770a4304dc85","unresolved":false,"context_lines":[{"line_number":3299,"context_line":"    from the source."},{"line_number":3300,"context_line":""},{"line_number":3301,"context_line":"    \u003e\u003e\u003e si \u003d Spliterator([\"abcde\", \"fg\", \"hijkl\"])"},{"line_number":3302,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(4))"},{"line_number":3303,"context_line":"    \"abcd\""},{"line_number":3304,"context_line":"    \u003e\u003e\u003e \u0027\u0027.join(si.take(3))"},{"line_number":3305,"context_line":"    \"efg\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_faf05193","line":3302,"in_reply_to":"3ac371cc_14a8a48c","updated":"2016-08-17 20:32:48.000000000","message":"If we did it as lists, the second example would be\n\n    [\u0027e\u0027, \u0027fg\u0027]\n\ninstead of its current value \"efg\". IMHO, that slightly obscures the useful part, which is that take(3) gets you the next 3 elements. I\u0027m much less interested in how those 3 elements are grouped up.","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cb3eb033a8479183e0b500b34bc49a1729ab395e","unresolved":false,"context_lines":[{"line_number":3315,"context_line":"        self.input_iterator \u003d iter(source_iterable)"},{"line_number":3316,"context_line":"        self.leftovers \u003d None"},{"line_number":3317,"context_line":""},{"line_number":3318,"context_line":"    def take(self, n):"},{"line_number":3319,"context_line":"        if self.leftovers:"},{"line_number":3320,"context_line":"            llen \u003d len(self.leftovers)"},{"line_number":3321,"context_line":"            if llen \u003c n:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_946c9436","line":3318,"updated":"2016-08-16 23:38:27.000000000","message":"Should we add some guard here to prevent you mixing and matching take() generators? Doing something like\n\n zip(*[si.take(1) for x in xrange(2)])\n\nseems like a horrible idea that should probably raise a ValueError or something.","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"e85d88546f56d401a7fa41f007c4770a4304dc85","unresolved":false,"context_lines":[{"line_number":3315,"context_line":"        self.input_iterator \u003d iter(source_iterable)"},{"line_number":3316,"context_line":"        self.leftovers \u003d None"},{"line_number":3317,"context_line":""},{"line_number":3318,"context_line":"    def take(self, n):"},{"line_number":3319,"context_line":"        if self.leftovers:"},{"line_number":3320,"context_line":"            llen \u003d len(self.leftovers)"},{"line_number":3321,"context_line":"            if llen \u003c n:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_daed95b8","line":3318,"in_reply_to":"3ac371cc_946c9436","updated":"2016-08-17 20:32:48.000000000","message":"Yeah, that\u0027s probably worth fixing.","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"de84be85664beeb5e03dbf652b0c5afe3ad85762","unresolved":false,"context_lines":[{"line_number":3320,"context_line":"    def take(self, n):"},{"line_number":3321,"context_line":"        if self._iterator_in_progress:"},{"line_number":3322,"context_line":"            raise ValueError(\"cannot call take() again until the first\""},{"line_number":3323,"context_line":"                             \" iterator is exhausted\")"},{"line_number":3324,"context_line":"        self._iterator_in_progress \u003d True"},{"line_number":3325,"context_line":""},{"line_number":3326,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8ec9b2_ebf57dcb","line":3323,"range":{"start_line":3323,"start_character":40,"end_line":3323,"end_character":52},"updated":"2016-09-20 00:44:01.000000000","message":"Maybe worth being more explicit and saying \"raises StopIteration\"? Knowing the value of n I passed in, this feels kinda weird:\n\n\u003e\u003e\u003e s \u003d utils.Spliterator([\"abcde\", \"fg\", \"hijkl\"])\n\u003e\u003e\u003e its \u003d [s.take(6), s.take(6)]\n\u003e\u003e\u003e next(its[0])\n\u0027abcde\u0027\n\u003e\u003e\u003e next(its[0])\n\u0027f\u0027\n\u003e\u003e\u003e next(its[1])\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"swift/common/utils.py\", line 3322, in take\n    raise ValueError(\"cannot call take() again until the first\"\nValueError: cannot call take() again until the first iterator is exhausted","commit_id":"4bcd3d7f6de53ccd04d42005848060b92e7733ce"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"080f89dcd24020ef973e7ed35c3496234c3516c0","unresolved":false,"context_lines":[{"line_number":3338,"context_line":"                # leftovers[k:] and omit leftovers_index, then each call to"},{"line_number":3339,"context_line":"                # take() would copy k bytes to create the desired substring,"},{"line_number":3340,"context_line":"                # then copy all the remaining bytes to reset leftovers,"},{"line_number":3341,"context_line":"                # resulting in an overall O(N^2) bytes copied."},{"line_number":3342,"context_line":"                llen \u003d len(self.leftovers) - self.leftovers_index"},{"line_number":3343,"context_line":"                if llen \u003c\u003d n:"},{"line_number":3344,"context_line":"                    n -\u003d llen"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a89bdaa_066757e9","line":3341,"updated":"2016-09-08 03:38:50.000000000","message":"Great write up.  I walked through all the logic added for switch to save whole leftovers, and didn\u0027t find any holes.","commit_id":"4bcd3d7f6de53ccd04d42005848060b92e7733ce"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"de84be85664beeb5e03dbf652b0c5afe3ad85762","unresolved":false,"context_lines":[{"line_number":3363,"context_line":"                    self.leftovers_index \u003d n"},{"line_number":3364,"context_line":"                    n \u003d 0"},{"line_number":3365,"context_line":"        finally:"},{"line_number":3366,"context_line":"            self._iterator_in_progress \u003d False"},{"line_number":3367,"context_line":""},{"line_number":3368,"context_line":""},{"line_number":3369,"context_line":"def tpool_reraise(func, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8ec9b2_4bd2f135","line":3366,"updated":"2016-09-20 00:44:01.000000000","message":"Love it! We can close the generator if we want to bail on a take()!\n\n \u003e\u003e\u003e s \u003d utils.Spliterator([\"abcde\", \"fg\", \"hijkl\"])\n \u003e\u003e\u003e its \u003d [s.take(6), s.take(6)]\n \u003e\u003e\u003e next(its[0])\n \u0027abcde\u0027\n \u003e\u003e\u003e its[0].close()\n \u003e\u003e\u003e next(its[1])\n \u0027fg\u0027\n\n...but things get a little funky if there were leftovers :-/\n\n \u003e\u003e\u003e s \u003d utils.Spliterator([\"abcde\", \"fg\", \"hijkl\"])\n \u003e\u003e\u003e its \u003d [s.take(3), s.take(3)]\n \u003e\u003e\u003e next(its[0])\n \u0027abc\u0027\n \u003e\u003e\u003e its[0].close()\n \u003e\u003e\u003e next(its[1])\n \u0027fg\u0027\n\nI think we want to move the yield to after the setting of leftovers, like\n\n self.leftovers \u003d chunk\n self.leftovers_index \u003d n\n yield chunk[:n]","commit_id":"4bcd3d7f6de53ccd04d42005848060b92e7733ce"}],"test/unit/common/middleware/test_slo.py":[{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"13fbbf925e087edd806d59392f92305758143f6e","unresolved":false,"context_lines":[{"line_number":1764,"context_line":"        first_range_headers \u003d got_mime_docs[0][0]"},{"line_number":1765,"context_line":"        first_range_body \u003d got_mime_docs[0][1]"},{"line_number":1766,"context_line":"        self.assertEqual(first_range_headers[\u0027Content-Range\u0027],"},{"line_number":1767,"context_line":"                         \u0027bytes 3-17/50\u0027)"},{"line_number":1768,"context_line":"        self.assertEqual(first_range_body, \u0027aabbbbbbbbbbccc\u0027)"},{"line_number":1769,"context_line":""},{"line_number":1770,"context_line":"        second_range_headers \u003d got_mime_docs[1][0]"}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad45d7e_da0dad91","line":1767,"updated":"2016-08-10 03:35:18.000000000","message":"would it be helpful to assert the content-type of each range?","commit_id":"a308b0189c9cd1bbe78032ae0c4c13e0f66b6c6c"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"013e0aad47125a4caaef51845342e98bbc19c1a4","unresolved":false,"context_lines":[{"line_number":1764,"context_line":"        first_range_headers \u003d got_mime_docs[0][0]"},{"line_number":1765,"context_line":"        first_range_body \u003d got_mime_docs[0][1]"},{"line_number":1766,"context_line":"        self.assertEqual(first_range_headers[\u0027Content-Range\u0027],"},{"line_number":1767,"context_line":"                         \u0027bytes 3-17/50\u0027)"},{"line_number":1768,"context_line":"        self.assertEqual(first_range_body, \u0027aabbbbbbbbbbccc\u0027)"},{"line_number":1769,"context_line":""},{"line_number":1770,"context_line":"        second_range_headers \u003d got_mime_docs[1][0]"}],"source_content_type":"text/x-python","patch_set":2,"id":"9ad45d7e_8d8bc167","line":1767,"in_reply_to":"9ad45d7e_da0dad91","updated":"2016-08-11 00:13:48.000000000","message":"Probably not a bad idea.","commit_id":"a308b0189c9cd1bbe78032ae0c4c13e0f66b6c6c"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"1885e386dc80c4a28b23119be9cad45381302096","unresolved":false,"context_lines":[{"line_number":1737,"context_line":"        self.assertEqual(self.app.swift_sources[1:],"},{"line_number":1738,"context_line":"                         [\u0027SLO\u0027] * (len(self.app.swift_sources) - 1))"},{"line_number":1739,"context_line":""},{"line_number":1740,"context_line":"    def test_multiple_ranges_get_manifest(self):"},{"line_number":1741,"context_line":"        req \u003d Request.blank("},{"line_number":1742,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcd\u0027,"},{"line_number":1743,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_59b96b2d","line":1740,"updated":"2016-08-11 11:58:28.000000000","message":"Since SLO segments can be other SLO\u0027s, worth adding a test with ranges in submanifest?","commit_id":"54a06d6567b945199ee36d023d5b77cf8565edb3"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"6473fb1a21591607ef96bcc2d1ef9f24d5557e24","unresolved":false,"context_lines":[{"line_number":1737,"context_line":"        self.assertEqual(self.app.swift_sources[1:],"},{"line_number":1738,"context_line":"                         [\u0027SLO\u0027] * (len(self.app.swift_sources) - 1))"},{"line_number":1739,"context_line":""},{"line_number":1740,"context_line":"    def test_multiple_ranges_get_manifest(self):"},{"line_number":1741,"context_line":"        req \u003d Request.blank("},{"line_number":1742,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcd\u0027,"},{"line_number":1743,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ad45d7e_278551ce","line":1740,"in_reply_to":"9ad45d7e_59b96b2d","updated":"2016-08-11 22:17:58.000000000","message":"`manifest-abcd` already has a submanifest for the \u0027b\u0027 and \u0027c\u0027 parts, so I think we\u0027re covered.","commit_id":"54a06d6567b945199ee36d023d5b77cf8565edb3"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cb3eb033a8479183e0b500b34bc49a1729ab395e","unresolved":false,"context_lines":[{"line_number":5347,"context_line":"        self.assertEqual(\u0027\u0027.join(si.take(8)), \"fungusy-\")"},{"line_number":5348,"context_line":"        self.assertEqual(\u0027\u0027.join(si.take(8)), \"nummular\")"},{"line_number":5349,"context_line":""},{"line_number":5350,"context_line":"    def test_big_input_string(self):"},{"line_number":5351,"context_line":"        input_chunks \u003d [\"iridium\"]"},{"line_number":5352,"context_line":"        si \u003d utils.Spliterator(input_chunks)"},{"line_number":5353,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_570cde3a","line":5350,"range":{"start_line":5350,"start_character":13,"end_line":5350,"end_character":16},"updated":"2016-08-16 23:38:27.000000000","message":"That doesn\u0027t seem so big ;-)\n\nAlthough, thinking of big strings... what\u0027s the performance like when we\u0027ve got (say) 1MB input chunks and someone\u0027s taking tiny 10B chunks out? It seems like the way we\u0027re slicing would be quadratic? I suppose it probably doesn\u0027t matter too much; that\u0027s why we\u0027ve got the \"egregious range request\" handling, right?","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"e85d88546f56d401a7fa41f007c4770a4304dc85","unresolved":false,"context_lines":[{"line_number":5347,"context_line":"        self.assertEqual(\u0027\u0027.join(si.take(8)), \"fungusy-\")"},{"line_number":5348,"context_line":"        self.assertEqual(\u0027\u0027.join(si.take(8)), \"nummular\")"},{"line_number":5349,"context_line":""},{"line_number":5350,"context_line":"    def test_big_input_string(self):"},{"line_number":5351,"context_line":"        input_chunks \u003d [\"iridium\"]"},{"line_number":5352,"context_line":"        si \u003d utils.Spliterator(input_chunks)"},{"line_number":5353,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3ac371cc_484f1f6b","line":5350,"in_reply_to":"3ac371cc_570cde3a","updated":"2016-08-17 20:32:48.000000000","message":"Yeah, but it\u0027s nice not to leave little performance turds for others to step in later. :)\n\nI\u0027ll knock that down to linear.","commit_id":"5605cac781f4cfce332dbcb1ffd13fd9c9dba241"}]}
