)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7b4c12017292a9bb74b8ec19032182044e319554","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Jamie Lennox \u003cjamielennox@redhat.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2013-09-23 13:26:20 +1000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Implement discovery of client versions"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Allow discovery of the API versions a server supports and client"},{"line_number":10,"context_line":"creation based on this."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"AAAAS3%2F%2FnCg%3D","line":7,"updated":"2013-09-24 00:19:49.000000000","message":"suggest change the title since this isn\u0027t about discovering client versions up identity API versions.","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7b4c12017292a9bb74b8ec19032182044e319554","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Implement discovery of client versions"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Allow discovery of the API versions a server supports and client"},{"line_number":10,"context_line":"creation based on this."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Implements: blueprint api-version-discovery"},{"line_number":13,"context_line":"Change-Id: I63e6759889066a784dc47e35152c82e1ead7951d"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"AAAAS3%2F%2FnCU%3D","line":10,"updated":"2013-09-24 00:19:49.000000000","message":"This needs more documentation either in the blueprint or here in the commit message... how is someone supposed to use this?","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"}],"keystoneclient/client.py":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"3f43d0be17889ff3e9061be10764855eaa54e842","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    verify \u003d not insecure"},{"line_number":31,"context_line":"    if cacert:"},{"line_number":32,"context_line":"        verify \u003d cacert"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    if original_ip:"},{"line_number":35,"context_line":"        headers[\u0027Forwarded\u0027] \u003d \"for\u003d%s;by\u003d%s\" % (original_ip,"},{"line_number":36,"context_line":"                                                 httpclient.USER_AGENT)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAQn%2F%2Flts%3D","line":33,"updated":"2013-07-27 01:43:50.000000000","message":"None of the if statements here seem to be run in the unit tests.","commit_id":"7bd23b355bd1d112c9bfa743630b5f0ee3fd241a"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"3f43d0be17889ff3e9061be10764855eaa54e842","unresolved":false,"context_lines":[{"line_number":63,"context_line":"                \"%s/%s\" % (resp.url.rstrip(\u0027/\u0027), \u0027v2.0\u0027))]"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":66,"context_line":"        _logger.warning(\"Invalid Response code from %s\" % resp.url)"},{"line_number":67,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"},{"line_number":68,"context_line":"                                          resp.url)"},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAQn%2F%2Fltc%3D","line":66,"updated":"2013-07-27 01:43:50.000000000","message":"Untested","commit_id":"7bd23b355bd1d112c9bfa743630b5f0ee3fd241a"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"3f43d0be17889ff3e9061be10764855eaa54e842","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        try:"},{"line_number":77,"context_line":"            response_values \u003d [response[\u0027version\u0027]]"},{"line_number":78,"context_line":"        except KeyError:"},{"line_number":79,"context_line":"            raise exceptions.DiscoveryFailure(\"Invalid Response\")"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    for version_data in response_values:"},{"line_number":82,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAQn%2F%2FltQ%3D","line":79,"updated":"2013-07-27 01:43:50.000000000","message":"untested","commit_id":"7bd23b355bd1d112c9bfa743630b5f0ee3fd241a"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"3f43d0be17889ff3e9061be10764855eaa54e842","unresolved":false,"context_lines":[{"line_number":96,"context_line":"                    versions.append((version_number, client_class, url))"},{"line_number":97,"context_line":"                    break"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"        except (KeyError, ValueError):"},{"line_number":100,"context_line":"            _logger.debug(\"Skipping over invalid version data\")"},{"line_number":101,"context_line":"            continue"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAQn%2F%2FltM%3D","line":99,"updated":"2013-07-27 01:43:50.000000000","message":"untested","commit_id":"7bd23b355bd1d112c9bfa743630b5f0ee3fd241a"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"2747f2d72cb424068218f8376a9260642d3fe3b8","unresolved":false,"context_lines":[{"line_number":113,"context_line":"              the class of the keystone client that can be used with this API,"},{"line_number":114,"context_line":"              and the discovered base url for this API."},{"line_number":115,"context_line":"              eg. [(2.0, keystoneclient.v2_0.Client, \u0027http://host:5000/v2.0\u0027),"},{"line_number":116,"context_line":"                   (3.0, keystoneclient.v3.Client, \u0027http://host:5000/v3\u0027)]"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    :raises: DiscoveryFailure if the response is invalid"},{"line_number":119,"context_line":"    :raises: VersionNotAvailable if a suitable client cannot be found."}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAQn%2F%2FOVE%3D","line":116,"updated":"2013-08-05 08:08:42.000000000","message":"this is wrong, it\u0027s returned as a dictionary now.","commit_id":"ceebc7034ae11647afa7b8dff20b63be696d4f67"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"92345f7f7239379d854d2e562232cfe65f0cc09d","unresolved":false,"context_lines":[{"line_number":236,"context_line":"                continue"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"            # will prevent a requested v3.5 selecting a v3.1 endpoint"},{"line_number":239,"context_line":"            if required_version \u003e keystone_version.version:"},{"line_number":240,"context_line":"                continue"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"            chosen \u003d keystone_version"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAARH%2F%2F3XU%3D","line":239,"updated":"2013-08-16 01:26:38.000000000","message":"After the discussion in IRC, this should be done with tuples, or at least verify that major/minor works as expected..\n\nin this comparison 3.15 will be \u003c 3.2, however (3,15) \u003e (3,2) for example.","commit_id":"b9d22cb643c72b468dea0a60b7713e35383e0440"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"1cc98db1ff3164487ff14338e165cf3f277568fa","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        return self.client_class(**client_kwargs)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def _normalize_version_number(version):"},{"line_number":63,"context_line":"    \"\"\"Turn a version representation into a tuple.\"\"\""},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # trim the v from a \u0027v2.0\u0027 or similar"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAS3%2F%2FDrA%3D","line":62,"updated":"2013-10-05 15:34:12.000000000","message":"This handles a lot of different variations on what we\u0027d consider a version number.  Is it necessary?","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"fb6b8013f194185f542f2060b935e7a744964a0b","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        return self.client_class(**client_kwargs)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def _normalize_version_number(version):"},{"line_number":63,"context_line":"    \"\"\"Turn a version representation into a tuple.\"\"\""},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # trim the v from a \u0027v2.0\u0027 or similar"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATH%2F%2F6%2BU%3D","line":62,"in_reply_to":"AAAAS3%2F%2FDrA%3D","updated":"2013-10-08 01:26:46.000000000","message":"Yes and no. The document that is supposed to be a cross client blueprint suggests using a float. The problem with floats is that eg. 3.14 \u003c 3.2 so you can\u0027t just a basic comparison, but convert to a string first (or other maths). Given that we have the intermediate string step and that the client.version is a string of the form \u0027v3\u0027 we may as well support that use case.\n\nIn python the typical way of doing version comparison is to compare tuples and this will be the documented way.\n\nSo necessary, i\u0027m not sure. but there are already these formats supported and it\u0027s not hard to cover them all.","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"1cc98db1ff3164487ff14338e165cf3f277568fa","unresolved":false,"context_lines":[{"line_number":63,"context_line":"    \"\"\"Turn a version representation into a tuple.\"\"\""},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # trim the v from a \u0027v2.0\u0027 or similar"},{"line_number":66,"context_line":"    try:"},{"line_number":67,"context_line":"        starts_with \u003d version.startswith(\u0027v\u0027)"},{"line_number":68,"context_line":"    except AttributeError:"},{"line_number":69,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAS3%2F%2FEi0%3D","line":66,"updated":"2013-10-05 15:34:12.000000000","message":"I think you can replace the entire try-except-else with:\n  version \u003d version.lstrip(\u0027v\u0027)","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"fb6b8013f194185f542f2060b935e7a744964a0b","unresolved":false,"context_lines":[{"line_number":63,"context_line":"    \"\"\"Turn a version representation into a tuple.\"\"\""},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # trim the v from a \u0027v2.0\u0027 or similar"},{"line_number":66,"context_line":"    try:"},{"line_number":67,"context_line":"        starts_with \u003d version.startswith(\u0027v\u0027)"},{"line_number":68,"context_line":"    except AttributeError:"},{"line_number":69,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATH%2F%2F6%2FE%3D","line":66,"in_reply_to":"AAAAS3%2F%2FEi0%3D","updated":"2013-10-08 01:26:46.000000000","message":"Done","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"56e1d61c704a993155832f535acb3b42062e6de7","unresolved":false,"context_lines":[{"line_number":26,"context_line":"_logger \u003d logging.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"CLIENT_VERSIONS \u003d {2: v2_client.Client,"},{"line_number":30,"context_line":"                   3: v3_client.Client}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FdZ0%3D","line":29,"updated":"2013-10-15 22:11:48.000000000","message":"if this is part of the public API then it needs a docstring. If it\u0027s not then prefix with _.","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0f46679329f056c5f937dbcd14e5e27774052dc1","unresolved":false,"context_lines":[{"line_number":26,"context_line":"_logger \u003d logging.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"CLIENT_VERSIONS \u003d {2: v2_client.Client,"},{"line_number":30,"context_line":"                   3: v3_client.Client}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fc58%3D","line":29,"in_reply_to":"AAAATH%2F%2FdZ0%3D","updated":"2013-10-16 01:38:58.000000000","message":"It\u0027s probably safe to be public, but i\u0027m working on \"if it\u0027s not absolutely required to be public then it should be private\"","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"56e1d61c704a993155832f535acb3b42062e6de7","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    the object."},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __init__(self, version, client_class\u003dNone, **kwargs):"},{"line_number":43,"context_line":"        self.version \u003d version"},{"line_number":44,"context_line":"        self.client_class \u003d client_class"},{"line_number":45,"context_line":"        self.client_kwargs \u003d kwargs"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FdZc%3D","line":42,"updated":"2013-10-15 22:11:48.000000000","message":"document the arguments.","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0f46679329f056c5f937dbcd14e5e27774052dc1","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    the object."},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __init__(self, version, client_class\u003dNone, **kwargs):"},{"line_number":43,"context_line":"        self.version \u003d version"},{"line_number":44,"context_line":"        self.client_class \u003d client_class"},{"line_number":45,"context_line":"        self.client_kwargs \u003d kwargs"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fc5s%3D","line":42,"in_reply_to":"AAAATH%2F%2FdZc%3D","updated":"2013-10-16 01:38:58.000000000","message":"Done","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"527ec6d6a6c28b479886ce41d4fd99a0d24a8c80","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # trim the v from a \u0027v2.0\u0027 or similar"},{"line_number":66,"context_line":"    try:"},{"line_number":67,"context_line":"        version \u003d version.lstrip(\u0027v\u0027)"},{"line_number":68,"context_line":"    except AttributeError:"},{"line_number":69,"context_line":"        pass"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FikI%3D","line":67,"updated":"2013-10-14 20:35:04.000000000","message":"lstrip?  what if it is http://hostname:35357/v2.0/  ?  won\u0027t you end up with the trailing / appended?","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"6e4527001c944a289bd55c317036717b2fbb79ba","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    # trim the v from a \u0027v2.0\u0027 or similar"},{"line_number":66,"context_line":"    try:"},{"line_number":67,"context_line":"        version \u003d version.lstrip(\u0027v\u0027)"},{"line_number":68,"context_line":"    except AttributeError:"},{"line_number":69,"context_line":"        pass"},{"line_number":70,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FeJw%3D","line":67,"in_reply_to":"AAAATH%2F%2FikI%3D","updated":"2013-10-15 19:10:30.000000000","message":"This is the version passed in as a parameter to the client call. We never parse URLs for version numbers.\n\n(so it\u0027s fine)","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"56e1d61c704a993155832f535acb3b42062e6de7","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    \"\"\"Construct a dict of available endpoints from a server response.\"\"\""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":101,"context_line":"        _logger.warning(\"Invalid Response code from %s\" % resp.url)"},{"line_number":102,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"},{"line_number":103,"context_line":"                                          resp.url)"},{"line_number":104,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FdY0%3D","line":101,"updated":"2013-10-15 22:11:48.000000000","message":"we\u0027re probably going to want to know what the status code is and even the response text.","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0f46679329f056c5f937dbcd14e5e27774052dc1","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    \"\"\"Construct a dict of available endpoints from a server response.\"\"\""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":101,"context_line":"        _logger.warning(\"Invalid Response code from %s\" % resp.url)"},{"line_number":102,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"},{"line_number":103,"context_line":"                                          resp.url)"},{"line_number":104,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fc3A%3D","line":101,"in_reply_to":"AAAATH%2F%2FdY0%3D","updated":"2013-10-16 01:38:58.000000000","message":"I added the status code to the response warning message. if you want more than this then if you pass debug\u003dTrue to the client.Client then you get request and response logging (same as calling a v2 or v3 client).\n\nIs that sufficient?","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"56e1d61c704a993155832f535acb3b42062e6de7","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        raise exceptions.DiscoveryFailure(\u0027Invalid json response: %s\u0027,"},{"line_number":109,"context_line":"                                          resp.text)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    try:"},{"line_number":112,"context_line":"        response_values \u003d response[\u0027versions\u0027][\u0027values\u0027]"},{"line_number":113,"context_line":"    except KeyError:"},{"line_number":114,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FdYU%3D","line":111,"updated":"2013-10-15 22:11:48.000000000","message":"document why different response formats","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0f46679329f056c5f937dbcd14e5e27774052dc1","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        raise exceptions.DiscoveryFailure(\u0027Invalid json response: %s\u0027,"},{"line_number":109,"context_line":"                                          resp.text)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    try:"},{"line_number":112,"context_line":"        response_values \u003d response[\u0027versions\u0027][\u0027values\u0027]"},{"line_number":113,"context_line":"    except KeyError:"},{"line_number":114,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fc5o%3D","line":111,"in_reply_to":"AAAATH%2F%2FdYU%3D","updated":"2013-10-16 01:38:58.000000000","message":"Done","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"56e1d61c704a993155832f535acb3b42062e6de7","unresolved":false,"context_lines":[{"line_number":148,"context_line":"    \"\"\"Return a list of available API versions and client params."},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    :param string auth_url: the url which contains the version listing. Name"},{"line_number":151,"context_line":"                            is kept compatible with existing clients."},{"line_number":152,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":153,"context_line":"    :returns: A dictionary of available API endpoints with the version number"},{"line_number":154,"context_line":"              as a tuple as the key, and a factory object that can be used"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FdWo%3D","line":151,"updated":"2013-10-15 22:11:48.000000000","message":"document endpoint also if going to document parameters.","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0f46679329f056c5f937dbcd14e5e27774052dc1","unresolved":false,"context_lines":[{"line_number":148,"context_line":"    \"\"\"Return a list of available API versions and client params."},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    :param string auth_url: the url which contains the version listing. Name"},{"line_number":151,"context_line":"                            is kept compatible with existing clients."},{"line_number":152,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":153,"context_line":"    :returns: A dictionary of available API endpoints with the version number"},{"line_number":154,"context_line":"              as a tuple as the key, and a factory object that can be used"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fc5k%3D","line":151,"in_reply_to":"AAAATH%2F%2FdWo%3D","updated":"2013-10-16 01:38:58.000000000","message":"Done","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"56e1d61c704a993155832f535acb3b42062e6de7","unresolved":false,"context_lines":[{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    :param string auth_url: the url which contains the version listing. Name"},{"line_number":151,"context_line":"                            is kept compatible with existing clients."},{"line_number":152,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":153,"context_line":"    :returns: A dictionary of available API endpoints with the version number"},{"line_number":154,"context_line":"              as a tuple as the key, and a factory object that can be used"},{"line_number":155,"context_line":"              to create an appropriate client as the value."}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FdXk%3D","line":152,"updated":"2013-10-15 22:11:48.000000000","message":"suggest remove (optional) since it\u0027s obvious.","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0f46679329f056c5f937dbcd14e5e27774052dc1","unresolved":false,"context_lines":[{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    :param string auth_url: the url which contains the version listing. Name"},{"line_number":151,"context_line":"                            is kept compatible with existing clients."},{"line_number":152,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":153,"context_line":"    :returns: A dictionary of available API endpoints with the version number"},{"line_number":154,"context_line":"              as a tuple as the key, and a factory object that can be used"},{"line_number":155,"context_line":"              to create an appropriate client as the value."}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fc5E%3D","line":152,"in_reply_to":"AAAATH%2F%2FdXk%3D","updated":"2013-10-16 01:38:58.000000000","message":"Yes it\u0027s obvious but it\u0027s a convention that we seem to follow","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"56e1d61c704a993155832f535acb3b42062e6de7","unresolved":false,"context_lines":[{"line_number":154,"context_line":"              as a tuple as the key, and a factory object that can be used"},{"line_number":155,"context_line":"              to create an appropriate client as the value."},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    To use the returned factory you simply call it with the parameters to pass"},{"line_number":158,"context_line":"    to keystoneclient. These parameters will override those saved in the"},{"line_number":159,"context_line":"    factory."},{"line_number":160,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FdXE%3D","line":157,"updated":"2013-10-15 22:11:48.000000000","message":"since this is an internal function, not sure that all this documentation belongs here.","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0f46679329f056c5f937dbcd14e5e27774052dc1","unresolved":false,"context_lines":[{"line_number":154,"context_line":"              as a tuple as the key, and a factory object that can be used"},{"line_number":155,"context_line":"              to create an appropriate client as the value."},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    To use the returned factory you simply call it with the parameters to pass"},{"line_number":158,"context_line":"    to keystoneclient. These parameters will override those saved in the"},{"line_number":159,"context_line":"    factory."},{"line_number":160,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fc48%3D","line":157,"in_reply_to":"AAAATH%2F%2FdXE%3D","updated":"2013-10-16 01:38:58.000000000","message":"The intention was that it would be public, i just don\u0027t want to standardize the interface until the session stuff is ready so i\u0027m keeping it private. The doc will be required later.","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":1916,"name":"Guang Yee","email":"gyee@suse.com","username":"guang-yee"},"change_message_id":"6315fbbe45c31d914a72519f027016cd6a1864bb","unresolved":false,"context_lines":[{"line_number":206,"context_line":"    try:"},{"line_number":207,"context_line":"        response \u003d httpclient.request(url, verify\u003dverify, headers\u003dheaders,"},{"line_number":208,"context_line":"                                      cert\u003dclient_cert, debug\u003ddebug,"},{"line_number":209,"context_line":"                                      original_ip\u003doriginal_ip)"},{"line_number":210,"context_line":"    except exceptions.HTTPNotImplemented:"},{"line_number":211,"context_line":"        # NOTE(jamielennox): This is dangerous however it is an assumption"},{"line_number":212,"context_line":"        # that is found in the original auth_token middleware that a 501 error"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2FdVI%3D","line":209,"updated":"2013-10-15 22:24:04.000000000","message":"what happen to python-requests?\n\nPlease refactor the HTTP/REST client code into a separae object so it can be shared by both v2, v3, and middleware?","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"0f46679329f056c5f937dbcd14e5e27774052dc1","unresolved":false,"context_lines":[{"line_number":206,"context_line":"    try:"},{"line_number":207,"context_line":"        response \u003d httpclient.request(url, verify\u003dverify, headers\u003dheaders,"},{"line_number":208,"context_line":"                                      cert\u003dclient_cert, debug\u003ddebug,"},{"line_number":209,"context_line":"                                      original_ip\u003doriginal_ip)"},{"line_number":210,"context_line":"    except exceptions.HTTPNotImplemented:"},{"line_number":211,"context_line":"        # NOTE(jamielennox): This is dangerous however it is an assumption"},{"line_number":212,"context_line":"        # that is found in the original auth_token middleware that a 501 error"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fc4s%3D","line":209,"in_reply_to":"AAAATH%2F%2FdVI%3D","updated":"2013-10-16 01:38:58.000000000","message":"talked to gyee on IRC. httpclient is our module, and this function is a wrapper around python-requests.","commit_id":"377a7110d44a0052f477256e1ad393d776078244"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":27,"context_line":"_logger \u003d logging.getLogger(__name__)"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"_CLIENT_VERSIONS \u003d {2: v2_client.Client,"},{"line_number":31,"context_line":"                    3: v3_client.Client}"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLks%3D","line":30,"updated":"2013-10-21 22:12:20.000000000","message":"Since this is only used in _KeystoneVersion could move it in there.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":27,"context_line":"_logger \u003d logging.getLogger(__name__)"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"_CLIENT_VERSIONS \u003d {2: v2_client.Client,"},{"line_number":31,"context_line":"                    3: v3_client.Client}"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLQ0%3D","line":30,"in_reply_to":"AAAATH%2F%2FLks%3D","updated":"2013-10-21 23:10:10.000000000","message":"Done","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    \"\"\""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def __init__(self, version, client_class\u003dNone, **kwargs):"},{"line_number":44,"context_line":"        \"\"\"Create a new KeystoneVersion object."},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"        :param tuple version: the version of the available API."},{"line_number":47,"context_line":"        :param Class client_class: the client class that should be used to"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLlU%3D","line":44,"updated":"2013-10-21 22:12:20.000000000","message":"Since added _ to class name, change to _KeystoneVersion. Or remove the name since it\u0027s redundant.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    \"\"\""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def __init__(self, version, client_class\u003dNone, **kwargs):"},{"line_number":44,"context_line":"        \"\"\"Create a new KeystoneVersion object."},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"        :param tuple version: the version of the available API."},{"line_number":47,"context_line":"        :param Class client_class: the client class that should be used to"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLQw%3D","line":44,"in_reply_to":"AAAATH%2F%2FLlU%3D","updated":"2013-10-21 23:10:10.000000000","message":"Done","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        return cmp(self.version, other.version)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    def __call__(self, **kwargs):"},{"line_number":64,"context_line":"        if kwargs:"},{"line_number":65,"context_line":"            client_kwargs \u003d self.client_kwargs.copy()"},{"line_number":66,"context_line":"            client_kwargs.update(kwargs)"},{"line_number":67,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLjk%3D","line":64,"updated":"2013-10-21 22:12:20.000000000","message":"I don\u0027t think it\u0027s possible for kwargs to be None, so this could be simplified by removing the if / else.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        return cmp(self.version, other.version)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    def __call__(self, **kwargs):"},{"line_number":64,"context_line":"        if kwargs:"},{"line_number":65,"context_line":"            client_kwargs \u003d self.client_kwargs.copy()"},{"line_number":66,"context_line":"            client_kwargs.update(kwargs)"},{"line_number":67,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLSo%3D","line":64,"in_reply_to":"AAAATH%2F%2FLjk%3D","updated":"2013-10-21 23:10:10.000000000","message":"no, but it\u0027s possible that kwargs \u003d\u003d {} which is false here\n\nit just means that if nothing is passed in you don\u0027t need to do a copy and update","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    except Exception:"},{"line_number":94,"context_line":"        pass"},{"line_number":95,"context_line":"    else:"},{"line_number":96,"context_line":"        return tuple(split)"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    # last attempt, maybe it\u0027s a list or iterable."},{"line_number":99,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLjM%3D","line":96,"updated":"2013-10-21 22:12:20.000000000","message":"could put the return at line 92 to avoid else:.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    except Exception:"},{"line_number":94,"context_line":"        pass"},{"line_number":95,"context_line":"    else:"},{"line_number":96,"context_line":"        return tuple(split)"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    # last attempt, maybe it\u0027s a list or iterable."},{"line_number":99,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLP4%3D","line":96,"in_reply_to":"AAAATH%2F%2FLjM%3D","updated":"2013-10-21 23:10:10.000000000","message":"Done","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    except Exception:"},{"line_number":102,"context_line":"        pass"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    raise TypeError(\"Invalid version specified: %s\" % version)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"def _get_versions_from_response(resp, unstable\u003dFalse):"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLiw%3D","line":104,"updated":"2013-10-21 22:12:20.000000000","message":"this all seems excessively complicated. Why not just take a string and return a tuple?","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    except Exception:"},{"line_number":102,"context_line":"        pass"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    raise TypeError(\"Invalid version specified: %s\" % version)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"def _get_versions_from_response(resp, unstable\u003dFalse):"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLSE%3D","line":104,"in_reply_to":"AAAATH%2F%2FLiw%3D","updated":"2013-10-21 23:10:10.000000000","message":"So i think the tuple is best. The blueprint for discovery that was more global suggests using a float. Given that version is specified in the client currently as a string and I have to convert from float to string to make floats work anyway it\u0027s not hard to support this use case.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":108,"context_line":"    \"\"\"Construct a dict of available endpoints from a server response.\"\"\""},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":111,"context_line":"        _logger.warning(\"Invalid Response code from %s: %d\" %"},{"line_number":112,"context_line":"                        (resp.url, resp.status_code))"},{"line_number":113,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"},{"line_number":114,"context_line":"                                          resp.url)"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLig%3D","line":111,"updated":"2013-10-21 22:12:20.000000000","message":"seems like should be logged at an error level?\n\nAlso, change \"Response\" to \"response\" (lowercase)\n\nAlso, should use named format variables since this might be translated in future, e.g. \"from %(url)s %(code)\"\n\nAlso previous response asked if it was sufficient to log important information... I don\u0027t think it is since the application getting this error might be able to report better information if it had it, and applications can\u0027t go looking at log entries, they get the exception.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":108,"context_line":"    \"\"\"Construct a dict of available endpoints from a server response.\"\"\""},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":111,"context_line":"        _logger.warning(\"Invalid Response code from %s: %d\" %"},{"line_number":112,"context_line":"                        (resp.url, resp.status_code))"},{"line_number":113,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"},{"line_number":114,"context_line":"                                          resp.url)"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLPs%3D","line":111,"in_reply_to":"AAAATH%2F%2FLig%3D","updated":"2013-10-21 23:10:10.000000000","message":"I\u0027m not sure what else here. If you get a 4xx or 5xx here then the regular http exceptions are thrown, if you get a 2xx or \u003e 300 here then most likely you have pointed the API at a bad url and the exception is about as descriptive for that situation as i think it needs to be.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":142,"context_line":"            version_str \u003d version_data[\u0027id\u0027]"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"            if not version_str.startswith(\u0027v\u0027):"},{"line_number":145,"context_line":"                _logger.debug(\u0027Skipping over invalid version string: %s \u0027"},{"line_number":146,"context_line":"                              \u0027It should start with a v\u0027, version_str)"},{"line_number":147,"context_line":"                continue"},{"line_number":148,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLhM%3D","line":145,"updated":"2013-10-21 22:12:20.000000000","message":"There\u0027s a . missing here.\n\nAlso, should this be a warning since it indicates a misconfiguration?","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":142,"context_line":"            version_str \u003d version_data[\u0027id\u0027]"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"            if not version_str.startswith(\u0027v\u0027):"},{"line_number":145,"context_line":"                _logger.debug(\u0027Skipping over invalid version string: %s \u0027"},{"line_number":146,"context_line":"                              \u0027It should start with a v\u0027, version_str)"},{"line_number":147,"context_line":"                continue"},{"line_number":148,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLPY%3D","line":145,"in_reply_to":"AAAATH%2F%2FLhM%3D","updated":"2013-10-21 23:10:10.000000000","message":"Done","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":153,"context_line":"                    break"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        except (KeyError, TypeError, ValueError):"},{"line_number":156,"context_line":"            _logger.debug(\"Skipping over invalid version data\")"},{"line_number":157,"context_line":"            continue"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    return versions"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLhE%3D","line":156,"updated":"2013-10-21 22:12:20.000000000","message":"seems like a warning.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":153,"context_line":"                    break"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"        except (KeyError, TypeError, ValueError):"},{"line_number":156,"context_line":"            _logger.debug(\"Skipping over invalid version data\")"},{"line_number":157,"context_line":"            continue"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    return versions"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLPU%3D","line":156,"in_reply_to":"AAAATH%2F%2FLhE%3D","updated":"2013-10-21 23:10:10.000000000","message":"Done","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":159,"context_line":"    return versions"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"def _available_versions(auth_url\u003dNone, endpoint\u003dNone, unstable\u003dFalse,"},{"line_number":163,"context_line":"                        **kwargs):"},{"line_number":164,"context_line":"    \"\"\"Return a list of available API versions and client params."},{"line_number":165,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLZI%3D","line":162,"updated":"2013-10-21 22:12:20.000000000","message":"I think keystoneclient should provide a public API to get the list of available versions from the server, as I think clients would find this useful if they for some reason don\u0027t want to use our automatic method. Could you split this out and submit it as a separate patch? (This patch should use that one to get the available versions.) If you do, I think the function should return the list of versions and not a tuple including client params.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":159,"context_line":"    return versions"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"def _available_versions(auth_url\u003dNone, endpoint\u003dNone, unstable\u003dFalse,"},{"line_number":163,"context_line":"                        **kwargs):"},{"line_number":164,"context_line":"    \"\"\"Return a list of available API versions and client params."},{"line_number":165,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLR0%3D","line":162,"in_reply_to":"AAAATH%2F%2FLZI%3D","updated":"2013-10-21 23:10:10.000000000","message":"So this was originally a public API in the initial patches and i agree that this would be a useful thing to have public. This is why there is so much documentation for it. I\u0027m pretty sure for example that this will be the function we have to use in auth_token middleware at least for a while. \n\nThe problem is that as soon as i can push through the sessions code the parameters of this function will have to change. Given that no one is asking for it now i\u0027d prefer to leave it private until that change happens rather than have to deprecate another set of parameters.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":260,"context_line":""},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"def Client(version\u003dNone, **kwargs):"},{"line_number":263,"context_line":"    \"\"\"Factory method to create a new keystone client."},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    :param tuple version: A specific version of the client to return."},{"line_number":266,"context_line":"                          If specified the client will be selected such that"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLgs%3D","line":263,"updated":"2013-10-21 22:12:20.000000000","message":"suggest use \"Identity service client\" rather than \"keystone client\"\n\nchange \"method\" to \"function\"","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":260,"context_line":""},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"def Client(version\u003dNone, **kwargs):"},{"line_number":263,"context_line":"    \"\"\"Factory method to create a new keystone client."},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    :param tuple version: A specific version of the client to return."},{"line_number":266,"context_line":"                          If specified the client will be selected such that"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLOs%3D","line":263,"in_reply_to":"AAAATH%2F%2FLgs%3D","updated":"2013-10-21 23:10:10.000000000","message":"Done","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":262,"context_line":"def Client(version\u003dNone, **kwargs):"},{"line_number":263,"context_line":"    \"\"\"Factory method to create a new keystone client."},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    :param tuple version: A specific version of the client to return."},{"line_number":266,"context_line":"                          If specified the client will be selected such that"},{"line_number":267,"context_line":"                          the major is equivalent and an endpoint provides at"},{"line_number":268,"context_line":"                          least the specified minor version. For example to"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLgM%3D","line":265,"updated":"2013-10-21 22:12:20.000000000","message":"This says it\u0027s a \"tuple\" but since it goes through _normalize_version_number it allows strings, etc. So either don\u0027t use _normalize_version_number or change the type here.\n\nAlso, Suggest change \"A specific version\" to \"The version\" ... the following sentences indicate that it\u0027s not a specific version, since you can provide a partial version.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":262,"context_line":"def Client(version\u003dNone, **kwargs):"},{"line_number":263,"context_line":"    \"\"\"Factory method to create a new keystone client."},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    :param tuple version: A specific version of the client to return."},{"line_number":266,"context_line":"                          If specified the client will be selected such that"},{"line_number":267,"context_line":"                          the major is equivalent and an endpoint provides at"},{"line_number":268,"context_line":"                          least the specified minor version. For example to"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLRQ%3D","line":265,"in_reply_to":"AAAATH%2F%2FLgM%3D","updated":"2013-10-21 23:10:10.000000000","message":"This was intentional. Whilst the _normalize_version_number will allow multiple input formats that ability is somewhat a preventative measure in case other clients are doing things differently. I want to support the case where another scheme is used but i do not want it documented as the expected input to the function. \n\nThe function expects a tuple, if you pass it something else it will do its best to comply but it is not the recommended usage.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    :param tuple version: A specific version of the client to return."},{"line_number":266,"context_line":"                          If specified the client will be selected such that"},{"line_number":267,"context_line":"                          the major is equivalent and an endpoint provides at"},{"line_number":268,"context_line":"                          least the specified minor version. For example to"},{"line_number":269,"context_line":"                          specify the 3.1 API use (3, 1)."},{"line_number":270,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLgk%3D","line":267,"updated":"2013-10-21 22:12:20.000000000","message":"change \"major\" to \"major version\"","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    :param tuple version: A specific version of the client to return."},{"line_number":266,"context_line":"                          If specified the client will be selected such that"},{"line_number":267,"context_line":"                          the major is equivalent and an endpoint provides at"},{"line_number":268,"context_line":"                          least the specified minor version. For example to"},{"line_number":269,"context_line":"                          specify the 3.1 API use (3, 1)."},{"line_number":270,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLPM%3D","line":267,"in_reply_to":"AAAATH%2F%2FLgk%3D","updated":"2013-10-21 23:10:10.000000000","message":"Done","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a9aae164edd740bad6ea97e962fa92646a9c4fb0","unresolved":false,"context_lines":[{"line_number":266,"context_line":"                          If specified the client will be selected such that"},{"line_number":267,"context_line":"                          the major is equivalent and an endpoint provides at"},{"line_number":268,"context_line":"                          least the specified minor version. For example to"},{"line_number":269,"context_line":"                          specify the 3.1 API use (3, 1)."},{"line_number":270,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":271,"context_line":"    :returns: An instantiated keystone client object."},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLe4%3D","line":269,"updated":"2013-10-21 22:12:20.000000000","message":"Is this the version of the client API or the identity API?","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"1ea7e0a5952bac9a16d947d64a57c1be3ef2218a","unresolved":false,"context_lines":[{"line_number":266,"context_line":"                          If specified the client will be selected such that"},{"line_number":267,"context_line":"                          the major is equivalent and an endpoint provides at"},{"line_number":268,"context_line":"                          least the specified minor version. For example to"},{"line_number":269,"context_line":"                          specify the 3.1 API use (3, 1)."},{"line_number":270,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":271,"context_line":"    :returns: An instantiated keystone client object."},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAATH%2F%2FLPI%3D","line":269,"in_reply_to":"AAAATH%2F%2FLe4%3D","updated":"2013-10-21 23:10:10.000000000","message":"Fixed. Version is always related to the required identity API version. If you\u0027re running the code then it\u0027s already too late to do anything about the client version.","commit_id":"f63806972984cfefd801c8a51e241e4cbacaec94"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d08a318fc11913e9902be16f18716139b741b5af","unresolved":false,"context_lines":[{"line_number":103,"context_line":"    raise TypeError(\"Invalid version specified: %s\" % version)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"def available_versions(url, **kwargs):"},{"line_number":107,"context_line":"    \"\"\"Return a list of identity APIs available on the server and the data"},{"line_number":108,"context_line":"    associated with them."},{"line_number":109,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATX%2F%2F8Mo%3D","line":106,"updated":"2013-10-23 22:31:21.000000000","message":"I\u0027d prefer this as a separate commit.\n\nActually, it looks like we\u0027ve got this already in keystoneclient/generic/client.py ?","commit_id":"1d6b06c9520d022dc92012e3366aedaa110ae46f"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c347c186dcab9a71169e4b441d958a6dddc5458c","unresolved":false,"context_lines":[{"line_number":103,"context_line":"    raise TypeError(\"Invalid version specified: %s\" % version)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"def available_versions(url, **kwargs):"},{"line_number":107,"context_line":"    \"\"\"Return a list of identity APIs available on the server and the data"},{"line_number":108,"context_line":"    associated with them."},{"line_number":109,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATX%2F%2F77o%3D","line":106,"in_reply_to":"AAAATX%2F%2F8Mo%3D","updated":"2013-10-24 00:05:56.000000000","message":"There is something similar in keystone/generic/client.py I found a while ago some points:\n\nI\u0027ve never seen any documentation (other than the doc string) about how or where you would use it. It\u0027s not mentioned in any tutorial or how to use keystone. \n\nIt inherits HTTPClient (which made me think it was supposed to be a client) and then proceeds to construct HTTPClient objects whenever it needs to make network calls. This means that any information you provide to the client (original_ip, certificates, validation) is simply ignored.\n\nIt does the same was as previous reviews returning a dictionary keyed with version number to url, status, and\n\nThe last (non-trivial code) was from Feb 2012, and then a fix for bug 1136476 which seems to mean that it was broken since pretty much the beginning.\n\nGeneric Client also supports extension discovery. At this point this is a 2.0 API only feature, so it\u0027s not that generic.\n\nThis is not the function i really want public anyway. It\u0027s client.Client() and possibly available_clients that are the intent of this review. Until requested this whole method was private.\n\nAnd really i\u0027d just never known the point of a generic client until after i\u0027d written at least the first version of this and i would suggest that most people are in the same boat.","commit_id":"1d6b06c9520d022dc92012e3366aedaa110ae46f"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d08a318fc11913e9902be16f18716139b741b5af","unresolved":false,"context_lines":[{"line_number":162,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":163,"context_line":"        _logger.error(\"Invalid response code from %(url)s: %(code)d\" %"},{"line_number":164,"context_line":"                      {\u0027url\u0027: resp.url, \u0027code\u0027: resp.status_code})"},{"line_number":165,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"},{"line_number":166,"context_line":"                                          resp.url)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATX%2F%2F8Ms%3D","line":165,"updated":"2013-10-23 22:31:21.000000000","message":"This shouldn\u0027t be DiscoveryFailure. The error should be like the other keystoneclient APIs. (This comment applies other places that DiscoveryFailure is used.)","commit_id":"1d6b06c9520d022dc92012e3366aedaa110ae46f"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c347c186dcab9a71169e4b441d958a6dddc5458c","unresolved":false,"context_lines":[{"line_number":162,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":163,"context_line":"        _logger.error(\"Invalid response code from %(url)s: %(code)d\" %"},{"line_number":164,"context_line":"                      {\u0027url\u0027: resp.url, \u0027code\u0027: resp.status_code})"},{"line_number":165,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"},{"line_number":166,"context_line":"                                          resp.url)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATX%2F%2F77U%3D","line":165,"in_reply_to":"AAAATX%2F%2F8Ms%3D","updated":"2013-10-24 00:05:56.000000000","message":"What do you suggest? If the error is 4xx or 5xx then the typical errors will be raised by the httpclient.request function. The other options here are a 2xx or \u003e302 because requests.request will treat 301 or 302 as a redirect.","commit_id":"1d6b06c9520d022dc92012e3366aedaa110ae46f"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d08a318fc11913e9902be16f18716139b741b5af","unresolved":false,"context_lines":[{"line_number":175,"context_line":"        # In the event of querying a root URL we will get back a list of"},{"line_number":176,"context_line":"        # available versions."},{"line_number":177,"context_line":"        return response[\u0027versions\u0027][\u0027values\u0027]"},{"line_number":178,"context_line":"    except KeyError:"},{"line_number":179,"context_line":"        # Otherwise if we query an endpoint like /v2.0 then we will get back"},{"line_number":180,"context_line":"        # just the one available version."},{"line_number":181,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATX%2F%2F8Mk%3D","line":178,"updated":"2013-10-23 22:31:21.000000000","message":"suggest pass here, then it\u0027ll be more like how we passthrough at line 184.","commit_id":"1d6b06c9520d022dc92012e3366aedaa110ae46f"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c347c186dcab9a71169e4b441d958a6dddc5458c","unresolved":false,"context_lines":[{"line_number":175,"context_line":"        # In the event of querying a root URL we will get back a list of"},{"line_number":176,"context_line":"        # available versions."},{"line_number":177,"context_line":"        return response[\u0027versions\u0027][\u0027values\u0027]"},{"line_number":178,"context_line":"    except KeyError:"},{"line_number":179,"context_line":"        # Otherwise if we query an endpoint like /v2.0 then we will get back"},{"line_number":180,"context_line":"        # just the one available version."},{"line_number":181,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATX%2F%2F768%3D","line":178,"in_reply_to":"AAAATX%2F%2F8Mk%3D","updated":"2013-10-24 00:05:56.000000000","message":"Done","commit_id":"1d6b06c9520d022dc92012e3366aedaa110ae46f"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a0d9b68660bc324b1fc481768e72813176a224fa","unresolved":false,"context_lines":[{"line_number":103,"context_line":"    raise TypeError(\"Invalid version specified: %s\" % version)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"def available_versions(url, **kwargs):"},{"line_number":107,"context_line":"    \"\"\"Return a list of identity APIs available on the server and the data"},{"line_number":108,"context_line":"    associated with them."},{"line_number":109,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAATn%2F%2F70o%3D","line":106,"updated":"2013-10-24 23:54:50.000000000","message":"do you think keystoneclient/generic should be deprecated in favor of this API?","commit_id":"8f7f752486fb2a99762ecc6b3fa6e52661e8bb8c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a0d9b68660bc324b1fc481768e72813176a224fa","unresolved":false,"context_lines":[{"line_number":132,"context_line":"                             when establishing SSL connection with identity"},{"line_number":133,"context_line":"                             service. default: False (optional)"},{"line_number":134,"context_line":""},{"line_number":135,"context_line":"    :returns: A List of dictionaries as presented by the server. The dict"},{"line_number":136,"context_line":"              will contain the version and the URL to use for the version"},{"line_number":137,"context_line":"    \"\"\""},{"line_number":138,"context_line":"    headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027}"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAATn%2F%2F72A%3D","line":135,"updated":"2013-10-24 23:54:50.000000000","message":"I think in order to use this the developer is going to need to know the format of the returned data. For example, my first attempt used\n\n client.available_versions(\u0027http://localhost:5000\u0027)[0][\u0027version\u0027]\n\nbut that didn\u0027t work because the version is in \u0027id\u0027.","commit_id":"8f7f752486fb2a99762ecc6b3fa6e52661e8bb8c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a0d9b68660bc324b1fc481768e72813176a224fa","unresolved":false,"context_lines":[{"line_number":159,"context_line":"                              cert\u003dclient_cert, debug\u003ddebug,"},{"line_number":160,"context_line":"                              original_ip\u003doriginal_ip)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":163,"context_line":"        _logger.error(\"Invalid response code from %(url)s: %(code)d\" %"},{"line_number":164,"context_line":"                      {\u0027url\u0027: resp.url, \u0027code\u0027: resp.status_code})"},{"line_number":165,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAATn%2F%2F71E%3D","line":162,"updated":"2013-10-24 23:54:50.000000000","message":"My keystone server returns 200 for http://localhost:5000/v3 and v2.0 rather than 300.","commit_id":"8f7f752486fb2a99762ecc6b3fa6e52661e8bb8c"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c32f4c1b60f938d4561b8afd7769495a15467b19","unresolved":false,"context_lines":[{"line_number":159,"context_line":"                              cert\u003dclient_cert, debug\u003ddebug,"},{"line_number":160,"context_line":"                              original_ip\u003doriginal_ip)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":163,"context_line":"        _logger.error(\"Invalid response code from %(url)s: %(code)d\" %"},{"line_number":164,"context_line":"                      {\u0027url\u0027: resp.url, \u0027code\u0027: resp.status_code})"},{"line_number":165,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAATn%2F%2F7nU%3D","line":162,"in_reply_to":"AAAATn%2F%2F71E%3D","updated":"2013-10-25 01:39:42.000000000","message":"ouch, good catch, i\u0027m not sure how i missed that one.","commit_id":"8f7f752486fb2a99762ecc6b3fa6e52661e8bb8c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a0d9b68660bc324b1fc481768e72813176a224fa","unresolved":false,"context_lines":[{"line_number":162,"context_line":"    if resp.status_code !\u003d 300:"},{"line_number":163,"context_line":"        _logger.error(\"Invalid response code from %(url)s: %(code)d\" %"},{"line_number":164,"context_line":"                      {\u0027url\u0027: resp.url, \u0027code\u0027: resp.status_code})"},{"line_number":165,"context_line":"        raise exceptions.DiscoveryFailure(\"Invalid response from: %s\" %"},{"line_number":166,"context_line":"                                          resp.url)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAATn%2F%2F71A%3D","line":165,"updated":"2013-10-24 23:54:50.000000000","message":"The docstring for DiscoveryFailure is \"Discovery of client versions failed.\", but the problem is that fetching the server versions failed, so DiscoveryFailure isn\u0027t appropriate.\n\nI\u0027d suggest a new exception... FetchVersions.","commit_id":"8f7f752486fb2a99762ecc6b3fa6e52661e8bb8c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":27,"context_line":"                          major version is equivalent and an endpoint provides"},{"line_number":28,"context_line":"                          at least the specified minor version. For example to"},{"line_number":29,"context_line":"                          specify the 3.1 API use (3, 1)."},{"line_number":30,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":31,"context_line":"    :returns: An instantiated keystone client object."},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    :raises: DiscoveryFailure if the response is invalid"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpHw%3D","line":30,"updated":"2013-10-31 01:14:31.000000000","message":"document what the kwargs are for... i.e., kwargs are passed on to client constructor.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":27,"context_line":"                          major version is equivalent and an endpoint provides"},{"line_number":28,"context_line":"                          at least the specified minor version. For example to"},{"line_number":29,"context_line":"                          specify the 3.1 API use (3, 1)."},{"line_number":30,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":31,"context_line":"    :returns: An instantiated keystone client object."},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    :raises: DiscoveryFailure if the response is invalid"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FoxE%3D","line":30,"in_reply_to":"AAAATn%2F%2FpHw%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":31,"context_line":"    :returns: An instantiated keystone client object."},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    :raises: DiscoveryFailure if the response is invalid"},{"line_number":34,"context_line":"    :raises: VersionNotAvailable if a suitable client cannot be found."},{"line_number":35,"context_line":"    \"\"\""},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpIA%3D","line":33,"updated":"2013-10-31 01:14:31.000000000","message":"suggest change \"response\" to \"server\u0027s response\"","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":31,"context_line":"    :returns: An instantiated keystone client object."},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    :raises: DiscoveryFailure if the response is invalid"},{"line_number":34,"context_line":"    :raises: VersionNotAvailable if a suitable client cannot be found."},{"line_number":35,"context_line":"    \"\"\""},{"line_number":36,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FoxA%3D","line":33,"in_reply_to":"AAAATn%2F%2FpIA%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    :raises: VersionNotAvailable if a suitable client cannot be found."},{"line_number":35,"context_line":"    \"\"\""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    return discover.Discover(**kwargs).create_client(version\u003dversion,"},{"line_number":38,"context_line":"                                                     unstable\u003dunstable)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpH4%3D","line":37,"updated":"2013-10-31 01:14:31.000000000","message":"This seems reversed... wouldn\u0027t the arguments to Discover be the version and unstable, and the arguments to create_client be the kwargs?","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    :raises: VersionNotAvailable if a suitable client cannot be found."},{"line_number":35,"context_line":"    \"\"\""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    return discover.Discover(**kwargs).create_client(version\u003dversion,"},{"line_number":38,"context_line":"                                                     unstable\u003dunstable)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Fo6w%3D","line":37,"in_reply_to":"AAAATn%2F%2FpH4%3D","updated":"2013-10-31 03:57:41.000000000","message":"Ideally, but we need the parameters that would generally be required for communication (debug, certs etc) to be used by the discovery process.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":31,"context_line":"    :param kwargs: Additional arguments are passed through to the client"},{"line_number":32,"context_line":"                   that is being created."},{"line_number":33,"context_line":"    :returns: An instantiated keystone client object."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    :raises: DiscoveryFailure if the server\u0027s response is invalid"},{"line_number":36,"context_line":"    :raises: VersionNotAvailable if a suitable client cannot be found."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpv8%3D","line":33,"updated":"2013-11-22 00:53:29.000000000","message":"could you provide a reference to what this is? users are going to need to know.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":30,"context_line":"    :param bool unstable: Accept endpoints not marked as \u0027stable\u0027. (optional)"},{"line_number":31,"context_line":"    :param kwargs: Additional arguments are passed through to the client"},{"line_number":32,"context_line":"                   that is being created."},{"line_number":33,"context_line":"    :returns: An instantiated keystone client object."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    :raises: DiscoveryFailure if the server\u0027s response is invalid"},{"line_number":36,"context_line":"    :raises: VersionNotAvailable if a suitable client cannot be found."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiSw%3D","line":33,"in_reply_to":"AAAATn%2F%2Bpv8%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"b99d207433d7482c29841b69d28671d410312a53","unresolved":false,"context_lines":[{"line_number":19,"context_line":"HTTPClient \u003d httpclient.HTTPClient"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"def Client(version\u003dNone, unstable\u003dFalse, **kwargs):"},{"line_number":23,"context_line":"    \"\"\"Factory function to create a new identity service client."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    :param tuple version: The required version of the identity API. If"}],"source_content_type":"text/x-python","patch_set":26,"id":"AAAATn%2F%2BJL8%3D","line":22,"updated":"2013-12-02 01:21:50.000000000","message":"Wouldn\u0027t version 3.x whatever make more sense?","commit_id":"a6a4ad9c5083ce9a829163bdca9079a3b1b47ccb"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"41e8931eabada7934da7148f899125f8836aa38f","unresolved":false,"context_lines":[{"line_number":19,"context_line":"HTTPClient \u003d httpclient.HTTPClient"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"def Client(version\u003dNone, unstable\u003dFalse, **kwargs):"},{"line_number":23,"context_line":"    \"\"\"Factory function to create a new identity service client."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    :param tuple version: The required version of the identity API. If"}],"source_content_type":"text/x-python","patch_set":26,"id":"AAAATn%2F%2BFM0%3D","line":22,"in_reply_to":"AAAATn%2F%2BJL8%3D","updated":"2013-12-02 19:02:05.000000000","message":"@ayoung, If anything automatically getting the latest stable version makes more sense than hard-defining a default.  Though, tbh, I\u0027d probably make it a required argument (at least in the future).","commit_id":"a6a4ad9c5083ce9a829163bdca9079a3b1b47ccb"}],"keystoneclient/discover.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        self.client_kwargs \u003d kwargs"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        if not self.client_class:"},{"line_number":55,"context_line":"            self.client_class \u003d self._CLIENT_VERSIONS[self.version[0]]"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __lt__(self, other):"},{"line_number":58,"context_line":"        if self.version \u003d\u003d other.version:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpGI%3D","line":55,"updated":"2013-10-31 01:14:31.000000000","message":"I think it would be better to raise a known exception if self.version[0] not in CLIENT_VERSIONS than a KeyError.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        self.client_kwargs \u003d kwargs"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        if not self.client_class:"},{"line_number":55,"context_line":"            self.client_class \u003d self._CLIENT_VERSIONS[self.version[0]]"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __lt__(self, other):"},{"line_number":58,"context_line":"        if self.version \u003d\u003d other.version:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Foy0%3D","line":55,"in_reply_to":"AAAATn%2F%2FpGI%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        if not self.client_class:"},{"line_number":55,"context_line":"            self.client_class \u003d self._CLIENT_VERSIONS[self.version[0]]"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __lt__(self, other):"},{"line_number":58,"context_line":"        if self.version \u003d\u003d other.version:"},{"line_number":59,"context_line":"            if self.status \u003d\u003d \u0027stable\u0027:"},{"line_number":60,"context_line":"                return False"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpF8%3D","line":57,"updated":"2013-10-31 01:14:31.000000000","message":"documentation of the intent of this function would be useful","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        if not self.client_class:"},{"line_number":55,"context_line":"            self.client_class \u003d self._CLIENT_VERSIONS[self.version[0]]"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __lt__(self, other):"},{"line_number":58,"context_line":"        if self.version \u003d\u003d other.version:"},{"line_number":59,"context_line":"            if self.status \u003d\u003d \u0027stable\u0027:"},{"line_number":60,"context_line":"                return False"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Foyw%3D","line":57,"in_reply_to":"AAAATn%2F%2FpF8%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        pass"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    raise exceptions.DiscoveryFailure(\"Invalid Response - Bad version\""},{"line_number":134,"context_line":"                                      \" data provided\")"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"class Discover(object):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpFY%3D","line":134,"updated":"2013-10-31 01:14:31.000000000","message":"change \"provided\" to \"returned\"","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        pass"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    raise exceptions.DiscoveryFailure(\"Invalid Response - Bad version\""},{"line_number":134,"context_line":"                                      \" data provided\")"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"class Discover(object):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Foys%3D","line":134,"in_reply_to":"AAAATn%2F%2FpFY%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":134,"context_line":"                                      \" data provided\")"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"class Discover(object):"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    _CLIENT_VERSIONS \u003d {2: v2_client.Client,"},{"line_number":140,"context_line":"                        3: v3_client.Client}"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpFM%3D","line":137,"updated":"2013-10-31 01:14:31.000000000","message":"docstring is required for public API","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":134,"context_line":"                                      \" data provided\")"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"class Discover(object):"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    _CLIENT_VERSIONS \u003d {2: v2_client.Client,"},{"line_number":140,"context_line":"                        3: v3_client.Client}"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Foyk%3D","line":137,"in_reply_to":"AAAATn%2F%2FpFM%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":137,"context_line":"class Discover(object):"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    _CLIENT_VERSIONS \u003d {2: v2_client.Client,"},{"line_number":140,"context_line":"                        3: v3_client.Client}"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def __init__(self, **kwargs):"},{"line_number":143,"context_line":"        self._url \u003d kwargs.get(\u0027endpoint\u0027) or kwargs.get(\u0027auth_url\u0027)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpFU%3D","line":140,"updated":"2013-10-31 01:14:31.000000000","message":"this is copied from line 35. Suggest move someplace common.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":137,"context_line":"class Discover(object):"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    _CLIENT_VERSIONS \u003d {2: v2_client.Client,"},{"line_number":140,"context_line":"                        3: v3_client.Client}"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def __init__(self, **kwargs):"},{"line_number":143,"context_line":"        self._url \u003d kwargs.get(\u0027endpoint\u0027) or kwargs.get(\u0027auth_url\u0027)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Foyg%3D","line":140,"in_reply_to":"AAAATn%2F%2FpFU%3D","updated":"2013-10-31 03:57:41.000000000","message":"shouldn\u0027t be here at all, deleted","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":140,"context_line":"                        3: v3_client.Client}"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def __init__(self, **kwargs):"},{"line_number":143,"context_line":"        self._url \u003d kwargs.get(\u0027endpoint\u0027) or kwargs.get(\u0027auth_url\u0027)"},{"line_number":144,"context_line":"        if not self._url:"},{"line_number":145,"context_line":"            raise exceptions.DiscoveryFailure(\u0027Not enough information to \u0027"},{"line_number":146,"context_line":"                                              \u0027determine URL. Provide either \u0027"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpFE%3D","line":143,"updated":"2013-10-31 01:14:31.000000000","message":"should have in docstring that endpoint takes precedence over auth_url.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":140,"context_line":"                        3: v3_client.Client}"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def __init__(self, **kwargs):"},{"line_number":143,"context_line":"        self._url \u003d kwargs.get(\u0027endpoint\u0027) or kwargs.get(\u0027auth_url\u0027)"},{"line_number":144,"context_line":"        if not self._url:"},{"line_number":145,"context_line":"            raise exceptions.DiscoveryFailure(\u0027Not enough information to \u0027"},{"line_number":146,"context_line":"                                              \u0027determine URL. Provide either \u0027"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Fo6E%3D","line":143,"in_reply_to":"AAAATn%2F%2FpFE%3D","updated":"2013-10-31 03:57:41.000000000","message":"This is based upon how the client works. It\u0027s not really precedence, if you give an endpoint and token you have no use for auth_url.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    @property"},{"line_number":153,"context_line":"    def url(self):"},{"line_number":154,"context_line":"        return self._url"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def _get_kwargs(self, dict\u003dNone, **kwargs):"},{"line_number":157,"context_line":"        client_kwargs \u003d self._client_kwargs.copy()"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpE8%3D","line":154,"updated":"2013-10-31 01:14:31.000000000","message":"seems excessive when could just have self.url instead.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    @property"},{"line_number":153,"context_line":"    def url(self):"},{"line_number":154,"context_line":"        return self._url"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def _get_kwargs(self, dict\u003dNone, **kwargs):"},{"line_number":157,"context_line":"        client_kwargs \u003d self._client_kwargs.copy()"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Foxg%3D","line":154,"in_reply_to":"AAAATn%2F%2FpE8%3D","updated":"2013-10-31 03:57:41.000000000","message":"actually, if i change things around just a little i can get rid of url entirely.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":153,"context_line":"    def url(self):"},{"line_number":154,"context_line":"        return self._url"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def _get_kwargs(self, dict\u003dNone, **kwargs):"},{"line_number":157,"context_line":"        client_kwargs \u003d self._client_kwargs.copy()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        if dict:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpE4%3D","line":156,"updated":"2013-10-31 01:14:31.000000000","message":"suggest change name to _get_client_constructor_kwargs","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":153,"context_line":"    def url(self):"},{"line_number":154,"context_line":"        return self._url"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"    def _get_kwargs(self, dict\u003dNone, **kwargs):"},{"line_number":157,"context_line":"        client_kwargs \u003d self._client_kwargs.copy()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        if dict:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Foxc%3D","line":156,"in_reply_to":"AAAATn%2F%2FpE4%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    def _get_kwargs(self, dict\u003dNone, **kwargs):"},{"line_number":157,"context_line":"        client_kwargs \u003d self._client_kwargs.copy()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        if dict:"},{"line_number":160,"context_line":"            client_kwargs.update(dict)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"        client_kwargs.update(**kwargs)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpEY%3D","line":159,"updated":"2013-10-31 01:14:31.000000000","message":"could have dict\u003d{} at line 156 to simplify.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    def _get_kwargs(self, dict\u003dNone, **kwargs):"},{"line_number":157,"context_line":"        client_kwargs \u003d self._client_kwargs.copy()"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        if dict:"},{"line_number":160,"context_line":"            client_kwargs.update(dict)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"        client_kwargs.update(**kwargs)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FoxY%3D","line":159,"in_reply_to":"AAAATn%2F%2FpEY%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        The connection parameters associated with this method are the same"},{"line_number":170,"context_line":"        format and name as those used by a client."},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"        The return value of this command will be cached for future use. If a"},{"line_number":173,"context_line":"        cached version is available it will be returned and the arguments to"},{"line_number":174,"context_line":"        this function will be ignored."},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpEE%3D","line":172,"updated":"2013-10-31 01:14:31.000000000","message":"change \"command\" to \"method\"","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        The connection parameters associated with this method are the same"},{"line_number":170,"context_line":"        format and name as those used by a client."},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"        The return value of this command will be cached for future use. If a"},{"line_number":173,"context_line":"        cached version is available it will be returned and the arguments to"},{"line_number":174,"context_line":"        this function will be ignored."},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FoxU%3D","line":172,"in_reply_to":"AAAATn%2F%2FpEE%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":171,"context_line":""},{"line_number":172,"context_line":"        The return value of this command will be cached for future use. If a"},{"line_number":173,"context_line":"        cached version is available it will be returned and the arguments to"},{"line_number":174,"context_line":"        this function will be ignored."},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"        :param string original_ip: The original IP of the requesting user"},{"line_number":177,"context_line":"                                   which will be sent to identity service in a"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpDM%3D","line":174,"updated":"2013-10-31 01:14:31.000000000","message":"seems like shouldn\u0027t return the cached value if changed from unstable\u003dTrue to unstable\u003dFalse?","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":171,"context_line":""},{"line_number":172,"context_line":"        The return value of this command will be cached for future use. If a"},{"line_number":173,"context_line":"        cached version is available it will be returned and the arguments to"},{"line_number":174,"context_line":"        this function will be ignored."},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"        :param string original_ip: The original IP of the requesting user"},{"line_number":177,"context_line":"                                   which will be sent to identity service in a"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Fo5s%3D","line":174,"in_reply_to":"AAAATn%2F%2FpDM%3D","updated":"2013-10-31 03:57:41.000000000","message":"I think i changed this after i wrote the doc, the server response is cached unstable is processed from the cached response.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                                   which will be sent to identity service in a"},{"line_number":178,"context_line":"                                   \u0027Forwarded\u0027 header. (optional)"},{"line_number":179,"context_line":"        :param boolean debug: Enables debug logging of all request and"},{"line_number":180,"context_line":"                              responses to the identity service."},{"line_number":181,"context_line":"                              default False (optional)"},{"line_number":182,"context_line":"        :param string cacert: Path to the Privacy Enhanced Mail (PEM) file"},{"line_number":183,"context_line":"                              which contains the trusted authority X.509"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpEQ%3D","line":180,"updated":"2013-10-31 01:14:31.000000000","message":"the formatting of this section is not good. If the argument name changes length then will have to reformat all these lines.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":177,"context_line":"                                   which will be sent to identity service in a"},{"line_number":178,"context_line":"                                   \u0027Forwarded\u0027 header. (optional)"},{"line_number":179,"context_line":"        :param boolean debug: Enables debug logging of all request and"},{"line_number":180,"context_line":"                              responses to the identity service."},{"line_number":181,"context_line":"                              default False (optional)"},{"line_number":182,"context_line":"        :param string cacert: Path to the Privacy Enhanced Mail (PEM) file"},{"line_number":183,"context_line":"                              which contains the trusted authority X.509"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Fo5Y%3D","line":180,"in_reply_to":"AAAATn%2F%2FpEQ%3D","updated":"2013-10-31 03:57:41.000000000","message":"agreed, but this seems to be the pattern all over keystoneclient.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        if unstable:"},{"line_number":240,"context_line":"            return self._available_versions"},{"line_number":241,"context_line":"        else:"},{"line_number":242,"context_line":"            versions \u003d []"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"            for v in self._available_versions:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpD8%3D","line":241,"updated":"2013-10-31 01:14:31.000000000","message":"remove the else then can unindent 12 lines.","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        if unstable:"},{"line_number":240,"context_line":"            return self._available_versions"},{"line_number":241,"context_line":"        else:"},{"line_number":242,"context_line":"            versions \u003d []"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"            for v in self._available_versions:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FoxQ%3D","line":241,"in_reply_to":"AAAATn%2F%2FpD8%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":299,"context_line":"                    if link[\u0027rel\u0027].lower() \u003d\u003d \u0027self\u0027:"},{"line_number":300,"context_line":"                        version_number \u003d _normalize_version_number(version_str)"},{"line_number":301,"context_line":"                        version_url \u003d link[\u0027href\u0027]"},{"line_number":302,"context_line":"                        break"},{"line_number":303,"context_line":"                else:"},{"line_number":304,"context_line":"                    _logger.warning(\"Didn\u0027t find any links in version data\")"},{"line_number":305,"context_line":"                    continue"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpD0%3D","line":302,"updated":"2013-10-31 01:14:31.000000000","message":"add a comment why no else leg, e.g., \"# ignore non-self rels\"","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":299,"context_line":"                    if link[\u0027rel\u0027].lower() \u003d\u003d \u0027self\u0027:"},{"line_number":300,"context_line":"                        version_number \u003d _normalize_version_number(version_str)"},{"line_number":301,"context_line":"                        version_url \u003d link[\u0027href\u0027]"},{"line_number":302,"context_line":"                        break"},{"line_number":303,"context_line":"                else:"},{"line_number":304,"context_line":"                    _logger.warning(\"Didn\u0027t find any links in version data\")"},{"line_number":305,"context_line":"                    continue"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2Fo5I%3D","line":302,"in_reply_to":"AAAATn%2F%2FpD0%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"e73d7d9ee0271686bdf274209f36cee71f3af8b0","unresolved":false,"context_lines":[{"line_number":308,"context_line":"                _logger.warning(\"Skipping over invalid version data\")"},{"line_number":309,"context_line":"                continue"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"            if not new_kwargs:"},{"line_number":312,"context_line":"                new_kwargs \u003d self._get_kwargs(**kwargs)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"                for url_type in (\u0027auth_url\u0027, \u0027endpoint\u0027):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FpDg%3D","line":311,"updated":"2013-10-31 01:14:31.000000000","message":"add a comment what\u0027s going on here... looks like only want to setup new_kwargs if we haven\u0027t done it for a different version?","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"879d114eb3305cd250f3346cc9fe8d90351274ce","unresolved":false,"context_lines":[{"line_number":308,"context_line":"                _logger.warning(\"Skipping over invalid version data\")"},{"line_number":309,"context_line":"                continue"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"            if not new_kwargs:"},{"line_number":312,"context_line":"                new_kwargs \u003d self._get_kwargs(**kwargs)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"                for url_type in (\u0027auth_url\u0027, \u0027endpoint\u0027):"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATn%2F%2FoxM%3D","line":311,"in_reply_to":"AAAATn%2F%2FpDg%3D","updated":"2013-10-31 03:57:41.000000000","message":"Done","commit_id":"dc987104012e353161b869338a8d3d3cd6715cd3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"07d29a1b3ce5b8e469e5bd44ea1273d6996ec42d","unresolved":false,"context_lines":[{"line_number":55,"context_line":"            try:"},{"line_number":56,"context_line":"                self.client_class \u003d self._CLIENT_VERSIONS[self.version[0]]"},{"line_number":57,"context_line":"            except KeyError:"},{"line_number":58,"context_line":"                raise exceptions.DiscoveryFailure(\"Unknown client available \""},{"line_number":59,"context_line":"                                                  \"for version: %s\" %"},{"line_number":60,"context_line":"                                                  self.version[0])"},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2FDzA%3D","line":58,"updated":"2013-11-19 01:23:52.000000000","message":"change \"Unknown\" to \"No\" ?","commit_id":"e1c553202f064f53ebc4470cc4e1bc326df3eb31"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"8bf2098bda911c1434bc24c62432d29d0533183b","unresolved":false,"context_lines":[{"line_number":55,"context_line":"            try:"},{"line_number":56,"context_line":"                self.client_class \u003d self._CLIENT_VERSIONS[self.version[0]]"},{"line_number":57,"context_line":"            except KeyError:"},{"line_number":58,"context_line":"                raise exceptions.DiscoveryFailure(\"Unknown client available \""},{"line_number":59,"context_line":"                                                  \"for version: %s\" %"},{"line_number":60,"context_line":"                                                  self.version[0])"},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2B0TA%3D","line":58,"in_reply_to":"AAAATn%2F%2FDzA%3D","updated":"2013-11-19 19:02:26.000000000","message":"Done","commit_id":"e1c553202f064f53ebc4470cc4e1bc326df3eb31"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"07d29a1b3ce5b8e469e5bd44ea1273d6996ec42d","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        treated alphabetically (alpha \u003c beta etc)"},{"line_number":68,"context_line":"        \"\"\""},{"line_number":69,"context_line":"        if self.version \u003d\u003d other.version:"},{"line_number":70,"context_line":"            if self.status \u003d\u003d \u0027stable\u0027:"},{"line_number":71,"context_line":"                return False"},{"line_number":72,"context_line":"            elif other.status \u003d\u003d \u0027stable\u0027:"},{"line_number":73,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2B4Vc%3D","line":70,"updated":"2013-11-19 01:23:52.000000000","message":"if self.status \u003d\u003d \u0027stable\u0027 and other.status \u003d\u003d \u0027stable\u0027 then this should return False, since it\u0027s not \u003c.","commit_id":"e1c553202f064f53ebc4470cc4e1bc326df3eb31"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"8bf2098bda911c1434bc24c62432d29d0533183b","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        treated alphabetically (alpha \u003c beta etc)"},{"line_number":68,"context_line":"        \"\"\""},{"line_number":69,"context_line":"        if self.version \u003d\u003d other.version:"},{"line_number":70,"context_line":"            if self.status \u003d\u003d \u0027stable\u0027:"},{"line_number":71,"context_line":"                return False"},{"line_number":72,"context_line":"            elif other.status \u003d\u003d \u0027stable\u0027:"},{"line_number":73,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2B0So%3D","line":70,"in_reply_to":"AAAATn%2F%2B4Vc%3D","updated":"2013-11-19 19:02:26.000000000","message":"I\u0027m not sure how that differs from what happens now. If self.status is stable then it is the highest available level of that version number so it can never be \u003c - i don\u0027t need to explicitly check other.status","commit_id":"e1c553202f064f53ebc4470cc4e1bc326df3eb31"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"07d29a1b3ce5b8e469e5bd44ea1273d6996ec42d","unresolved":false,"context_lines":[{"line_number":215,"context_line":""},{"line_number":216,"context_line":"        :param bool unstable: Accept endpoints not marked \u0027stable\u0027. (optional)"},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"        :returns: A List of dictionaries as presented by the server. The dict"},{"line_number":219,"context_line":"                  will contain the version and the URL to use for the version."},{"line_number":220,"context_line":"                  It is a direct representation of the layout presented by the"},{"line_number":221,"context_line":"                  identity API."}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2B4VY%3D","line":218,"updated":"2013-11-19 01:23:52.000000000","message":"suggest change \"The dict\" to \"Each dict\"","commit_id":"e1c553202f064f53ebc4470cc4e1bc326df3eb31"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"8bf2098bda911c1434bc24c62432d29d0533183b","unresolved":false,"context_lines":[{"line_number":215,"context_line":""},{"line_number":216,"context_line":"        :param bool unstable: Accept endpoints not marked \u0027stable\u0027. (optional)"},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"        :returns: A List of dictionaries as presented by the server. The dict"},{"line_number":219,"context_line":"                  will contain the version and the URL to use for the version."},{"line_number":220,"context_line":"                  It is a direct representation of the layout presented by the"},{"line_number":221,"context_line":"                  identity API."}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2B0TE%3D","line":218,"in_reply_to":"AAAATn%2F%2B4VY%3D","updated":"2013-11-19 19:02:26.000000000","message":"Done","commit_id":"e1c553202f064f53ebc4470cc4e1bc326df3eb31"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":26,"context_line":"class _KeystoneVersion(object):"},{"line_number":27,"context_line":"    \"\"\"A factory object that holds all the information to create a client."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    This object will hold all the kwargs that were passed to discovery so that"},{"line_number":30,"context_line":"    a user may simply call it to create a new client object."},{"line_number":31,"context_line":"    Additional arguments passed to the call will override those provided to"},{"line_number":32,"context_line":"    the object."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpvo%3D","line":29,"updated":"2013-11-22 00:53:29.000000000","message":"suggest change \"object\" to \"callable object\"... or, since this is a class and not an object:\n\n Instances of this class are callable objects that hold all ...","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":26,"context_line":"class _KeystoneVersion(object):"},{"line_number":27,"context_line":"    \"\"\"A factory object that holds all the information to create a client."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    This object will hold all the kwargs that were passed to discovery so that"},{"line_number":30,"context_line":"    a user may simply call it to create a new client object."},{"line_number":31,"context_line":"    Additional arguments passed to the call will override those provided to"},{"line_number":32,"context_line":"    the object."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiSo%3D","line":29,"in_reply_to":"AAAATn%2F%2Bpvo%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    This object will hold all the kwargs that were passed to discovery so that"},{"line_number":30,"context_line":"    a user may simply call it to create a new client object."},{"line_number":31,"context_line":"    Additional arguments passed to the call will override those provided to"},{"line_number":32,"context_line":"    the object."},{"line_number":33,"context_line":"    \"\"\""},{"line_number":34,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpuw%3D","line":31,"updated":"2013-11-22 00:53:29.000000000","message":"suggest change \"override\" to \"override or add to\"\n\nsuggest change \"provided to\" to \"held by\" (since used \"hold\" previously)","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    This object will hold all the kwargs that were passed to discovery so that"},{"line_number":30,"context_line":"    a user may simply call it to create a new client object."},{"line_number":31,"context_line":"    Additional arguments passed to the call will override those provided to"},{"line_number":32,"context_line":"    the object."},{"line_number":33,"context_line":"    \"\"\""},{"line_number":34,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiSk%3D","line":31,"in_reply_to":"AAAATn%2F%2Bpuw%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":57,"context_line":"            except KeyError:"},{"line_number":58,"context_line":"                raise exceptions.DiscoveryFailure(\"No client available \""},{"line_number":59,"context_line":"                                                  \"for version: %s\" %"},{"line_number":60,"context_line":"                                                  self.version[0])"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def __lt__(self, other):"},{"line_number":63,"context_line":"        \"\"\"Version Ordering."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpt4%3D","line":60,"updated":"2013-11-22 00:53:29.000000000","message":"suggest use entire version here (change self.version[0] to self.version)","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":57,"context_line":"            except KeyError:"},{"line_number":58,"context_line":"                raise exceptions.DiscoveryFailure(\"No client available \""},{"line_number":59,"context_line":"                                                  \"for version: %s\" %"},{"line_number":60,"context_line":"                                                  self.version[0])"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def __lt__(self, other):"},{"line_number":63,"context_line":"        \"\"\"Version Ordering."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiSc%3D","line":60,"in_reply_to":"AAAATn%2F%2Bpt4%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":125,"context_line":"    headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027}"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    client \u003d httpclient.HTTPClient(**kwargs)"},{"line_number":128,"context_line":"    resp, body_resp \u003d client.request(url, \u0027GET\u0027, headers\u003dheaders)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    # In the event of querying a root URL we will get back a list of"},{"line_number":131,"context_line":"    # available versions."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpsc%3D","line":128,"updated":"2013-11-22 00:53:29.000000000","message":"should we check the server response code? e.g., make sure it\u0027s a 300 or 200 and not something unexpected, like a 500 or something.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":125,"context_line":"    headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027}"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    client \u003d httpclient.HTTPClient(**kwargs)"},{"line_number":128,"context_line":"    resp, body_resp \u003d client.request(url, \u0027GET\u0027, headers\u003dheaders)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    # In the event of querying a root URL we will get back a list of"},{"line_number":131,"context_line":"    # available versions."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiSQ%3D","line":128,"in_reply_to":"AAAATn%2F%2Bpsc%3D","updated":"2013-11-25 00:33:03.000000000","message":"So anything 4xx or 5xx will throw an exception within the request() call, and the standard redirect calls will happen automatically.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        pass"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"    raise exceptions.DiscoveryFailure(\"Invalid Response - Bad version\""},{"line_number":145,"context_line":"                                      \" data returned\")"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"class Discover(object):"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BpsM%3D","line":145,"updated":"2013-11-22 00:53:29.000000000","message":"I think it would be useful to store the server\u0027s response in the exception in case the caller can use it.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        pass"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"    raise exceptions.DiscoveryFailure(\"Invalid Response - Bad version\""},{"line_number":145,"context_line":"                                      \" data returned\")"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"class Discover(object):"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiSM%3D","line":145,"in_reply_to":"AAAATn%2F%2BpsM%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":157,"context_line":"        \"\"\"Construct a new discovery object."},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        The connection parameters associated with this method are the same"},{"line_number":160,"context_line":"        format and name as those used by a client. If not overriden in"},{"line_number":161,"context_line":"        subsequent methods they will also be what is passed to the constructed"},{"line_number":162,"context_line":"        client."},{"line_number":163,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bprs%3D","line":160,"updated":"2013-11-22 00:53:29.000000000","message":"is there a reference that could be provided to what a client is? Users are going to need to figure this out.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":157,"context_line":"        \"\"\"Construct a new discovery object."},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        The connection parameters associated with this method are the same"},{"line_number":160,"context_line":"        format and name as those used by a client. If not overriden in"},{"line_number":161,"context_line":"        subsequent methods they will also be what is passed to the constructed"},{"line_number":162,"context_line":"        client."},{"line_number":163,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiSE%3D","line":160,"in_reply_to":"AAAATn%2F%2Bprs%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":164,"context_line":"        In the event that auth_url and endpoint is provided then auth_url will"},{"line_number":165,"context_line":"        be used in accordance with how the client operates."},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"        The initialization process also runs the server query."},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        :param string auth_url: Identity service endpoint for authorization."},{"line_number":170,"context_line":"        :param string endpoint: A user-supplied endpoint URL for the identity"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bprk%3D","line":167,"updated":"2013-11-22 00:53:29.000000000","message":"suggest change \"runs the server query\" to \"queries the server\"","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":164,"context_line":"        In the event that auth_url and endpoint is provided then auth_url will"},{"line_number":165,"context_line":"        be used in accordance with how the client operates."},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"        The initialization process also runs the server query."},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        :param string auth_url: Identity service endpoint for authorization."},{"line_number":170,"context_line":"        :param string endpoint: A user-supplied endpoint URL for the identity"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiSA%3D","line":167,"in_reply_to":"AAAATn%2F%2Bprk%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":166,"context_line":""},{"line_number":167,"context_line":"        The initialization process also runs the server query."},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        :param string auth_url: Identity service endpoint for authorization."},{"line_number":170,"context_line":"        :param string endpoint: A user-supplied endpoint URL for the identity"},{"line_number":171,"context_line":"                                service. (optional)"},{"line_number":172,"context_line":"        :param string original_ip: The original IP of the requesting user"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BprU%3D","line":169,"updated":"2013-11-22 00:53:29.000000000","message":"this parameter is also optional, so put (optional)","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":166,"context_line":""},{"line_number":167,"context_line":"        The initialization process also runs the server query."},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"        :param string auth_url: Identity service endpoint for authorization."},{"line_number":170,"context_line":"        :param string endpoint: A user-supplied endpoint URL for the identity"},{"line_number":171,"context_line":"                                service. (optional)"},{"line_number":172,"context_line":"        :param string original_ip: The original IP of the requesting user"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiR8%3D","line":169,"in_reply_to":"AAAATn%2F%2BprU%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        self._client_kwargs \u003d kwargs"},{"line_number":202,"context_line":"        self._available_versions \u003d available_versions(url, **kwargs)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"    def _get_client_constructor_kwargs(self, dict\u003d{}, **kwargs):"},{"line_number":205,"context_line":"        client_kwargs \u003d self._client_kwargs.copy()"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"        client_kwargs.update(dict)"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpqw%3D","line":204,"updated":"2013-11-22 00:53:29.000000000","message":"dict is a python built-in so don\u0027t use it for a symbol otherwise it masks the built-in.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        self._client_kwargs \u003d kwargs"},{"line_number":202,"context_line":"        self._available_versions \u003d available_versions(url, **kwargs)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"    def _get_client_constructor_kwargs(self, dict\u003d{}, **kwargs):"},{"line_number":205,"context_line":"        client_kwargs \u003d self._client_kwargs.copy()"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"        client_kwargs.update(dict)"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiR4%3D","line":204,"in_reply_to":"AAAATn%2F%2Bpqw%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":247,"context_line":"                      {\u0027base\u0027: \u0027application/xml\u0027,"},{"line_number":248,"context_line":"                       \u0027type\u0027: \u0027application/vnd.openstack.identity-v2.0+xml\u0027}],"},{"line_number":249,"context_line":"                  \u0027status\u0027: \u0027stable\u0027,"},{"line_number":250,"context_line":"                  \u0027updated\u0027: \u00272013-03-06T00:00:00Z\u0027}]"},{"line_number":251,"context_line":"        \"\"\""},{"line_number":252,"context_line":"        if unstable:"},{"line_number":253,"context_line":"            return self._available_versions"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BpqY%3D","line":250,"updated":"2013-11-22 00:53:29.000000000","message":"nice!","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":250,"context_line":"                  \u0027updated\u0027: \u00272013-03-06T00:00:00Z\u0027}]"},{"line_number":251,"context_line":"        \"\"\""},{"line_number":252,"context_line":"        if unstable:"},{"line_number":253,"context_line":"            return self._available_versions"},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"        versions \u003d []"},{"line_number":256,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BpqI%3D","line":253,"updated":"2013-11-22 00:53:29.000000000","message":"add a comment why can return early here... don\u0027t need to filter available versions.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":250,"context_line":"                  \u0027updated\u0027: \u00272013-03-06T00:00:00Z\u0027}]"},{"line_number":251,"context_line":"        \"\"\""},{"line_number":252,"context_line":"        if unstable:"},{"line_number":253,"context_line":"            return self._available_versions"},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"        versions \u003d []"},{"line_number":256,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiR0%3D","line":253,"in_reply_to":"AAAATn%2F%2BpqI%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":259,"context_line":"                status \u003d v[\u0027status\u0027]"},{"line_number":260,"context_line":"            except KeyError:"},{"line_number":261,"context_line":"                _logger.warning(\"Skipping over invalid version data. \""},{"line_number":262,"context_line":"                                \"No stability status in version\")"},{"line_number":263,"context_line":"            else:"},{"line_number":264,"context_line":"                if status \u003d\u003d \u0027stable\u0027:"},{"line_number":265,"context_line":"                    versions.append(v)"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BpqU%3D","line":262,"updated":"2013-11-22 00:53:29.000000000","message":"add a . at end of sentence.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":259,"context_line":"                status \u003d v[\u0027status\u0027]"},{"line_number":260,"context_line":"            except KeyError:"},{"line_number":261,"context_line":"                _logger.warning(\"Skipping over invalid version data. \""},{"line_number":262,"context_line":"                                \"No stability status in version\")"},{"line_number":263,"context_line":"            else:"},{"line_number":264,"context_line":"                if status \u003d\u003d \u0027stable\u0027:"},{"line_number":265,"context_line":"                    versions.append(v)"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiRw%3D","line":262,"in_reply_to":"AAAATn%2F%2BpqU%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":267,"context_line":"        return versions"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def _available_clients(self, unstable\u003dFalse, **kwargs):"},{"line_number":270,"context_line":"        \"\"\"Return a list of available API versions and client params."},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"        :returns: A dictionary of available API endpoints with the version"},{"line_number":273,"context_line":"                  number as a tuple as the key, and a factory object that can"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bppg%3D","line":270,"updated":"2013-11-22 00:53:29.000000000","message":"this returns a dict, not a list. Also, it\u0027s a dict of factory functions.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":267,"context_line":"        return versions"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def _available_clients(self, unstable\u003dFalse, **kwargs):"},{"line_number":270,"context_line":"        \"\"\"Return a list of available API versions and client params."},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"        :returns: A dictionary of available API endpoints with the version"},{"line_number":273,"context_line":"                  number as a tuple as the key, and a factory object that can"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiRs%3D","line":270,"in_reply_to":"AAAATn%2F%2Bppg%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":280,"context_line":"        Example::"},{"line_number":281,"context_line":""},{"line_number":282,"context_line":"            \u003e\u003e\u003e from keystoneclient import client"},{"line_number":283,"context_line":"            \u003e\u003e\u003e available_versions \u003d client._available_versions(auth_url\u003durl,"},{"line_number":284,"context_line":"            ...                                                 **kwargs)"},{"line_number":285,"context_line":"            \u003e\u003e\u003e try:"},{"line_number":286,"context_line":"            ...     v2_factory \u003d available_versions[(2, 0)]"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BppM%3D","line":283,"updated":"2013-11-22 00:53:29.000000000","message":"not sure what this example is showing... this function is _available_clients not _available_versions.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":280,"context_line":"        Example::"},{"line_number":281,"context_line":""},{"line_number":282,"context_line":"            \u003e\u003e\u003e from keystoneclient import client"},{"line_number":283,"context_line":"            \u003e\u003e\u003e available_versions \u003d client._available_versions(auth_url\u003durl,"},{"line_number":284,"context_line":"            ...                                                 **kwargs)"},{"line_number":285,"context_line":"            \u003e\u003e\u003e try:"},{"line_number":286,"context_line":"            ...     v2_factory \u003d available_versions[(2, 0)]"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiRo%3D","line":283,"in_reply_to":"AAAATn%2F%2BppM%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":299,"context_line":"        client_kwargs \u003d self._get_client_constructor_kwargs(dict\u003dkwargs)"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        for version_data in response_values:"},{"line_number":302,"context_line":"            try:"},{"line_number":303,"context_line":"                version_str \u003d version_data[\u0027id\u0027]"},{"line_number":304,"context_line":"                status \u003d version_data[\u0027status\u0027]"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpn8%3D","line":302,"updated":"2013-11-22 00:53:29.000000000","message":"I\u0027d like to see 302-323 (or 333) moved into a function. it\u0027s too long and too complicated. (a for loop in a for loop with breaks and continues is too complicated.)","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":299,"context_line":"        client_kwargs \u003d self._get_client_constructor_kwargs(dict\u003dkwargs)"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        for version_data in response_values:"},{"line_number":302,"context_line":"            try:"},{"line_number":303,"context_line":"                version_str \u003d version_data[\u0027id\u0027]"},{"line_number":304,"context_line":"                status \u003d version_data[\u0027status\u0027]"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiQg%3D","line":302,"in_reply_to":"AAAATn%2F%2Bpn8%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":305,"context_line":""},{"line_number":306,"context_line":"                if not version_str.startswith(\u0027v\u0027):"},{"line_number":307,"context_line":"                    _logger.warning(\u0027Skipping over invalid version string: %s.\u0027"},{"line_number":308,"context_line":"                                    \u0027 It should start with a v\u0027, version_str)"},{"line_number":309,"context_line":"                    continue"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"                for link in version_data[\u0027links\u0027]:"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpoo%3D","line":308,"updated":"2013-11-22 00:53:29.000000000","message":"add . at end of sentence.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":305,"context_line":""},{"line_number":306,"context_line":"                if not version_str.startswith(\u0027v\u0027):"},{"line_number":307,"context_line":"                    _logger.warning(\u0027Skipping over invalid version string: %s.\u0027"},{"line_number":308,"context_line":"                                    \u0027 It should start with a v\u0027, version_str)"},{"line_number":309,"context_line":"                    continue"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"                for link in version_data[\u0027links\u0027]:"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiQc%3D","line":308,"in_reply_to":"AAAATn%2F%2Bpoo%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":345,"context_line":"                              specified the client will be selected such that"},{"line_number":346,"context_line":"                              the major version is equivalent and an endpoint"},{"line_number":347,"context_line":"                              provides at least the specified minor version."},{"line_number":348,"context_line":"                              For example to specify the 3.1 API use (3, 1)."},{"line_number":349,"context_line":"        :param bool unstable: Accept endpoints not marked \u0027stable\u0027. (optional)"},{"line_number":350,"context_line":"        :param kwargs: Additional arguments will be passed to the client"},{"line_number":351,"context_line":"                       creation process and override those provided to the"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpm4%3D","line":348,"updated":"2013-11-22 00:53:29.000000000","message":"since this is passed to _normalize_version_number several formats are allowed and not just tuples.\n\nalso, should say (optional)","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":345,"context_line":"                              specified the client will be selected such that"},{"line_number":346,"context_line":"                              the major version is equivalent and an endpoint"},{"line_number":347,"context_line":"                              provides at least the specified minor version."},{"line_number":348,"context_line":"                              For example to specify the 3.1 API use (3, 1)."},{"line_number":349,"context_line":"        :param bool unstable: Accept endpoints not marked \u0027stable\u0027. (optional)"},{"line_number":350,"context_line":"        :param kwargs: Additional arguments will be passed to the client"},{"line_number":351,"context_line":"                       creation process and override those provided to the"}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiQQ%3D","line":348,"in_reply_to":"AAAATn%2F%2Bpm4%3D","updated":"2013-11-25 00:33:03.000000000","message":"I know, but that one i want to keep. I want tuples to be the only documented way of doing it, handling the others just gives us interoperability with the other blueprint.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":348,"context_line":"                              For example to specify the 3.1 API use (3, 1)."},{"line_number":349,"context_line":"        :param bool unstable: Accept endpoints not marked \u0027stable\u0027. (optional)"},{"line_number":350,"context_line":"        :param kwargs: Additional arguments will be passed to the client"},{"line_number":351,"context_line":"                       creation process and override those provided to the"},{"line_number":352,"context_line":"                       Discovery object initialization."},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"        :returns: An instantiated identity client object."}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BpnY%3D","line":351,"updated":"2013-11-22 00:53:29.000000000","message":"change \"process\" to \"function\".. or remove \"be passed to the client creation process and\" ...\n\n Additional arguments will override those provided to\n this object\u0027s constructor.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        :param bool unstable: Accept endpoints not marked \u0027stable\u0027. (optional)"},{"line_number":350,"context_line":"        :param kwargs: Additional arguments will be passed to the client"},{"line_number":351,"context_line":"                       creation process and override those provided to the"},{"line_number":352,"context_line":"                       Discovery object initialization."},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"        :returns: An instantiated identity client object."},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpnc%3D","line":352,"updated":"2013-11-22 00:53:29.000000000","message":"change \"Discovery\" to \"Discover\", or use \"this object\"","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":374,"context_line":"                    break"},{"line_number":375,"context_line":""},{"line_number":376,"context_line":"        elif versions:"},{"line_number":377,"context_line":"            chosen \u003d max(six.iteritems(versions))[1]"},{"line_number":378,"context_line":""},{"line_number":379,"context_line":"        if not chosen:"},{"line_number":380,"context_line":"            msg \u003d \"Could not find a suitable endpoint\""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BpmM%3D","line":377,"updated":"2013-11-22 00:53:29.000000000","message":"this could use a comment, or be split up so that it\u0027s obvious what it\u0027s doing.\n\nalso, is it possible for versions to be an empty dict?","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":374,"context_line":"                    break"},{"line_number":375,"context_line":""},{"line_number":376,"context_line":"        elif versions:"},{"line_number":377,"context_line":"            chosen \u003d max(six.iteritems(versions))[1]"},{"line_number":378,"context_line":""},{"line_number":379,"context_line":"        if not chosen:"},{"line_number":380,"context_line":"            msg \u003d \"Could not find a suitable endpoint\""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiQA%3D","line":377,"in_reply_to":"AAAATn%2F%2BpmM%3D","updated":"2013-11-25 00:33:03.000000000","message":"yes, but then it would fail the elif versions: guard","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":379,"context_line":"        if not chosen:"},{"line_number":380,"context_line":"            msg \u003d \"Could not find a suitable endpoint\""},{"line_number":381,"context_line":"            if version:"},{"line_number":382,"context_line":"                msg \u003d \"%s for client version: %s\" % (msg, version)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"            raise exceptions.VersionNotAvailable(msg)"},{"line_number":385,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpmg%3D","line":382,"updated":"2013-11-22 00:53:29.000000000","message":"could also include in the message what versions are available since we know what they are.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"c9cf641625472fc007cfe7cdcad1b2c8cdbaf3d3","unresolved":false,"context_lines":[{"line_number":379,"context_line":"        if not chosen:"},{"line_number":380,"context_line":"            msg \u003d \"Could not find a suitable endpoint\""},{"line_number":381,"context_line":"            if version:"},{"line_number":382,"context_line":"                msg \u003d \"%s for client version: %s\" % (msg, version)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"            raise exceptions.VersionNotAvailable(msg)"},{"line_number":385,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2BiP8%3D","line":382,"in_reply_to":"AAAATn%2F%2Bpmg%3D","updated":"2013-11-25 00:33:03.000000000","message":"Done","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d59fc99b4f2d1828bb4c2345c54cdd1607e97775","unresolved":false,"context_lines":[{"line_number":279,"context_line":"        return versions"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"    def _get_factory_from_response_entry(self, version_data, **kwargs):"},{"line_number":282,"context_line":"        \"\"\"Create a _KeystoneVersion factory object from a version response"},{"line_number":283,"context_line":"        entry returned from a server."},{"line_number":284,"context_line":"        \"\"\""},{"line_number":285,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAATn%2F%2BcTU%3D","line":282,"updated":"2013-11-26 01:10:07.000000000","message":"suggest remove \"factory\" from this since it seems like it returns a function that creates a _KeystoneVersion.","commit_id":"efdc9cbf67b46ea8d9361c6030c4f5ea8817a74a"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d59fc99b4f2d1828bb4c2345c54cdd1607e97775","unresolved":false,"context_lines":[{"line_number":287,"context_line":"            status \u003d version_data[\u0027status\u0027]"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"            if not version_str.startswith(\u0027v\u0027):"},{"line_number":290,"context_line":"                raise exceptions.DiscoveryFailure(\u0027Skipping over invalid \u0027"},{"line_number":291,"context_line":"                                                  \u0027version string: %s. It \u0027"},{"line_number":292,"context_line":"                                                  \u0027should start with a v.\u0027 %"},{"line_number":293,"context_line":"                                                  version_str)"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAATn%2F%2BcTI%3D","line":290,"updated":"2013-11-26 01:10:07.000000000","message":"suggest put this on new line rather than stuffing it on the right.","commit_id":"efdc9cbf67b46ea8d9361c6030c4f5ea8817a74a"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"d59fc99b4f2d1828bb4c2345c54cdd1607e97775","unresolved":false,"context_lines":[{"line_number":309,"context_line":"                                              \u0027version data.\u0027)"},{"line_number":310,"context_line":""},{"line_number":311,"context_line":"        # NOTE(jamielennox): the url might be the auth_url or the endpoint"},{"line_number":312,"context_line":"        # depending on what was passed initially. Order is important, endpoint"},{"line_number":313,"context_line":"        # needs to override auth_url."},{"line_number":314,"context_line":"        for url_type in (\u0027auth_url\u0027, \u0027endpoint\u0027):"},{"line_number":315,"context_line":"            if self._client_kwargs.get(url_type, False):"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAATn%2F%2BcSk%3D","line":312,"updated":"2013-11-26 01:10:07.000000000","message":"I\u0027m not sure what \"depending on what was passed initially\" means?","commit_id":"efdc9cbf67b46ea8d9361c6030c4f5ea8817a74a"}],"keystoneclient/exceptions.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"caf89800315c852e0f4ed5b7186185e63f1fbbfa","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class DiscoveryFailure(Exception):"},{"line_number":45,"context_line":"    pass"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"class VersionNotAvailable(DiscoveryFailure):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAARH%2F%2F3a4%3D","line":45,"updated":"2013-08-16 01:20:32.000000000","message":"add a comment","commit_id":"b9d22cb643c72b468dea0a60b7713e35383e0440"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"caf89800315c852e0f4ed5b7186185e63f1fbbfa","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    pass"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"class VersionNotAvailable(DiscoveryFailure):"},{"line_number":49,"context_line":"    pass"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAARH%2F%2F3as%3D","line":48,"updated":"2013-08-16 01:20:32.000000000","message":"add a comment, also s/DiscoveryFailure/Exception.","commit_id":"b9d22cb643c72b468dea0a60b7713e35383e0440"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"8bc81eee6c7a6704494812408de30e51639f7104","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    pass"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"class VersionNotAvailable(DiscoveryFailure):"},{"line_number":49,"context_line":"    pass"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAARH%2F%2F24w%3D","line":48,"in_reply_to":"AAAARH%2F%2F3as%3D","updated":"2013-08-16 05:29:50.000000000","message":"disregard my second comment!","commit_id":"b9d22cb643c72b468dea0a60b7713e35383e0440"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"1cc98db1ff3164487ff14338e165cf3f277568fa","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":"class DiscoveryFailure(Exception):"},{"line_number":25,"context_line":"    \"\"\"Discovery of client versions failed.\"\"\""},{"line_number":26,"context_line":"    pass"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class VersionNotAvailable(DiscoveryFailure):"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAS3%2F%2FEeg%3D","line":26,"updated":"2013-10-05 15:34:12.000000000","message":"Is there any reason to have the pass here?","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"fb6b8013f194185f542f2060b935e7a744964a0b","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":"class DiscoveryFailure(Exception):"},{"line_number":25,"context_line":"    \"\"\"Discovery of client versions failed.\"\"\""},{"line_number":26,"context_line":"    pass"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class VersionNotAvailable(DiscoveryFailure):"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATH%2F%2F6%2FY%3D","line":26,"in_reply_to":"AAAAS3%2F%2FEeg%3D","updated":"2013-10-08 01:26:46.000000000","message":"Force of habit, i guess i wrote the doc string after the pass","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"1cc98db1ff3164487ff14338e165cf3f277568fa","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class VersionNotAvailable(DiscoveryFailure):"},{"line_number":30,"context_line":"    \"\"\"Discovery failed as the version you requested is not available.\"\"\""},{"line_number":31,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAS3%2F%2FEec%3D","line":31,"updated":"2013-10-05 15:34:12.000000000","message":"...or here?","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"fb6b8013f194185f542f2060b935e7a744964a0b","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class VersionNotAvailable(DiscoveryFailure):"},{"line_number":30,"context_line":"    \"\"\"Discovery failed as the version you requested is not available.\"\"\""},{"line_number":31,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAATH%2F%2F6%2FI%3D","line":31,"in_reply_to":"AAAAS3%2F%2FEec%3D","updated":"2013-10-08 01:26:46.000000000","message":"Done","commit_id":"82546b28b1ee6d1600e087ab646b95d0b4924cf9"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a0d9b68660bc324b1fc481768e72813176a224fa","unresolved":false,"context_lines":[{"line_number":21,"context_line":"#flake8: noqa"},{"line_number":22,"context_line":"from keystoneclient.apiclient.exceptions import *"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"class DiscoveryFailure(Exception):"},{"line_number":25,"context_line":"    \"\"\"Discovery of client versions failed.\"\"\""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAATn%2F%2F70A%3D","line":24,"updated":"2013-10-24 23:54:50.000000000","message":"Since I was looking at this... should this be derived from ClientException (The base exception class for all exceptions this library raises)?\n\nAlternatively, should we have a new exception base class derived from ClientException that the exceptions in here are derived from?","commit_id":"8f7f752486fb2a99762ecc6b3fa6e52661e8bb8c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"64ae78b02f6b211ca1e23bfc63c43063850a2fc2","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"#flake8: noqa"},{"line_number":22,"context_line":"from keystoneclient.apiclient.exceptions import *"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"class DiscoveryFailure(ClientException):"},{"line_number":25,"context_line":"    \"\"\"Discovery of client versions failed.\"\"\""},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"AAAATn%2F%2Bpl0%3D","line":23,"updated":"2013-11-22 00:53:29.000000000","message":"add another blank line here.","commit_id":"c6142f28915c61e0384af198a8f86684eb0b70bb"}],"keystoneclient/tests/test_discovery.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a0d9b68660bc324b1fc481768e72813176a224fa","unresolved":false,"context_lines":[{"line_number":199,"context_line":"        self.assertRaises(exceptions.DiscoveryFailure,"},{"line_number":200,"context_line":"                          client.Client, **kwargs)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    def test_available_versions(self):"},{"line_number":203,"context_line":"        httpretty.register_uri(httpretty.GET, BASE_URL, status\u003d300,"},{"line_number":204,"context_line":"                               body\u003dV3_VERSION_LIST)"},{"line_number":205,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAATn%2F%2F7z0%3D","line":202,"updated":"2013-10-24 23:54:50.000000000","message":"I think available versions tests should be in their own class.","commit_id":"8f7f752486fb2a99762ecc6b3fa6e52661e8bb8c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"a0d9b68660bc324b1fc481768e72813176a224fa","unresolved":false,"context_lines":[{"line_number":211,"context_line":"            self.assertIn(\u0027links\u0027, v)"},{"line_number":212,"context_line":""},{"line_number":213,"context_line":"    def test_available_versions_individual(self):"},{"line_number":214,"context_line":"        httpretty.register_uri(httpretty.GET, V3_URL, status\u003d300,"},{"line_number":215,"context_line":"                               body\u003dV3_VERSION_ENTRY)"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"        versions \u003d client.available_versions(V3_URL)"}],"source_content_type":"text/x-python","patch_set":21,"id":"AAAATn%2F%2F7z8%3D","line":214,"updated":"2013-10-24 23:54:50.000000000","message":"not how my server works.","commit_id":"8f7f752486fb2a99762ecc6b3fa6e52661e8bb8c"}],"keystoneclient/utils.py":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"3f43d0be17889ff3e9061be10764855eaa54e842","unresolved":false,"context_lines":[{"line_number":153,"context_line":"            return"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"def http_log_resp(logger, resp):"},{"line_number":157,"context_line":"    logger.debug(\"RESP: [%s] %s\\nRESP BODY: %s\\n\","},{"line_number":158,"context_line":"                 resp.status_code, resp.headers, resp.text)"},{"line_number":159,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAQn%2F%2Fls8%3D","line":156,"updated":"2013-07-27 01:43:50.000000000","message":"These functions are untested.","commit_id":"7bd23b355bd1d112c9bfa743630b5f0ee3fd241a"}],"keystoneclient/v2_0/client.py":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"527ec6d6a6c28b479886ce41d4fd99a0d24a8c80","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    version \u003d \u0027v2.0\u0027"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"    def __init__(self, **kwargs):"},{"line_number":127,"context_line":"        \"\"\"Initialize a new client for the Keystone v2.0 API.\"\"\""},{"line_number":128,"context_line":"        super(Client, self).__init__(**kwargs)"},{"line_number":129,"context_line":"        self.endpoints \u003d endpoints.EndpointManager(self)"},{"line_number":130,"context_line":"        self.roles \u003d roles.RoleManager(self)"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAATH%2F%2Fij4%3D","line":127,"updated":"2013-10-14 20:35:04.000000000","message":"Does this comment still hold? If so, why did version end up external?","commit_id":"377a7110d44a0052f477256e1ad393d776078244"}],"tests/test_discovery.py":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"3f43d0be17889ff3e9061be10764855eaa54e842","unresolved":false,"context_lines":[{"line_number":199,"context_line":"        self.assertVersionNotAvailable(BASE_URL, version\u003d5)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def test_discover_501_returns_v2_client(self):"},{"line_number":202,"context_line":"        httpretty.register_uri(httpretty.GET, BASE_URL, status\u003d501)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"        self.assertCreatesV2(BASE_URL)"},{"line_number":205,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAQn%2F%2Fluo%3D","line":202,"updated":"2013-07-27 01:43:50.000000000","message":"501 unimplemented means that the client defaults to V2?  That seems a little optimistic.  What is your rationale?","commit_id":"7bd23b355bd1d112c9bfa743630b5f0ee3fd241a"}]}
