)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":10,"context_line":"that can be provided custom headers; retries and ssl args"},{"line_number":11,"context_line":"so let\u0027s ensure we have it available for usage under these"},{"line_number":12,"context_line":"circumstances."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I4d5e777cf530e822bbea69c76846ebebb48a7927"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"9abe1de1_e69ff0b2","line":13,"updated":"2015-04-27 10:18:34.000000000","message":"Do you have tests for this? It would be nice to have something at least that tests this module.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":10,"context_line":"that can be provided custom headers; retries and ssl args"},{"line_number":11,"context_line":"so let\u0027s ensure we have it available for usage under these"},{"line_number":12,"context_line":"circumstances."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I4d5e777cf530e822bbea69c76846ebebb48a7927"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3afb71cf_ae72d8ab","line":13,"in_reply_to":"9abe1de1_e69ff0b2","updated":"2015-06-05 00:08:52.000000000","message":"Probably some somewhere.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"}],"cloudinit/test.py":[{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b20df58c8dde93ee656f2fbd5ab6d37fcd84c125","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#    Copyright (C) 2015 Yahoo!"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"#    Author: Joshua Harlow \u003charlowja@yahoo-inc.com\u003e"},{"line_number":4,"context_line":"#"},{"line_number":5,"context_line":"#    This program is free software: you can redistribute it and/or modify"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_b9c45992","line":2,"updated":"2015-06-05 09:59:05.000000000","message":"We\u0027re using a new License header: https://raw.githubusercontent.com/stackforge/cloud-init/master/cloudinit/sources/__init__.py","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"cda74070f544d69cb5752a3d349f92fe5be4b249","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#    Copyright (C) 2015 Yahoo!"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"#    Author: Joshua Harlow \u003charlowja@yahoo-inc.com\u003e"},{"line_number":4,"context_line":"#"},{"line_number":5,"context_line":"#    This program is free software: you can redistribute it and/or modify"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_285a3c84","line":2,"in_reply_to":"3afb71cf_b9c45992","updated":"2015-06-05 18:55:23.000000000","message":"Done","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"}],"cloudinit/tests/test_url_helper.py":[{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from cloudinit import url_helper"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class UrlHelperWaitForUrlsTest(test.TestCase):"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    @httpretty.activate"},{"line_number":28,"context_line":"    def test_url_wait_for(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_459c5669","line":25,"updated":"2015-06-05 09:20:15.000000000","message":"Part of the contract that wait_for_one_of_urls promises in its docstring is that every URL gets hit at least once before failure.","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b20df58c8dde93ee656f2fbd5ab6d37fcd84c125","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    @httpretty.activate"},{"line_number":28,"context_line":"    def test_url_wait_for(self):"},{"line_number":29,"context_line":"        httpretty.HTTPretty.allow_net_connect \u003d False"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"        urls_actions \u003d ["},{"line_number":32,"context_line":"            (\"http://www.yahoo.com\", (False, False, True)),"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_b94b392b","line":29,"updated":"2015-06-05 09:59:05.000000000","message":"I\u0027m not familiar with httpretty, but isn\u0027t this leaving allow_net_connect changed after the test finished? Wouldn\u0027t it be better if you use mock to patch the attribute or unpatch manually using addCleanup or something like this?","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"894c4c01f2d266ab0c863cec01007828e1e40f05","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    @httpretty.activate"},{"line_number":28,"context_line":"    def test_url_wait_for(self):"},{"line_number":29,"context_line":"        httpretty.HTTPretty.allow_net_connect \u003d False"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"        urls_actions \u003d ["},{"line_number":32,"context_line":"            (\"http://www.yahoo.com\", (False, False, True)),"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_bcee75ea","line":29,"in_reply_to":"3afb71cf_b94b392b","updated":"2015-06-05 15:33:13.000000000","message":"Agreed, I\u0027m thinking we want to set this in the root test class anyway. Don\u0027t really want net connections outwards to happen anyway... Let me add it there.","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":75,"context_line":"                               body\u003db\u0027it worked!\u0027)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        resp \u003d url_helper.read_url(\"http://www.yahoo.com\")"},{"line_number":78,"context_line":"        self.assertEqual(b\"it worked!\", resp.contents)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    @httpretty.activate"},{"line_number":81,"context_line":"    def test_retry_url_fetch(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_65c4f23f","line":78,"updated":"2015-06-05 09:20:15.000000000","message":"A fairly minor stylistic thing, but I like pulling out strings that will be used for test expectation to a variable; I find that it makes the test read a little more cleanly.  For example:\n\n success_body \u003d b\u0027it worked!\u0027\n httpretty.register_uri(httpretty.GET,\n                        \"http://www.yahoo.com\",\n                        body\u003db\u0027it worked!\u0027)\n ...\n self.assertEqual(success_body, resp.contents)\n\nI wouldn\u0027t bother changing this one; just submitted for your future consideration. :)","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b6601c7d250d6ebcfb2a1ba8ddf1620fdc585b38","unresolved":false,"context_lines":[{"line_number":19,"context_line":"        ]"},{"line_number":20,"context_line":"        urls \u003d []"},{"line_number":21,"context_line":"        for (url, actions) in urls_actions:"},{"line_number":22,"context_line":"            if actions:"},{"line_number":23,"context_line":"                urls.append(url)"},{"line_number":24,"context_line":"            for worked in actions:"},{"line_number":25,"context_line":"                if worked:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_e8884bc7","line":22,"updated":"2015-06-09 09:30:21.000000000","message":"actions (a non empty tuple) would be always True. Did you intend to use `any` or `all` instead? Otherwise, this `if` could be removed, it\u0027s dead code. Also, why not using something like ``urls \u003d [item[0] for item in urls_actions]``?","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b9cafac1d6bdcfec405eda8e5c85c0e803c9e88f","unresolved":false,"context_lines":[{"line_number":19,"context_line":"        ]"},{"line_number":20,"context_line":"        urls \u003d []"},{"line_number":21,"context_line":"        for (url, actions) in urls_actions:"},{"line_number":22,"context_line":"            if actions:"},{"line_number":23,"context_line":"                urls.append(url)"},{"line_number":24,"context_line":"            for worked in actions:"},{"line_number":25,"context_line":"                if worked:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_953759fe","line":22,"in_reply_to":"3afb71cf_373437dc","updated":"2015-06-10 18:11:21.000000000","message":"Done","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"7504cda8239e8d39dea9459f8b133783a17b4da6","unresolved":false,"context_lines":[{"line_number":19,"context_line":"        ]"},{"line_number":20,"context_line":"        urls \u003d []"},{"line_number":21,"context_line":"        for (url, actions) in urls_actions:"},{"line_number":22,"context_line":"            if actions:"},{"line_number":23,"context_line":"                urls.append(url)"},{"line_number":24,"context_line":"            for worked in actions:"},{"line_number":25,"context_line":"                if worked:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_373437dc","line":22,"in_reply_to":"3afb71cf_442dd893","updated":"2015-06-10 13:48:56.000000000","message":"Cool, then it can be removed. ;-)","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"ec786ef742580c6957e3b8b92deeab9fd8a03660","unresolved":false,"context_lines":[{"line_number":19,"context_line":"        ]"},{"line_number":20,"context_line":"        urls \u003d []"},{"line_number":21,"context_line":"        for (url, actions) in urls_actions:"},{"line_number":22,"context_line":"            if actions:"},{"line_number":23,"context_line":"                urls.append(url)"},{"line_number":24,"context_line":"            for worked in actions:"},{"line_number":25,"context_line":"                if worked:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_442dd893","line":22,"in_reply_to":"3afb71cf_e8884bc7","updated":"2015-06-10 04:15:31.000000000","message":"Dead code, probably just extra crap I put in for no good reason, ha.","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"}],"cloudinit/url_helper.py":[{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"if six.PY2:"},{"line_number":34,"context_line":"    import httplib"},{"line_number":35,"context_line":"    NOT_FOUND \u003d httplib.NOT_FOUND"},{"line_number":36,"context_line":"else:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_00bc0c6b","line":33,"updated":"2015-04-27 10:18:34.000000000","message":"Why not using six.moves.http.client?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"if six.PY2:"},{"line_number":34,"context_line":"    import httplib"},{"line_number":35,"context_line":"    NOT_FOUND \u003d httplib.NOT_FOUND"},{"line_number":36,"context_line":"else:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_cea4f409","line":33,"in_reply_to":"9abe1de1_00bc0c6b","updated":"2015-06-05 00:08:52.000000000","message":"\u003e\u003e\u003e from six.moves.http import client\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nImportError: No module named http\n\n??","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    SSL_ENABLED \u003d False"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"def _cleanurl(url):"},{"line_number":49,"context_line":"    parsed_url \u003d list(urlparse(url, scheme\u003d\u0027http\u0027))"},{"line_number":50,"context_line":"    if not parsed_url[1] and parsed_url[2]:"},{"line_number":51,"context_line":"        # Swap these since this seems to be a common"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_8077fcd3","line":48,"updated":"2015-04-27 10:18:34.000000000","message":"_clean_url?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":"def _cleanurl(url):"},{"line_number":49,"context_line":"    parsed_url \u003d list(urlparse(url, scheme\u003d\u0027http\u0027))"},{"line_number":50,"context_line":"    if not parsed_url[1] and parsed_url[2]:"},{"line_number":51,"context_line":"        # Swap these since this seems to be a common"},{"line_number":52,"context_line":"        # occurrence when given urls like \u0027www.google.com\u0027"},{"line_number":53,"context_line":"        parsed_url[1] \u003d parsed_url[2]"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_20039011","line":50,"updated":"2015-04-27 10:18:34.000000000","message":"I think you can access the items using dot acces, which is in this case parsed_url.netloc and parsed_url.path. Then we won\u0027t have to lookup what an item at position X represents.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":47,"context_line":""},{"line_number":48,"context_line":"def _cleanurl(url):"},{"line_number":49,"context_line":"    parsed_url \u003d list(urlparse(url, scheme\u003d\u0027http\u0027))"},{"line_number":50,"context_line":"    if not parsed_url[1] and parsed_url[2]:"},{"line_number":51,"context_line":"        # Swap these since this seems to be a common"},{"line_number":52,"context_line":"        # occurrence when given urls like \u0027www.google.com\u0027"},{"line_number":53,"context_line":"        parsed_url[1] \u003d parsed_url[2]"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_aece58b2","line":50,"in_reply_to":"9abe1de1_20039011","updated":"2015-06-05 00:08:52.000000000","message":"Ya, but then I can\u0027t reassign to them ;-)\n\n\u003e\u003e\u003e from six.moves.urllib.parse import urlparse\n\u003e\u003e\u003e url \u003d \"http://www.yahoo.com/b?c\u003dd\"\n\u003e\u003e\u003e urlparse(url)\nParseResult(scheme\u003d\u0027http\u0027, netloc\u003d\u0027www.yahoo.com\u0027, path\u003d\u0027/b\u0027, params\u003d\u0027\u0027, query\u003d\u0027c\u003dd\u0027, fragment\u003d\u0027\u0027)\n\u003e\u003e\u003e t \u003d urlparse(url)\n\u003e\u003e\u003e t.path\u003d3\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nAttributeError: can\u0027t set attribute","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def combine_single(url, add_on):"},{"line_number":61,"context_line":"        url_parsed \u003d list(urlparse(url))"},{"line_number":62,"context_line":"        path \u003d url_parsed[2]"},{"line_number":63,"context_line":"        if path and not path.endswith(\"/\"):"},{"line_number":64,"context_line":"            path +\u003d \"/\""},{"line_number":65,"context_line":"        path +\u003d urlquote(str(add_on), safe\u003d\"/:\")"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_eb03390c","line":62,"updated":"2015-04-27 10:18:34.000000000","message":"Ditto regarding dot access.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def combine_single(url, add_on):"},{"line_number":61,"context_line":"        url_parsed \u003d list(urlparse(url))"},{"line_number":62,"context_line":"        path \u003d url_parsed[2]"},{"line_number":63,"context_line":"        if path and not path.endswith(\"/\"):"},{"line_number":64,"context_line":"            path +\u003d \"/\""},{"line_number":65,"context_line":"        path +\u003d urlquote(str(add_on), safe\u003d\"/:\")"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_0e37acb1","line":62,"in_reply_to":"9abe1de1_eb03390c","updated":"2015-06-05 00:08:52.000000000","message":"Same reason ;)","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    url \u003d base"},{"line_number":70,"context_line":"    for add_on in add_ons:"},{"line_number":71,"context_line":"        url \u003d combine_single(url, add_on)"},{"line_number":72,"context_line":"    return url"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_8b683dbc","line":71,"updated":"2015-04-27 10:18:34.000000000","message":"Can\u0027t this be done in one single pass? Appending the quoted add_on that is.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    url \u003d base"},{"line_number":70,"context_line":"    for add_on in add_ons:"},{"line_number":71,"context_line":"        url \u003d combine_single(url, add_on)"},{"line_number":72,"context_line":"    return url"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_8e4b9c2b","line":71,"in_reply_to":"9abe1de1_8b683dbc","updated":"2015-06-05 00:08:52.000000000","message":"Probably, but meh, maybe a later change?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":89,"context_line":"            self.text \u003d contents"},{"line_number":90,"context_line":"            self.contents \u003d contents.encode(encoding)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def ok(self, *args, **kwargs):"},{"line_number":93,"context_line":"        if self.code !\u003d 200:"},{"line_number":94,"context_line":"            return False"},{"line_number":95,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_ebed7926","line":92,"updated":"2015-04-27 10:18:34.000000000","message":"Maybe 200 can be a constant?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":89,"context_line":"            self.text \u003d contents"},{"line_number":90,"context_line":"            self.contents \u003d contents.encode(encoding)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def ok(self, *args, **kwargs):"},{"line_number":93,"context_line":"        if self.code !\u003d 200:"},{"line_number":94,"context_line":"            return False"},{"line_number":95,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_4e0364b9","line":92,"in_reply_to":"9abe1de1_ebed7926","updated":"2015-06-05 00:08:52.000000000","message":"Done","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            self.contents \u003d contents.encode(encoding)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def ok(self, *args, **kwargs):"},{"line_number":93,"context_line":"        if self.code !\u003d 200:"},{"line_number":94,"context_line":"            return False"},{"line_number":95,"context_line":"        return True"},{"line_number":96,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_ab80a147","line":93,"updated":"2015-04-27 10:18:34.000000000","message":"return self.code \u003d\u003d 200","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            self.contents \u003d contents.encode(encoding)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def ok(self, *args, **kwargs):"},{"line_number":93,"context_line":"        if self.code !\u003d 200:"},{"line_number":94,"context_line":"            return False"},{"line_number":95,"context_line":"        return True"},{"line_number":96,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_6ef620d9","line":93,"in_reply_to":"9abe1de1_ab80a147","updated":"2015-06-05 00:08:52.000000000","message":"Done","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":101,"context_line":""},{"line_number":102,"context_line":"class FileResponse(StringResponse):"},{"line_number":103,"context_line":"    def __init__(self, path, contents, code\u003d200, encoding\u003d\u0027utf-8\u0027):"},{"line_number":104,"context_line":"        StringResponse.__init__(self, contents,"},{"line_number":105,"context_line":"                                code\u003dcode, encoding\u003dencoding)"},{"line_number":106,"context_line":"        self.url \u003d path"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_2b8db17b","line":104,"updated":"2015-04-27 10:18:34.000000000","message":"You could use super, since StringResponse is not an old style class.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":101,"context_line":""},{"line_number":102,"context_line":"class FileResponse(StringResponse):"},{"line_number":103,"context_line":"    def __init__(self, path, contents, code\u003d200, encoding\u003d\u0027utf-8\u0027):"},{"line_number":104,"context_line":"        StringResponse.__init__(self, contents,"},{"line_number":105,"context_line":"                                code\u003dcode, encoding\u003dencoding)"},{"line_number":106,"context_line":"        self.url \u003d path"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_ee8c5037","line":104,"in_reply_to":"9abe1de1_2b8db17b","updated":"2015-06-05 00:08:52.000000000","message":"Done","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        return self._response.url"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    def ok(self, redirects_ok\u003dFalse):"},{"line_number":127,"context_line":"        upper \u003d 300"},{"line_number":128,"context_line":"        if redirects_ok:"},{"line_number":129,"context_line":"            upper \u003d 400"},{"line_number":130,"context_line":"        if self.code \u003e\u003d 200 and self.code \u003c upper:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_cbc995ae","line":127,"updated":"2015-04-27 10:18:34.000000000","message":"Ditto, 300 and 400 can be constants.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        return self._response.url"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    def ok(self, redirects_ok\u003dFalse):"},{"line_number":127,"context_line":"        upper \u003d 300"},{"line_number":128,"context_line":"        if redirects_ok:"},{"line_number":129,"context_line":"            upper \u003d 400"},{"line_number":130,"context_line":"        if self.code \u003e\u003d 200 and self.code \u003c upper:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_ce8194fd","line":127,"in_reply_to":"9abe1de1_cbc995ae","updated":"2015-06-05 00:08:52.000000000","message":"Done","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        upper \u003d 300"},{"line_number":128,"context_line":"        if redirects_ok:"},{"line_number":129,"context_line":"            upper \u003d 400"},{"line_number":130,"context_line":"        if self.code \u003e\u003d 200 and self.code \u003c upper:"},{"line_number":131,"context_line":"            return True"},{"line_number":132,"context_line":"        else:"},{"line_number":133,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_6bc16980","line":130,"updated":"2015-04-27 10:18:34.000000000","message":"return self.code \u003e\u003d 200 and self.code \u003c upper.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        upper \u003d 300"},{"line_number":128,"context_line":"        if redirects_ok:"},{"line_number":129,"context_line":"            upper \u003d 400"},{"line_number":130,"context_line":"        if self.code \u003e\u003d 200 and self.code \u003c upper:"},{"line_number":131,"context_line":"            return True"},{"line_number":132,"context_line":"        else:"},{"line_number":133,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_0e8fac24","line":130,"in_reply_to":"9abe1de1_6bc16980","updated":"2015-06-05 00:08:52.000000000","message":"Done","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":149,"context_line":"        IOError.__init__(self, str(cause))"},{"line_number":150,"context_line":"        self.cause \u003d cause"},{"line_number":151,"context_line":"        self.code \u003d code"},{"line_number":152,"context_line":"        self.headers \u003d headers"},{"line_number":153,"context_line":"        if self.headers is None:"},{"line_number":154,"context_line":"            self.headers \u003d {}"},{"line_number":155,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_0b5e6de9","line":152,"updated":"2015-04-27 10:18:34.000000000","message":"self.headers \u003d headers or {}","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":174,"context_line":"    return ssl_args"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"def readurl(url, data\u003dNone, timeout\u003dNone, retries\u003d0, sec_between\u003d1,"},{"line_number":178,"context_line":"            headers\u003dNone, headers_cb\u003dNone, ssl_details\u003dNone,"},{"line_number":179,"context_line":"            check_status\u003dTrue, allow_redirects\u003dTrue, exception_cb\u003dNone):"},{"line_number":180,"context_line":"    \"\"\"Fetch a url (or post to one) with the given options.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_8b727d7b","line":177,"updated":"2015-04-27 10:18:34.000000000","message":"read_url.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":174,"context_line":"    return ssl_args"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"def readurl(url, data\u003dNone, timeout\u003dNone, retries\u003d0, sec_between\u003d1,"},{"line_number":178,"context_line":"            headers\u003dNone, headers_cb\u003dNone, ssl_details\u003dNone,"},{"line_number":179,"context_line":"            check_status\u003dTrue, allow_redirects\u003dTrue, exception_cb\u003dNone):"},{"line_number":180,"context_line":"    \"\"\"Fetch a url (or post to one) with the given options.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_ee93304e","line":177,"in_reply_to":"9abe1de1_8b727d7b","updated":"2015-06-05 00:08:52.000000000","message":"Done","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":177,"context_line":"def readurl(url, data\u003dNone, timeout\u003dNone, retries\u003d0, sec_between\u003d1,"},{"line_number":178,"context_line":"            headers\u003dNone, headers_cb\u003dNone, ssl_details\u003dNone,"},{"line_number":179,"context_line":"            check_status\u003dTrue, allow_redirects\u003dTrue, exception_cb\u003dNone):"},{"line_number":180,"context_line":"    \"\"\"Fetch a url (or post to one) with the given options.\"\"\""},{"line_number":181,"context_line":"    url \u003d _cleanurl(url)"},{"line_number":182,"context_line":"    req_args \u003d {"},{"line_number":183,"context_line":"        \u0027url\u0027: url,"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_2bf9314e","line":180,"updated":"2015-04-27 10:18:34.000000000","message":"Documenting the arguments should be nice, now you have to check the code to understand what this should be or that should do.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":179,"context_line":"            check_status\u003dTrue, allow_redirects\u003dTrue, exception_cb\u003dNone):"},{"line_number":180,"context_line":"    \"\"\"Fetch a url (or post to one) with the given options.\"\"\""},{"line_number":181,"context_line":"    url \u003d _cleanurl(url)"},{"line_number":182,"context_line":"    req_args \u003d {"},{"line_number":183,"context_line":"        \u0027url\u0027: url,"},{"line_number":184,"context_line":"    }"},{"line_number":185,"context_line":"    req_args.update(_get_ssl_args(url, ssl_details))"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_4b20e5f7","line":182,"updated":"2015-04-27 10:18:34.000000000","message":"Can\u0027t we pass the arguments directly to requests.request?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":179,"context_line":"            check_status\u003dTrue, allow_redirects\u003dTrue, exception_cb\u003dNone):"},{"line_number":180,"context_line":"    \"\"\"Fetch a url (or post to one) with the given options.\"\"\""},{"line_number":181,"context_line":"    url \u003d _cleanurl(url)"},{"line_number":182,"context_line":"    req_args \u003d {"},{"line_number":183,"context_line":"        \u0027url\u0027: url,"},{"line_number":184,"context_line":"    }"},{"line_number":185,"context_line":"    req_args.update(_get_ssl_args(url, ssl_details))"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_6ea06091","line":182,"in_reply_to":"9abe1de1_4b20e5f7","updated":"2015-06-05 00:08:52.000000000","message":"Sure, this is what this does in the end.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":203,"context_line":"    if data:"},{"line_number":204,"context_line":"        req_args[\u0027data\u0027] \u003d data"},{"line_number":205,"context_line":"    if sec_between is None:"},{"line_number":206,"context_line":"        sec_between \u003d -1"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    excps \u003d []"},{"line_number":209,"context_line":"    # Handle retrying ourselves since the built-in support"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_8b6ddd34","line":206,"updated":"2015-04-27 10:18:34.000000000","message":"Can sec_between be None?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":203,"context_line":"    if data:"},{"line_number":204,"context_line":"        req_args[\u0027data\u0027] \u003d data"},{"line_number":205,"context_line":"    if sec_between is None:"},{"line_number":206,"context_line":"        sec_between \u003d -1"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    excps \u003d []"},{"line_number":209,"context_line":"    # Handle retrying ourselves since the built-in support"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_ceaf547c","line":206,"in_reply_to":"9abe1de1_8b6ddd34","updated":"2015-06-05 00:08:52.000000000","message":"Not after we make it -1 ;)","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":210,"context_line":"    # doesn\u0027t handle sleeping between tries..."},{"line_number":211,"context_line":"    for i in range(0, manual_tries):"},{"line_number":212,"context_line":"        req_args[\u0027headers\u0027] \u003d headers_cb(url)"},{"line_number":213,"context_line":"        filtered_req_args \u003d {}"},{"line_number":214,"context_line":"        for (k, v) in req_args.items():"},{"line_number":215,"context_line":"            if k \u003d\u003d \u0027data\u0027:"},{"line_number":216,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_cbd075cc","line":213,"updated":"2015-04-27 10:18:34.000000000","message":"filtered_req_args \u003d req_args.copy()\nfiltered_req_args.pop(\u0027data\u0027, None)\n\nSomething along these lines?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":210,"context_line":"    # doesn\u0027t handle sleeping between tries..."},{"line_number":211,"context_line":"    for i in range(0, manual_tries):"},{"line_number":212,"context_line":"        req_args[\u0027headers\u0027] \u003d headers_cb(url)"},{"line_number":213,"context_line":"        filtered_req_args \u003d {}"},{"line_number":214,"context_line":"        for (k, v) in req_args.items():"},{"line_number":215,"context_line":"            if k \u003d\u003d \u0027data\u0027:"},{"line_number":216,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_eeba10c0","line":213,"in_reply_to":"9abe1de1_cbd075cc","updated":"2015-06-05 00:08:52.000000000","message":"Sure.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":251,"context_line":"    return None  # Should throw before this..."},{"line_number":252,"context_line":""},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"def wait_for_url(urls, max_wait\u003dNone, timeout\u003dNone,"},{"line_number":255,"context_line":"                 status_cb\u003dNone, headers_cb\u003dNone, sleep_time\u003d1,"},{"line_number":256,"context_line":"                 exception_cb\u003dNone):"},{"line_number":257,"context_line":"    \"\"\"Wait for one of many urls to respond correctly."}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_eb4e9995","line":254,"updated":"2015-04-27 10:18:34.000000000","message":"This is called wait_for_url but it actually waits for multiple urls. Can it be renamed?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":251,"context_line":"    return None  # Should throw before this..."},{"line_number":252,"context_line":""},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"def wait_for_url(urls, max_wait\u003dNone, timeout\u003dNone,"},{"line_number":255,"context_line":"                 status_cb\u003dNone, headers_cb\u003dNone, sleep_time\u003d1,"},{"line_number":256,"context_line":"                 exception_cb\u003dNone):"},{"line_number":257,"context_line":"    \"\"\"Wait for one of many urls to respond correctly."}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_4ec4843f","line":254,"in_reply_to":"9abe1de1_eb4e9995","updated":"2015-06-05 00:08:52.000000000","message":"Sure.","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    while True:"},{"line_number":300,"context_line":"        sleep_time \u003d int(loop_n / 5) + 1"},{"line_number":301,"context_line":"        for url in urls:"},{"line_number":302,"context_line":"            now \u003d time.time()"},{"line_number":303,"context_line":"            if loop_n !\u003d 0:"},{"line_number":304,"context_line":"                if timeup(max_wait, start_time):"},{"line_number":305,"context_line":"                    break"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_2b037111","line":302,"updated":"2015-04-27 10:18:34.000000000","message":"Can this block be refactored into a separate function?","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    while True:"},{"line_number":300,"context_line":"        sleep_time \u003d int(loop_n / 5) + 1"},{"line_number":301,"context_line":"        for url in urls:"},{"line_number":302,"context_line":"            now \u003d time.time()"},{"line_number":303,"context_line":"            if loop_n !\u003d 0:"},{"line_number":304,"context_line":"                if timeup(max_wait, start_time):"},{"line_number":305,"context_line":"                    break"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_ced074cc","line":302,"in_reply_to":"9abe1de1_2b037111","updated":"2015-06-05 00:08:52.000000000","message":"Probably ;)","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"96b962c82db92960eacefdfc4bbc50d2dcd60877","unresolved":false,"context_lines":[{"line_number":354,"context_line":"                  sleep_time)"},{"line_number":355,"context_line":"        time.sleep(sleep_time)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    return False"}],"source_content_type":"text/x-python","patch_set":4,"id":"9abe1de1_2648485b","line":357,"updated":"2015-04-27 10:18:34.000000000","message":"Why not raising something? An API is really dubious when it returns something (an url, a response etc) and False in case of failures. False what? The url is false? it\u0027s false that the function worked or not? Really weird if you think about it. :-)","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f50cc7b2916be66cd9a603dadc047856fca7772a","unresolved":false,"context_lines":[{"line_number":354,"context_line":"                  sleep_time)"},{"line_number":355,"context_line":"        time.sleep(sleep_time)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    return False"}],"source_content_type":"text/x-python","patch_set":4,"id":"3afb71cf_0eee8c8b","line":357,"in_reply_to":"9abe1de1_2648485b","updated":"2015-06-05 00:08:52.000000000","message":"What would u raise? Could return None, not sure what would be the right thing to raise here...","commit_id":"09100408ed1b7743667a9954c28c0d51f755a39b"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"if six.PY2:"},{"line_number":38,"context_line":"    import httplib"},{"line_number":39,"context_line":"    NOT_FOUND \u003d httplib.NOT_FOUND"},{"line_number":40,"context_line":"    OK \u003d httplib.OK"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_4a69058b","line":37,"updated":"2015-06-05 09:20:15.000000000","message":"Could we replace this with imports from six.moves?\n\n from six.moves.http_client import NOT_FOUND, OK\n from six.moves.http_client import MULTIPLE_CHOICES as _MULTIPLE_CHOICES\n from six.moves.http_client import BAD_REQUEST as _BAD_REQUEST","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"cda74070f544d69cb5752a3d349f92fe5be4b249","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"if six.PY2:"},{"line_number":38,"context_line":"    import httplib"},{"line_number":39,"context_line":"    NOT_FOUND \u003d httplib.NOT_FOUND"},{"line_number":40,"context_line":"    OK \u003d httplib.OK"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_e3ac45ef","line":37,"in_reply_to":"3afb71cf_4a69058b","updated":"2015-06-05 18:55:23.000000000","message":"Done","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    return urlunparse(parsed_url)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"def combine_url(base, *add_ons):"},{"line_number":69,"context_line":"    \"\"\"Creates a url from many pieces.\"\"\""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    def combine_single(url, add_on):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_4569f68a","line":68,"updated":"2015-06-05 09:20:15.000000000","message":"Some tests for this would be good; it seems like the sort of thing that could easily be broken without us knowing. :)","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b20df58c8dde93ee656f2fbd5ab6d37fcd84c125","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    return urlunparse(parsed_url)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"def combine_url(base, *add_ons):"},{"line_number":69,"context_line":"    \"\"\"Creates a url from many pieces.\"\"\""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    def combine_single(url, add_on):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_599c4569","line":68,"updated":"2015-06-05 09:59:05.000000000","message":"This doesn\u0027t seem to be tested. Could you write a test for it as well?","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b20df58c8dde93ee656f2fbd5ab6d37fcd84c125","unresolved":false,"context_lines":[{"line_number":83,"context_line":"    return url"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"# Made to have same accessors as UrlResponse so that the"},{"line_number":87,"context_line":"# read_file_or_url can return this or that object and the"},{"line_number":88,"context_line":"# \u0027user\u0027 of those objects will not need to know the difference."},{"line_number":89,"context_line":"class StringResponse(object):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_99799d32","line":86,"updated":"2015-06-05 09:59:05.000000000","message":"Can you make this comment a docstring for StringResponse instead? ;-)","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"cda74070f544d69cb5752a3d349f92fe5be4b249","unresolved":false,"context_lines":[{"line_number":83,"context_line":"    return url"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"# Made to have same accessors as UrlResponse so that the"},{"line_number":87,"context_line":"# read_file_or_url can return this or that object and the"},{"line_number":88,"context_line":"# \u0027user\u0027 of those objects will not need to know the difference."},{"line_number":89,"context_line":"class StringResponse(object):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_a3d88d1e","line":86,"in_reply_to":"3afb71cf_99799d32","updated":"2015-06-05 18:55:23.000000000","message":"Just going to remove, since \u0027read_file_or_url\u0027 doesn\u0027t exist yet anyway.","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        self.url \u003d path"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"class UrlResponse(object):"},{"line_number":119,"context_line":"    def __init__(self, response):"},{"line_number":120,"context_line":"        self._response \u003d response"},{"line_number":121,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_4a00e5aa","line":118,"updated":"2015-06-05 09:20:15.000000000","message":"I feel like this class existed to ease support of older versions of requests; if we don\u0027t need to support older versions of requests, is it worth dropping this and ensuring that StringResponse and (by extension) FileResponse behave the same as a requests Response?","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"f1bc8a29b152581ab59184725b1e3fef79c6cfcc","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        self.url \u003d path"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"class UrlResponse(object):"},{"line_number":119,"context_line":"    def __init__(self, response):"},{"line_number":120,"context_line":"        self._response \u003d response"},{"line_number":121,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_def59e83","line":118,"in_reply_to":"3afb71cf_43fe796c","updated":"2015-06-05 19:29:15.000000000","message":"If it quacks like a duck, no-one will care if it\u0027s a direct requests object. I would have thought, in fact, for most Python developers that would be a positive _feature_ rather than the opposite. :p","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"894c4c01f2d266ab0c863cec01007828e1e40f05","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        self.url \u003d path"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"class UrlResponse(object):"},{"line_number":119,"context_line":"    def __init__(self, response):"},{"line_number":120,"context_line":"        self._response \u003d response"},{"line_number":121,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_5c99c16d","line":118,"in_reply_to":"3afb71cf_4a00e5aa","updated":"2015-06-05 15:33:13.000000000","message":"Unsure.","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"cda74070f544d69cb5752a3d349f92fe5be4b249","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        self.url \u003d path"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"class UrlResponse(object):"},{"line_number":119,"context_line":"    def __init__(self, response):"},{"line_number":120,"context_line":"        self._response \u003d response"},{"line_number":121,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_43fe796c","line":118,"in_reply_to":"3afb71cf_5c99c16d","updated":"2015-06-05 18:55:23.000000000","message":"It also likely exists to provide a abstraction for \u0027read_file_or_url\u0027 so that people are not just getting requests objects/classes back (which wouldn\u0027t work for reading a file); will leave for now (doesn\u0027t seem to harm much).","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":188,"context_line":"          instead of GET)"},{"line_number":189,"context_line":"    timeout: the timeout (in seconds) to wait for a response"},{"line_number":190,"context_line":"    headers: any headers to provide (and send along) in the request"},{"line_number":191,"context_line":"    headers_cb: called method with single argument of url to get headers"},{"line_number":192,"context_line":"                for request (existence of a header callback overrides"},{"line_number":193,"context_line":"                the usage of a previous headers argument)"},{"line_number":194,"context_line":"    exception_cb: call method with 2 arguments \u0027request_args\u0027 (the"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_6adba11c","line":191,"updated":"2015-06-05 09:20:15.000000000","message":"I\u0027ve always found headers_cb to be a fairly obtuse way of specifying headers; I\u0027d be tempted to drop it while we have the chance...","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"894c4c01f2d266ab0c863cec01007828e1e40f05","unresolved":false,"context_lines":[{"line_number":188,"context_line":"          instead of GET)"},{"line_number":189,"context_line":"    timeout: the timeout (in seconds) to wait for a response"},{"line_number":190,"context_line":"    headers: any headers to provide (and send along) in the request"},{"line_number":191,"context_line":"    headers_cb: called method with single argument of url to get headers"},{"line_number":192,"context_line":"                for request (existence of a header callback overrides"},{"line_number":193,"context_line":"                the usage of a previous headers argument)"},{"line_number":194,"context_line":"    exception_cb: call method with 2 arguments \u0027request_args\u0027 (the"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_1ca469a4","line":191,"in_reply_to":"3afb71cf_6adba11c","updated":"2015-06-05 15:33:13.000000000","message":"Seems fine with me :-P","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":218,"context_line":"    manual_tries \u003d 1"},{"line_number":219,"context_line":"    if retries:"},{"line_number":220,"context_line":"        manual_tries \u003d max(int(retries) + 1, 1)"},{"line_number":221,"context_line":"    if not headers:"},{"line_number":222,"context_line":"        headers \u003d {"},{"line_number":223,"context_line":"            \u0027User-Agent\u0027: \u0027Cloud-Init/%s\u0027 % (version.version_string()),"},{"line_number":224,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_aacab94d","line":221,"updated":"2015-06-05 09:20:15.000000000","message":"Should we be sending a User-Agent even when headers are specified?","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"894c4c01f2d266ab0c863cec01007828e1e40f05","unresolved":false,"context_lines":[{"line_number":218,"context_line":"    manual_tries \u003d 1"},{"line_number":219,"context_line":"    if retries:"},{"line_number":220,"context_line":"        manual_tries \u003d max(int(retries) + 1, 1)"},{"line_number":221,"context_line":"    if not headers:"},{"line_number":222,"context_line":"        headers \u003d {"},{"line_number":223,"context_line":"            \u0027User-Agent\u0027: \u0027Cloud-Init/%s\u0027 % (version.version_string()),"},{"line_number":224,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_9cb619db","line":221,"in_reply_to":"3afb71cf_aacab94d","updated":"2015-06-05 15:33:13.000000000","message":"Probably?","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":232,"context_line":"        sec_between \u003d -1"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    excps \u003d []"},{"line_number":235,"context_line":"    # Handle retrying ourselves since the built-in support"},{"line_number":236,"context_line":"    # doesn\u0027t handle sleeping between tries..."},{"line_number":237,"context_line":"    for i in range(0, manual_tries):"},{"line_number":238,"context_line":"        req_args[\u0027headers\u0027] \u003d headers_cb(url)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_6a93a1fb","line":235,"updated":"2015-06-05 09:20:15.000000000","message":"I don\u0027t think this is true any longer; if we use urllib3\u0027s Retry[0] with back-off by mounting it to a requests session, as per the requests.adapters.HTTPAdapter example in [1], then we can get something useful.\n\nIt won\u0027t allow for precise timing between retries, but backoff is arguably better. If we do want precise timing between retries (as we have in cloud-init 0.7.x) we could sub-class Retry and override sleep or get_backoff_time.\n\n[0] https://urllib3.readthedocs.org/en/latest/helpers.html#module-urllib3.util.retry\n[1] http://docs.python-requests.org/en/latest/api/#main-interface","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"894c4c01f2d266ab0c863cec01007828e1e40f05","unresolved":false,"context_lines":[{"line_number":232,"context_line":"        sec_between \u003d -1"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    excps \u003d []"},{"line_number":235,"context_line":"    # Handle retrying ourselves since the built-in support"},{"line_number":236,"context_line":"    # doesn\u0027t handle sleeping between tries..."},{"line_number":237,"context_line":"    for i in range(0, manual_tries):"},{"line_number":238,"context_line":"        req_args[\u0027headers\u0027] \u003d headers_cb(url)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_3c03a575","line":235,"in_reply_to":"3afb71cf_6a93a1fb","updated":"2015-06-05 15:33:13.000000000","message":"Hmmm, intersting, might do that.","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":268,"context_line":"                time.sleep(sec_between)"},{"line_number":269,"context_line":"    if excps:"},{"line_number":270,"context_line":"        raise excps[-1]"},{"line_number":271,"context_line":"    return None  # Should throw before this..."},{"line_number":272,"context_line":""},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"def wait_for_one_of_urls(urls, max_wait\u003dNone, timeout\u003dNone,"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_655512c5","line":271,"updated":"2015-06-05 09:20:15.000000000","message":"Would it make sense to raise an exception of some description here? If we should never get here, then we\u0027re going to be horribly broken whatever happens, so raising an exception maybe makes it a little easier to debug.","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b20df58c8dde93ee656f2fbd5ab6d37fcd84c125","unresolved":false,"context_lines":[{"line_number":268,"context_line":"                time.sleep(sec_between)"},{"line_number":269,"context_line":"    if excps:"},{"line_number":270,"context_line":"        raise excps[-1]"},{"line_number":271,"context_line":"    return None  # Should throw before this..."},{"line_number":272,"context_line":""},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"def wait_for_one_of_urls(urls, max_wait\u003dNone, timeout\u003dNone,"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_4b9c6769","line":271,"in_reply_to":"3afb71cf_655512c5","updated":"2015-06-05 09:59:05.000000000","message":"+1, said the exactly same thing here: https://review.openstack.org/#/c/170242/4/cloudinit/url_helper.py","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b20df58c8dde93ee656f2fbd5ab6d37fcd84c125","unresolved":false,"context_lines":[{"line_number":270,"context_line":"        raise excps[-1]"},{"line_number":271,"context_line":"    return None  # Should throw before this..."},{"line_number":272,"context_line":""},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"def wait_for_one_of_urls(urls, max_wait\u003dNone, timeout\u003dNone,"},{"line_number":275,"context_line":"                         status_cb\u003dNone, headers_cb\u003dNone, sleep_time\u003d1,"},{"line_number":276,"context_line":"                         exception_cb\u003dNone):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_99f51d85","line":273,"updated":"2015-06-05 09:59:05.000000000","message":"That\u0027s one pretty long functon name. wait_any_url as an alternative?","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b550d649e7bda6e466ec481e15f63cfca3340dfb","unresolved":false,"context_lines":[{"line_number":270,"context_line":"        raise excps[-1]"},{"line_number":271,"context_line":"    return None  # Should throw before this..."},{"line_number":272,"context_line":""},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"def wait_for_one_of_urls(urls, max_wait\u003dNone, timeout\u003dNone,"},{"line_number":275,"context_line":"                         status_cb\u003dNone, headers_cb\u003dNone, sleep_time\u003d1,"},{"line_number":276,"context_line":"                         exception_cb\u003dNone):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_be06621e","line":273,"in_reply_to":"3afb71cf_99f51d85","updated":"2015-06-05 19:43:48.000000000","message":"Done","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":16703,"name":"Daniel Watkins","email":"daniel.watkins@canonical.com","username":"Odd_Bloke"},"change_message_id":"903a1bfe1ebbba75c5ec4492ee80fb3d72e31b20","unresolved":false,"context_lines":[{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    urls:      a list of urls to try"},{"line_number":280,"context_line":"    max_wait:  roughly the maximum time to wait before giving up"},{"line_number":281,"context_line":"               The max time is *actually* len(urls)*timeout as each url will"},{"line_number":282,"context_line":"               be tried once and given the timeout provided."},{"line_number":283,"context_line":"               a number \u003c\u003d 0 will always result in only one try"},{"line_number":284,"context_line":"    timeout:   the timeout provided to urlopen"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_05d53e42","line":281,"updated":"2015-06-05 09:20:15.000000000","message":"I don\u0027t think this is accurate; on line 325 of the diff, we could break on the second attempt of the first URL, without trying the others a second time.\n\nI think the _minimum_ time is len(urls)*timeout...","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b550d649e7bda6e466ec481e15f63cfca3340dfb","unresolved":false,"context_lines":[{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    urls:      a list of urls to try"},{"line_number":280,"context_line":"    max_wait:  roughly the maximum time to wait before giving up"},{"line_number":281,"context_line":"               The max time is *actually* len(urls)*timeout as each url will"},{"line_number":282,"context_line":"               be tried once and given the timeout provided."},{"line_number":283,"context_line":"               a number \u003c\u003d 0 will always result in only one try"},{"line_number":284,"context_line":"    timeout:   the timeout provided to urlopen"}],"source_content_type":"text/x-python","patch_set":8,"id":"3afb71cf_de091e33","line":281,"in_reply_to":"3afb71cf_05d53e42","updated":"2015-06-05 19:43:48.000000000","message":"removing","commit_id":"4b186b8e932c2c8a5707df1eefff78182b5b68aa"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"4c124b997c23d99a7b9a9802c0a551199428aea0","unresolved":false,"context_lines":[{"line_number":77,"context_line":"class _Retry(urllib3_util.Retry):"},{"line_number":78,"context_line":"    def is_forced_retry(self, method, status_code):"},{"line_number":79,"context_line":"        # Allow \u003e\u003d 400 to be tried..."},{"line_number":80,"context_line":"        if status_code \u003c _BAD_REQUEST:"},{"line_number":81,"context_line":"            return False"},{"line_number":82,"context_line":"        return True"},{"line_number":83,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_e5265f67","line":80,"updated":"2015-06-08 13:16:59.000000000","message":"return status_code \u003e\u003d BAD_REQUEST","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"764b779541265e092d6fe7d97c5d92f591709bcc","unresolved":false,"context_lines":[{"line_number":77,"context_line":"class _Retry(urllib3_util.Retry):"},{"line_number":78,"context_line":"    def is_forced_retry(self, method, status_code):"},{"line_number":79,"context_line":"        # Allow \u003e\u003d 400 to be tried..."},{"line_number":80,"context_line":"        if status_code \u003c _BAD_REQUEST:"},{"line_number":81,"context_line":"            return False"},{"line_number":82,"context_line":"        return True"},{"line_number":83,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_bf305202","line":80,"in_reply_to":"3afb71cf_e5265f67","updated":"2015-06-09 03:36:35.000000000","message":"Done","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"4c124b997c23d99a7b9a9802c0a551199428aea0","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        upper \u003d _MULTIPLE_CHOICES"},{"line_number":117,"context_line":"        if redirects_ok:"},{"line_number":118,"context_line":"            upper \u003d _BAD_REQUEST"},{"line_number":119,"context_line":"        if self.status_code \u003e\u003d OK and self.status_code \u003c upper:"},{"line_number":120,"context_line":"            return True"},{"line_number":121,"context_line":"        else:"},{"line_number":122,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_85e32b05","line":119,"updated":"2015-06-08 13:16:59.000000000","message":"return self.status_code \u003e\u003d OK and self.status_code \u003c upper.","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"764b779541265e092d6fe7d97c5d92f591709bcc","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        upper \u003d _MULTIPLE_CHOICES"},{"line_number":117,"context_line":"        if redirects_ok:"},{"line_number":118,"context_line":"            upper \u003d _BAD_REQUEST"},{"line_number":119,"context_line":"        if self.status_code \u003e\u003d OK and self.status_code \u003c upper:"},{"line_number":120,"context_line":"            return True"},{"line_number":121,"context_line":"        else:"},{"line_number":122,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_5f1cbe76","line":119,"in_reply_to":"3afb71cf_85e32b05","updated":"2015-06-09 03:36:35.000000000","message":"Done","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"4c124b997c23d99a7b9a9802c0a551199428aea0","unresolved":false,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":"class UrlError(IOError):"},{"line_number":137,"context_line":"    def __init__(self, cause, code\u003dNone, headers\u003dNone):"},{"line_number":138,"context_line":"        IOError.__init__(self, str(cause))"},{"line_number":139,"context_line":"        self.cause \u003d cause"},{"line_number":140,"context_line":"        self.status_code \u003d code"},{"line_number":141,"context_line":"        self.headers \u003d headers or {}"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_289c4ebf","line":138,"updated":"2015-06-08 13:16:59.000000000","message":"That\u0027s a newstyle class on Python 2.7+, so you could use super instead of this old idiom.","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"764b779541265e092d6fe7d97c5d92f591709bcc","unresolved":false,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":"class UrlError(IOError):"},{"line_number":137,"context_line":"    def __init__(self, cause, code\u003dNone, headers\u003dNone):"},{"line_number":138,"context_line":"        IOError.__init__(self, str(cause))"},{"line_number":139,"context_line":"        self.cause \u003d cause"},{"line_number":140,"context_line":"        self.status_code \u003d code"},{"line_number":141,"context_line":"        self.headers \u003d headers or {}"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_3f134268","line":138,"in_reply_to":"3afb71cf_289c4ebf","updated":"2015-06-09 03:36:35.000000000","message":"Done","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"4c124b997c23d99a7b9a9802c0a551199428aea0","unresolved":false,"context_lines":[{"line_number":199,"context_line":"    if \u0027User-Agent\u0027 not in headers:"},{"line_number":200,"context_line":"        headers[\u0027User-Agent\u0027] \u003d \u0027Cloud-Init/%s\u0027 % (version.version_string())"},{"line_number":201,"context_line":"    req_args[\u0027headers\u0027] \u003d headers"},{"line_number":202,"context_line":"    s \u003d requests.Session()"},{"line_number":203,"context_line":"    if retries:"},{"line_number":204,"context_line":"        r \u003d _Retry(total\u003dmax(int(retries), 0),"},{"line_number":205,"context_line":"                   raise_on_redirect\u003dnot allow_redirects)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_e5b09fdf","line":202,"updated":"2015-06-08 13:16:59.000000000","message":"Please use more descriptive names: session, retry. :-)","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"764b779541265e092d6fe7d97c5d92f591709bcc","unresolved":false,"context_lines":[{"line_number":199,"context_line":"    if \u0027User-Agent\u0027 not in headers:"},{"line_number":200,"context_line":"        headers[\u0027User-Agent\u0027] \u003d \u0027Cloud-Init/%s\u0027 % (version.version_string())"},{"line_number":201,"context_line":"    req_args[\u0027headers\u0027] \u003d headers"},{"line_number":202,"context_line":"    s \u003d requests.Session()"},{"line_number":203,"context_line":"    if retries:"},{"line_number":204,"context_line":"        r \u003d _Retry(total\u003dmax(int(retries), 0),"},{"line_number":205,"context_line":"                   raise_on_redirect\u003dnot allow_redirects)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_9f02360a","line":202,"in_reply_to":"3afb71cf_e5b09fdf","updated":"2015-06-09 03:36:35.000000000","message":"Done","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"4c124b997c23d99a7b9a9802c0a551199428aea0","unresolved":false,"context_lines":[{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    loop_n \u003d 0"},{"line_number":266,"context_line":"    while True:"},{"line_number":267,"context_line":"        sleep_time \u003d int(loop_n / 5) + 1"},{"line_number":268,"context_line":"        for url in urls:"},{"line_number":269,"context_line":"            current_time \u003d now()"},{"line_number":270,"context_line":"            if loop_n !\u003d 0:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_e85ab682","line":267,"updated":"2015-06-08 13:16:59.000000000","message":"From where 5 is coming from? Does it mean something or it\u0027s just a random number?","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"764b779541265e092d6fe7d97c5d92f591709bcc","unresolved":false,"context_lines":[{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    loop_n \u003d 0"},{"line_number":266,"context_line":"    while True:"},{"line_number":267,"context_line":"        sleep_time \u003d int(loop_n / 5) + 1"},{"line_number":268,"context_line":"        for url in urls:"},{"line_number":269,"context_line":"            current_time \u003d now()"},{"line_number":270,"context_line":"            if loop_n !\u003d 0:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_222449ad","line":267,"in_reply_to":"3afb71cf_e85ab682","updated":"2015-06-09 03:36:35.000000000","message":"Might want to ask smoser on that one :-P\n\nI\u0027m not sure why he picked 5,\n\nAnyway, this graphs to be:\n\nhttps://www.desmos.com/calculator/e5d5uwe5gu\n\nSo depending on how many loops have been attempted the backoff time before retrying will continue to increase at the rate of that graph...","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"4c124b997c23d99a7b9a9802c0a551199428aea0","unresolved":false,"context_lines":[{"line_number":265,"context_line":"    loop_n \u003d 0"},{"line_number":266,"context_line":"    while True:"},{"line_number":267,"context_line":"        sleep_time \u003d int(loop_n / 5) + 1"},{"line_number":268,"context_line":"        for url in urls:"},{"line_number":269,"context_line":"            current_time \u003d now()"},{"line_number":270,"context_line":"            if loop_n !\u003d 0:"},{"line_number":271,"context_line":"                if timeup(max_wait, start_time):"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_684a46c7","line":268,"updated":"2015-06-08 13:16:59.000000000","message":"for loop_n, url in enumerate(urls)?","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"764b779541265e092d6fe7d97c5d92f591709bcc","unresolved":false,"context_lines":[{"line_number":265,"context_line":"    loop_n \u003d 0"},{"line_number":266,"context_line":"    while True:"},{"line_number":267,"context_line":"        sleep_time \u003d int(loop_n / 5) + 1"},{"line_number":268,"context_line":"        for url in urls:"},{"line_number":269,"context_line":"            current_time \u003d now()"},{"line_number":270,"context_line":"            if loop_n !\u003d 0:"},{"line_number":271,"context_line":"                if timeup(max_wait, start_time):"}],"source_content_type":"text/x-python","patch_set":10,"id":"3afb71cf_e23631e6","line":268,"in_reply_to":"3afb71cf_684a46c7","updated":"2015-06-09 03:36:35.000000000","message":"Not exactly, since loop_n is incremented outside of this loop, not inside it, so don\u0027t think that can be done.","commit_id":"717653570ea2f6905f4bf4d466b96cd823589df8"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b6601c7d250d6ebcfb2a1ba8ddf1620fdc585b38","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    if not parsed_url[1] and parsed_url[2]:"},{"line_number":52,"context_line":"        # Swap these since this seems to be a common"},{"line_number":53,"context_line":"        # occurrence when given urls like \u0027www.google.com\u0027"},{"line_number":54,"context_line":"        parsed_url[1] \u003d parsed_url[2]"},{"line_number":55,"context_line":"        parsed_url[2] \u003d \u0027\u0027"},{"line_number":56,"context_line":"    return urlunparse(parsed_url)"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_039948c4","line":54,"updated":"2015-06-09 09:30:21.000000000","message":"Just to be sure, this handles cases such as \u0027www.google.com\u0027, where the path would contain the netloc as well and netloc is empty?\n\nIf so, if the url has a path (\u0027www.google.com/lala\u0027), then this code will make the netloc to be \u0027www.google.com/lala\u0027, whilst the path will then be empty. That sounds wrong.","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"7669ae77dbe53a41930c4d19833103471ba8d9eb","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    if not parsed_url[1] and parsed_url[2]:"},{"line_number":52,"context_line":"        # Swap these since this seems to be a common"},{"line_number":53,"context_line":"        # occurrence when given urls like \u0027www.google.com\u0027"},{"line_number":54,"context_line":"        parsed_url[1] \u003d parsed_url[2]"},{"line_number":55,"context_line":"        parsed_url[2] \u003d \u0027\u0027"},{"line_number":56,"context_line":"    return urlunparse(parsed_url)"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_f93d8ddd","line":54,"in_reply_to":"3afb71cf_039948c4","updated":"2015-06-10 04:14:54.000000000","message":"Soooo,\n\nFrom a few examples,\n\nThis is the main one that blows up http://paste.openstack.org/show/279944/ (requests seems to always want a scheme),\n\nSo the `_clean_url` willl make sure one exists:\n\nA few examples (probably should be test cases or something)...\n\n \u003e\u003e\u003e _clean_url(\"www.google.com/a?b\u003dc\")\n \u0027http://www.google.com/a?b\u003dc\u0027\n\n  \u003e\u003e\u003e _clean_url(\"www.google.com\")\n  \u0027http://www.google.com\u0027\n\n \u003e\u003e\u003e _clean_url(\"www.google.com\")\n \u0027http://www.google.com\u0027\n\nSo this makes sure that scheme-less uri\u0027s get fixed, which seems to be a good thing. We could just let requests blow-up I suppose, except users probably most of the time forget to put in the http or https parts.","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"7504cda8239e8d39dea9459f8b133783a17b4da6","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    if not parsed_url[1] and parsed_url[2]:"},{"line_number":52,"context_line":"        # Swap these since this seems to be a common"},{"line_number":53,"context_line":"        # occurrence when given urls like \u0027www.google.com\u0027"},{"line_number":54,"context_line":"        parsed_url[1] \u003d parsed_url[2]"},{"line_number":55,"context_line":"        parsed_url[2] \u003d \u0027\u0027"},{"line_number":56,"context_line":"    return urlunparse(parsed_url)"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_374b175b","line":54,"in_reply_to":"3afb71cf_f93d8ddd","updated":"2015-06-10 13:48:56.000000000","message":"Makes sense, thanks.","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"b6601c7d250d6ebcfb2a1ba8ddf1620fdc585b38","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    return urlunparse(parsed_url)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def combine_url(base, *add_ons):"},{"line_number":60,"context_line":"    \"\"\"Creates a url from many pieces.\"\"\""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def combine_single(url, add_on):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_630b5c8f","line":59,"updated":"2015-06-09 09:30:21.000000000","message":"This sounds a lot like ``posixpath.join(base, *add_ons)``. Do you have currently in cloud-init an usecase for combine_url where posixpath.join doesn\u0027t do the job?","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"7669ae77dbe53a41930c4d19833103471ba8d9eb","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    return urlunparse(parsed_url)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def combine_url(base, *add_ons):"},{"line_number":60,"context_line":"    \"\"\"Creates a url from many pieces.\"\"\""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def combine_single(url, add_on):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_b953956a","line":59,"in_reply_to":"3afb71cf_630b5c8f","updated":"2015-06-10 04:14:54.000000000","message":"Maybe not yet, can remove it, seem fine? This one does the urlquoting which is needed for urls.","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b9cafac1d6bdcfec405eda8e5c85c0e803c9e88f","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    return urlunparse(parsed_url)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def combine_url(base, *add_ons):"},{"line_number":60,"context_line":"    \"\"\"Creates a url from many pieces.\"\"\""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def combine_single(url, add_on):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_b51b7580","line":59,"in_reply_to":"3afb71cf_97f52bee","updated":"2015-06-10 18:11:21.000000000","message":"Done","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"},{"author":{"_account_id":13538,"name":"Claudiu Popa","email":"cpopa@cloudbasesolutions.com","username":"PCManticore"},"change_message_id":"7504cda8239e8d39dea9459f8b133783a17b4da6","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    return urlunparse(parsed_url)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def combine_url(base, *add_ons):"},{"line_number":60,"context_line":"    \"\"\"Creates a url from many pieces.\"\"\""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def combine_single(url, add_on):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3afb71cf_97f52bee","line":59,"in_reply_to":"3afb71cf_b953956a","updated":"2015-06-10 13:48:56.000000000","message":"I think we can remove it. Skimming through cloud-init\u0027s usage of this, it seems that urlquoting is an unused feature.","commit_id":"4014a2bb9fe157ae0e44f78e934ffb66c5b20add"}]}
