)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"52c1a7f113e05fb4a1d7cc91fc39bd4633eeb5cd","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Deprecate V1.1, add basic stuff for microversions"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Despite the fact that V1.1, V2 and V3 implemented by one module,"},{"line_number":10,"context_line":"microversions will be supported only for V2."},{"line_number":11,"context_line":"There are no reasons to keep V1.1, except backward"},{"line_number":12,"context_line":"compatibility, so we can\u0027t remove it. This version is marked as"},{"line_number":13,"context_line":"deprecated. Since implementation of V3 was stopped and it is not used"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9a80dd14_42c26535","line":10,"updated":"2015-03-17 04:42:36.000000000","message":"So V2 and V1.1 are implemented by the old V2 API code\n\nV2.1 and V2.1 with microversions support is implemented by the new nova api code. They are two a large extent quite separate. (with some common wsgi code)","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"25788d2caa48e4c68863f2882d415244e3d53600","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Deprecate V1.1, add basic stuff for microversions"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Despite the fact that V1.1, V2 and V3 implemented by one module,"},{"line_number":10,"context_line":"microversions will be supported only for V2."},{"line_number":11,"context_line":"There are no reasons to keep V1.1, except backward"},{"line_number":12,"context_line":"compatibility, so we can\u0027t remove it. This version is marked as"},{"line_number":13,"context_line":"deprecated. Since implementation of V3 was stopped and it is not used"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9a80dd14_e451e10e","line":10,"in_reply_to":"9a80dd14_42c26535","updated":"2015-03-20 16:02:30.000000000","message":"ok, i\u0027ll edit this sentence.","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"52c1a7f113e05fb4a1d7cc91fc39bd4633eeb5cd","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Despite the fact that V1.1, V2 and V3 implemented by one module,"},{"line_number":10,"context_line":"microversions will be supported only for V2."},{"line_number":11,"context_line":"There are no reasons to keep V1.1, except backward"},{"line_number":12,"context_line":"compatibility, so we can\u0027t remove it. This version is marked as"},{"line_number":13,"context_line":"deprecated. Since implementation of V3 was stopped and it is not used"},{"line_number":14,"context_line":"at all, we can remove it and all versioning mapping stuff."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9a80dd14_e2ea79ab","line":12,"updated":"2015-03-17 04:42:36.000000000","message":"Agreed. I think we can probably just remove v1.1 when we remove v2 (the old implementation) from Nova","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"52c1a7f113e05fb4a1d7cc91fc39bd4633eeb5cd","unresolved":false,"context_lines":[{"line_number":16,"context_line":"The basic microversioning stuff is implemented via"},{"line_number":17,"context_line":"X-OpenStack-Nova-API-Version header. Compute API version can be"},{"line_number":18,"context_line":"selected via --os-compute-api-version parameter."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Related bp: api-microversions"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"Change-Id: I0e6574ddaec11fdd053a49adb6b9de9056d0fbac"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9a80dd14_222011b0","line":19,"updated":"2015-03-17 04:42:36.000000000","message":"So perhaps I\u0027m a bit confused here, but I think we should have two separate flags. One can choose which entry from the service catalog to use (eg old Nova API code or the one from the service catalog which does support microversions).\n\nThen a second flag which says to use just try to use V2 (supply no header), or a a microversion (supply which a header which defines the version header). At the moment I\u0027m finding the automated determination a bit confusing","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"25788d2caa48e4c68863f2882d415244e3d53600","unresolved":false,"context_lines":[{"line_number":16,"context_line":"The basic microversioning stuff is implemented via"},{"line_number":17,"context_line":"X-OpenStack-Nova-API-Version header. Compute API version can be"},{"line_number":18,"context_line":"selected via --os-compute-api-version parameter."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Related bp: api-microversions"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"Change-Id: I0e6574ddaec11fdd053a49adb6b9de9056d0fbac"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"9a80dd14_69acea35","line":19,"in_reply_to":"9a80dd14_222011b0","updated":"2015-03-20 16:02:30.000000000","message":"Two options for enabling one thing? It can be helpful only when we will have more that two available endpoints.","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"}],"doc/source/conf.py":[{"author":{"_account_id":10224,"name":"Feodor Tersin","email":"ftersin@hotmail.com","username":"ftersin"},"change_message_id":"36e72f90b37f39811da7ec26aadcac6ace97f8b9","unresolved":false,"context_lines":[{"line_number":78,"context_line":"         \"limits\", \"networks\", \"quota_classes\", \"quotas\","},{"line_number":79,"context_line":"         \"security_group_rules\", \"security_groups\", \"services\","},{"line_number":80,"context_line":"         \"virtual_interfaces\", \"volume_snapshots\", \"volumes\", \"volume_types\"])"},{"line_number":81,"context_line":"gen_ref(\"v2\", \"Version 1.1, Version 2 API Reference\","},{"line_number":82,"context_line":"        [\"flavors\", \"images\", \"servers\", \"hosts\", \"agents\", \"aggregates\","},{"line_number":83,"context_line":"         \"availability_zones\", \"certs\", \"fixed_ips\", \"floating_ip_pools\","},{"line_number":84,"context_line":"         \"floating_ips\", \"hypervisors\", \"keypairs\", \"limits\", \"networks\","}],"source_content_type":"text/x-python","patch_set":15,"id":"9a80dd14_eb1640f1","line":81,"updated":"2015-03-13 14:38:06.000000000","message":"this looks very similar to the previous block, is that right?","commit_id":"33f439c1781806efa75078166c3ab1fece3592c6"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"6e525cd6c6b2aa817b3531fa33e3d8a5b5dbc026","unresolved":false,"context_lines":[{"line_number":78,"context_line":"         \"limits\", \"networks\", \"quota_classes\", \"quotas\","},{"line_number":79,"context_line":"         \"security_group_rules\", \"security_groups\", \"services\","},{"line_number":80,"context_line":"         \"virtual_interfaces\", \"volume_snapshots\", \"volumes\", \"volume_types\"])"},{"line_number":81,"context_line":"gen_ref(\"v2\", \"Version 1.1, Version 2 API Reference\","},{"line_number":82,"context_line":"        [\"flavors\", \"images\", \"servers\", \"hosts\", \"agents\", \"aggregates\","},{"line_number":83,"context_line":"         \"availability_zones\", \"certs\", \"fixed_ips\", \"floating_ip_pools\","},{"line_number":84,"context_line":"         \"floating_ips\", \"hypervisors\", \"keypairs\", \"limits\", \"networks\","}],"source_content_type":"text/x-python","patch_set":15,"id":"9a80dd14_eb02c00a","line":81,"in_reply_to":"9a80dd14_eb1640f1","updated":"2015-03-13 14:42:10.000000000","message":"oops, rebase finished with errors:)","commit_id":"33f439c1781806efa75078166c3ab1fece3592c6"}],"novaclient/api_versions.py":[{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"1c4370e60010d6cfc584835a97f7dc108fb03799","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        if type(self) is type(other):"},{"line_number":56,"context_line":"            return (self.major, self.minor) \u003c (other.major, other.minor)"},{"line_number":57,"context_line":"        else:"},{"line_number":58,"context_line":"            return False"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def __le__(self, other):"},{"line_number":61,"context_line":"        if type(self) is type(other):"}],"source_content_type":"text/x-python","patch_set":24,"id":"1a6ced46_81e5c939","line":58,"updated":"2015-03-25 16:36:44.000000000","message":"I suggest not having:\n\n    else:\n        return False\n\nand just have instead:\n\n    return False\n\nthere is no point in having else in this case. It will also make the code simpler / cleaner. :)","commit_id":"d7ee29f398c86f3206de8fc512a7a18473afa26f"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"1c4370e60010d6cfc584835a97f7dc108fb03799","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        if type(self) is type(other):"},{"line_number":62,"context_line":"            return (self.major, self.minor) \u003c\u003d (other.major, other.minor)"},{"line_number":63,"context_line":"        else:"},{"line_number":64,"context_line":"            return False"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def __eq__(self, other):"},{"line_number":67,"context_line":"        if type(self) is type(other):"}],"source_content_type":"text/x-python","patch_set":24,"id":"1a6ced46_a16725b6","line":64,"updated":"2015-03-25 16:36:44.000000000","message":"ditto","commit_id":"d7ee29f398c86f3206de8fc512a7a18473afa26f"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"1c4370e60010d6cfc584835a97f7dc108fb03799","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        if type(self) is type(other):"},{"line_number":68,"context_line":"            return (self.major, self.minor) \u003d\u003d (other.major, other.minor)"},{"line_number":69,"context_line":"        else:"},{"line_number":70,"context_line":"            return False"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def __ne__(self, other):"},{"line_number":73,"context_line":"        return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":24,"id":"1a6ced46_e10cbdef","line":70,"updated":"2015-03-25 16:36:44.000000000","message":"ditto","commit_id":"d7ee29f398c86f3206de8fc512a7a18473afa26f"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"1c4370e60010d6cfc584835a97f7dc108fb03799","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        if type(self) is type(other):"},{"line_number":77,"context_line":"            return (self.major, self.minor) \u003e (other.major, other.minor)"},{"line_number":78,"context_line":"        else:"},{"line_number":79,"context_line":"            return False"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def __ge__(self, other):"},{"line_number":82,"context_line":"        if type(self) is type(other):"}],"source_content_type":"text/x-python","patch_set":24,"id":"1a6ced46_2113350e","line":79,"updated":"2015-03-25 16:36:44.000000000","message":"ditto","commit_id":"d7ee29f398c86f3206de8fc512a7a18473afa26f"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"1c4370e60010d6cfc584835a97f7dc108fb03799","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        if type(self) is type(other):"},{"line_number":83,"context_line":"            return (self.major, self.minor) \u003e\u003d (other.major, other.minor)"},{"line_number":84,"context_line":"        else:"},{"line_number":85,"context_line":"            return False"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"# key is a deprecated version and value is an alternative version."},{"line_number":88,"context_line":"DEPRECATED_VERSIONS \u003d {\"1.1\": APIVersion(\"2\")}"}],"source_content_type":"text/x-python","patch_set":24,"id":"1a6ced46_61f8cdc3","line":85,"updated":"2015-03-25 16:36:44.000000000","message":"ditto","commit_id":"d7ee29f398c86f3206de8fc512a7a18473afa26f"},{"author":{"_account_id":10608,"name":"Matthew Edmonds","email":"edmondsw@us.ibm.com","username":"edmondsw"},"change_message_id":"167765ed32f362a852cf287bf26d7a96dad33597","unresolved":false,"context_lines":[{"line_number":22,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d {\"legacy\": \"2.0\","},{"line_number":26,"context_line":"                                  \"microversions\": \"2.1\"}"},{"line_number":27,"context_line":"LATEST_COMPUTE_API_MAJOR_VERSION \u003d \"2\""},{"line_number":28,"context_line":"# key is a deprecated version and value is an alternative version."}],"source_content_type":"text/x-python","patch_set":26,"id":"9aa53dc9_2eaa5771","line":25,"updated":"2015-04-06 14:32:57.000000000","message":"as commented under shell.py, this must be simply \"compute\" and all places this is used must be updated accordingly. The default IS \"compute\". How devstack sets up the service catalog has no bearing on that. Novaclient is not specific to devstack.","commit_id":"7c87d94bbe312081ef944b2fbd70c4dfaf959018"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"3e3ecc954280d3f62b17ddff2ac2476f77e2d59c","unresolved":false,"context_lines":[{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"def get_api_version(version_string):"},{"line_number":159,"context_line":"    version_string \u003d str(version_string)"},{"line_number":160,"context_line":"    if version_string in DEPRECATED_VERSIONS:"},{"line_number":161,"context_line":"        LOG.warning(_LW(\"Version %(deprecated_version)s is deprecated, using \""},{"line_number":162,"context_line":"                    \"alternative version %(alternative)s instead.\") %"}],"source_content_type":"text/x-python","patch_set":29,"id":"9aa53dc9_d7e8c57e","line":159,"updated":"2015-04-08 11:37:31.000000000","message":"Are we really need this line? Where can we request non-string api-version? \n\nAlso this line produce such inconsistence:\n\n\u003e\u003e\u003e api_versions_get_api_version(None)\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"novaclient/api_versions.py\", line 171, in get_api_version\n    return APIVersion(version_string)\n  File \"novaclient/api_versions.py\", line 52, in __init__\n    raise exceptions.UnsupportedVersion(msg)\nnovaclient.exceptions.UnsupportedVersion: Invalid format of client version \u0027None\u0027. Expected format \u0027X.Y\u0027, where X is a major part and Y is a minor part of version.\n\u003e\u003e\u003e \n\nWithout it it can be so:\n\n\u003e\u003e\u003e api_versions.get_api_version(None)\n\u003cAPIVersion: null\u003e","commit_id":"f18c42aec1b04c33d0a12a77f0e530e212bc72cd"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"9b91e07c8fc515ab466914388ba0cd54341fe96c","unresolved":false,"context_lines":[{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"def get_api_version(version_string):"},{"line_number":159,"context_line":"    version_string \u003d str(version_string)"},{"line_number":160,"context_line":"    if version_string in DEPRECATED_VERSIONS:"},{"line_number":161,"context_line":"        LOG.warning(_LW(\"Version %(deprecated_version)s is deprecated, using \""},{"line_number":162,"context_line":"                    \"alternative version %(alternative)s instead.\") %"}],"source_content_type":"text/x-python","patch_set":29,"id":"9aa53dc9_d95fd7e3","line":159,"in_reply_to":"9aa53dc9_7687bad7","updated":"2015-04-08 12:33:58.000000000","message":"Maybe you are right. Looks like sometimes it prevents from some mistakes\n\nAndrey, could you please fix argument name to be just \u0027version\u0027 instead of \u0027version_string\u0027 if you\u0027ll do next patch-set. It\u0027s quite misleading","commit_id":"f18c42aec1b04c33d0a12a77f0e530e212bc72cd"},{"author":{"_account_id":10224,"name":"Feodor Tersin","email":"ftersin@hotmail.com","username":"ftersin"},"change_message_id":"a1fc9c9a739e7371d8fc189471fdb4b095bcb517","unresolved":false,"context_lines":[{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"def get_api_version(version_string):"},{"line_number":159,"context_line":"    version_string \u003d str(version_string)"},{"line_number":160,"context_line":"    if version_string in DEPRECATED_VERSIONS:"},{"line_number":161,"context_line":"        LOG.warning(_LW(\"Version %(deprecated_version)s is deprecated, using \""},{"line_number":162,"context_line":"                    \"alternative version %(alternative)s instead.\") %"}],"source_content_type":"text/x-python","patch_set":29,"id":"9aa53dc9_7687bad7","line":159,"in_reply_to":"9aa53dc9_d7e8c57e","updated":"2015-04-08 12:22:52.000000000","message":"A version can definitely be specified as a number. See http://docs.openstack.org/developer/python-novaclient/api.html and ceilometer/nova_client for example.\n\nAs i understand you try to get a default version of novaclient. But this was not supported early.","commit_id":"f18c42aec1b04c33d0a12a77f0e530e212bc72cd"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"e4250968836ded9b07464fe07be497a8085a965d","unresolved":false,"context_lines":[{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"def get_api_version(version_string):"},{"line_number":159,"context_line":"    version_string \u003d str(version_string)"},{"line_number":160,"context_line":"    if version_string in DEPRECATED_VERSIONS:"},{"line_number":161,"context_line":"        LOG.warning(_LW(\"Version %(deprecated_version)s is deprecated, using \""},{"line_number":162,"context_line":"                    \"alternative version %(alternative)s instead.\") %"}],"source_content_type":"text/x-python","patch_set":29,"id":"9aa53dc9_191f7f60","line":159,"in_reply_to":"9aa53dc9_d7e8c57e","updated":"2015-04-08 12:27:50.000000000","message":"added additional check for None.","commit_id":"f18c42aec1b04c33d0a12a77f0e530e212bc72cd"},{"author":{"_account_id":10608,"name":"Matthew Edmonds","email":"edmondsw@us.ibm.com","username":"edmondsw"},"change_message_id":"64074a2d4f6c37b718fe7d05e9ab998092dcedfa","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    numbers that we need to do to implement microversions."},{"line_number":36,"context_line":"    \"\"\""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def __init__(self, version_str\u003dNone, latest\u003dFalse):"},{"line_number":39,"context_line":"        \"\"\"Create an API version object.\"\"\""},{"line_number":40,"context_line":"        self.ver_major \u003d None"},{"line_number":41,"context_line":"        self.ver_minor \u003d None"}],"source_content_type":"text/x-python","patch_set":31,"id":"7aaa499b_1b31140c","line":38,"updated":"2015-04-10 23:04:59.000000000","message":"if latest is True, this implementation makes version_str irrelevant. Why not just get rid of latest and pass \"latest\" as the value for version_str if you want the latest? Or at least check latest first, since that appears to take precedence, rather than waste time parsing version_str in a way you\u0027re not going to use.","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"db4c95225ecf218c193454f807b4a705f4104c21","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    numbers that we need to do to implement microversions."},{"line_number":36,"context_line":"    \"\"\""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def __init__(self, version_str\u003dNone, latest\u003dFalse):"},{"line_number":39,"context_line":"        \"\"\"Create an API version object.\"\"\""},{"line_number":40,"context_line":"        self.ver_major \u003d None"},{"line_number":41,"context_line":"        self.ver_minor \u003d None"}],"source_content_type":"text/x-python","patch_set":31,"id":"dac4157f_f0caf34e","line":38,"in_reply_to":"7aaa499b_1b31140c","updated":"2015-04-20 13:31:28.000000000","message":"Such implementation gives ability to set major version, so users can choose latest V2 or latest V3. Maybe it is not needed now, but in future... So if you are really against this implementation, I can change it.","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"b823d39ff1dab7c71dea29f991506db264ad37c0","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    numbers that we need to do to implement microversions."},{"line_number":36,"context_line":"    \"\"\""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def __init__(self, version_str\u003dNone, latest\u003dFalse):"},{"line_number":39,"context_line":"        \"\"\"Create an API version object.\"\"\""},{"line_number":40,"context_line":"        self.ver_major \u003d None"},{"line_number":41,"context_line":"        self.ver_minor \u003d None"}],"source_content_type":"text/x-python","patch_set":31,"id":"dac4157f_487d106d","line":38,"in_reply_to":"7aaa499b_1b31140c","updated":"2015-04-22 12:05:11.000000000","message":"changed to use only `version_str` var","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"d4ab12f158934ca407d487de39b4a33963fa3bbe","unresolved":false,"context_lines":[{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        if latest:"},{"line_number":55,"context_line":"            self.ver_major \u003d self.ver_major or LATEST_COMPUTE_API_MAJOR_VERSION"},{"line_number":56,"context_line":"            self.ver_minor \u003d float(\"inf\")"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def __str__(self):"},{"line_number":59,"context_line":"        \"\"\"Debug/Logging representation of object.\"\"\""}],"source_content_type":"text/x-python","patch_set":31,"id":"dac4157f_034069a4","line":56,"updated":"2015-04-20 19:56:11.000000000","message":"Current code related to \"latest\" is a little difficult, and it would make confuse in long term.\nIt is possible to raise LATEST_COMPUTE_API_MAJOR_VERSION and clients\u0027 python-novaclient version is different from nova\u0027s one in real world.\n\nso how about using keyword \"latest\" or something instead of LATEST_COMPUTE_API_MAJOR_VERSION and float(\u0027inf\u0027) ?","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"b823d39ff1dab7c71dea29f991506db264ad37c0","unresolved":false,"context_lines":[{"line_number":53,"context_line":""},{"line_number":54,"context_line":"        if latest:"},{"line_number":55,"context_line":"            self.ver_major \u003d self.ver_major or LATEST_COMPUTE_API_MAJOR_VERSION"},{"line_number":56,"context_line":"            self.ver_minor \u003d float(\"inf\")"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def __str__(self):"},{"line_number":59,"context_line":"        \"\"\"Debug/Logging representation of object.\"\"\""}],"source_content_type":"text/x-python","patch_set":31,"id":"dac4157f_6f7367e8","line":56,"in_reply_to":"dac4157f_034069a4","updated":"2015-04-22 12:05:11.000000000","message":"infinity helps to simplify comparison methods. But it looks I know how can I simplify this logic a bit.","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":10608,"name":"Matthew Edmonds","email":"edmondsw@us.ibm.com","username":"edmondsw"},"change_message_id":"64074a2d4f6c37b718fe7d05e9ab998092dcedfa","unresolved":false,"context_lines":[{"line_number":152,"context_line":"        \"\"\""},{"line_number":153,"context_line":"        if self.is_null():"},{"line_number":154,"context_line":"            raise ValueError"},{"line_number":155,"context_line":"        return \"%s.%s\" % (self.ver_major, self.ver_minor)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"def get_api_version(version_string):"}],"source_content_type":"text/x-python","patch_set":31,"id":"7aaa499b_7b2258bb","line":155,"updated":"2015-04-10 23:04:59.000000000","message":"\"2.inf\" when ver_minor \u003d\u003d float(\"inf\")? And I don\u0027t think the comment at the outset of the method holds true in that case.","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"db4c95225ecf218c193454f807b4a705f4104c21","unresolved":false,"context_lines":[{"line_number":152,"context_line":"        \"\"\""},{"line_number":153,"context_line":"        if self.is_null():"},{"line_number":154,"context_line":"            raise ValueError"},{"line_number":155,"context_line":"        return \"%s.%s\" % (self.ver_major, self.ver_minor)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"def get_api_version(version_string):"}],"source_content_type":"text/x-python","patch_set":31,"id":"7aaa499b_e5c65348","line":155,"in_reply_to":"7aaa499b_7b2258bb","updated":"2015-04-20 13:31:28.000000000","message":"\u003e \"2.inf\" when ver_minor \u003d\u003d float(\"inf\")? \n\nyes. why not? Maybe \"latest 2\" will be better?\n\n\u003e And I don\u0027t think the comment at the outset of the method holds true in that case.\n\nwill be fixed","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"b823d39ff1dab7c71dea29f991506db264ad37c0","unresolved":false,"context_lines":[{"line_number":152,"context_line":"        \"\"\""},{"line_number":153,"context_line":"        if self.is_null():"},{"line_number":154,"context_line":"            raise ValueError"},{"line_number":155,"context_line":"        return \"%s.%s\" % (self.ver_major, self.ver_minor)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"def get_api_version(version_string):"}],"source_content_type":"text/x-python","patch_set":31,"id":"dac4157f_af861fd9","line":155,"in_reply_to":"7aaa499b_e5c65348","updated":"2015-04-22 12:05:11.000000000","message":"\u003e \"2.inf\" when ver_minor \u003d\u003d float(\"inf\")? \n\nchanged to \"2.latest\"","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":6167,"name":"Ken\u0027ichi Ohmichi","email":"ken1ohmichi@gmail.com","username":"oomichi"},"change_message_id":"d4ab12f158934ca407d487de39b4a33963fa3bbe","unresolved":false,"context_lines":[{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    if api_version.is_latest():"},{"line_number":179,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d \"latest\""},{"line_number":180,"context_line":"    elif not api_version.is_null() and api_version.ver_minor !\u003d \"0\":"},{"line_number":181,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d api_version.get_string()"}],"source_content_type":"text/x-python","patch_set":31,"id":"dac4157f_3163db1c","line":180,"updated":"2015-04-20 19:56:11.000000000","message":"I feel\n\n elif not api_version.is_null():\n\nis enough here because current code doesn\u0027t work if major version raises like \"3.0\".","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"b823d39ff1dab7c71dea29f991506db264ad37c0","unresolved":false,"context_lines":[{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    if api_version.is_latest():"},{"line_number":179,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d \"latest\""},{"line_number":180,"context_line":"    elif not api_version.is_null() and api_version.ver_minor !\u003d \"0\":"},{"line_number":181,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d api_version.get_string()"}],"source_content_type":"text/x-python","patch_set":31,"id":"dac4157f_efa418a7","line":180,"in_reply_to":"dac4157f_3163db1c","updated":"2015-04-22 12:05:11.000000000","message":"`is_null`method will return True for \"2.0\" version, so we should check minor part:)","commit_id":"889cefd71cf41a8d5a5f1ef21a904fe9c54516a0"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"a1fc7510a99aec43de4f14f57c12f7a919d8b6a6","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def __lt__(self, other):"},{"line_number":78,"context_line":"        if not isinstance(other, APIVersion):"},{"line_number":79,"context_line":"            raise TypeError"},{"line_number":80,"context_line":"        if ((self.is_null() and other.is_null()) or"},{"line_number":81,"context_line":"                (not self.is_null() and other.is_null())):"},{"line_number":82,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":34,"id":"7a016987_57d46c1e","line":79,"updated":"2015-05-29 20:03:22.000000000","message":"I\u0027d prefer this be an instantiated exception.","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"e1c112a35d7d23ab9c9028d23acd5aa23bf0f416","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def __lt__(self, other):"},{"line_number":78,"context_line":"        if not isinstance(other, APIVersion):"},{"line_number":79,"context_line":"            raise TypeError"},{"line_number":80,"context_line":"        if ((self.is_null() and other.is_null()) or"},{"line_number":81,"context_line":"                (not self.is_null() and other.is_null())):"},{"line_number":82,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":34,"id":"fa32b979_daf39b07","line":79,"in_reply_to":"7a016987_57d46c1e","updated":"2015-06-25 14:00:38.000000000","message":"Done","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"a1fc7510a99aec43de4f14f57c12f7a919d8b6a6","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        if not isinstance(other, APIVersion):"},{"line_number":79,"context_line":"            raise TypeError"},{"line_number":80,"context_line":"        if ((self.is_null() and other.is_null()) or"},{"line_number":81,"context_line":"                (not self.is_null() and other.is_null())):"},{"line_number":82,"context_line":"            return False"},{"line_number":83,"context_line":"        elif self.is_null() and not other.is_null():"},{"line_number":84,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":34,"id":"7a016987_37957032","line":81,"updated":"2015-05-29 20:03:22.000000000","message":"This condition is equivalent to \"other.is_null()\".  Is that what is intended?  I\u0027d be tempted to always return False in all the comparison methods if either operand is \"is_null()\"…well, except maybe for __eq__()…","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"e1c112a35d7d23ab9c9028d23acd5aa23bf0f416","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        if not isinstance(other, APIVersion):"},{"line_number":79,"context_line":"            raise TypeError"},{"line_number":80,"context_line":"        if ((self.is_null() and other.is_null()) or"},{"line_number":81,"context_line":"                (not self.is_null() and other.is_null())):"},{"line_number":82,"context_line":"            return False"},{"line_number":83,"context_line":"        elif self.is_null() and not other.is_null():"},{"line_number":84,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":34,"id":"fa32b979_bd233157","line":81,"in_reply_to":"7a016987_37957032","updated":"2015-06-25 14:00:38.000000000","message":"\u003eI\u0027d be tempted to always return False in all the comparison methods if either operand is \"is_null()\"\n\nI\u0027d like the comparison way for int and None in py26/27(unfortunately, py3 doesn\u0027t support it):\n\nIn [1]: (1, 2) \u003c (None, None)\nOut[1]: False\n\nIn [2]: (1, 2) \u003e (None, None)\nOut[2]: True\n\n\nMaybe we should move from None to \"0\". It will simplify comparison methods a lot.","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"87b7a1f26647ee1d32b1dbfcc1e4dd58cb1f6eb9","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        if not isinstance(other, APIVersion):"},{"line_number":79,"context_line":"            raise TypeError"},{"line_number":80,"context_line":"        if ((self.is_null() and other.is_null()) or"},{"line_number":81,"context_line":"                (not self.is_null() and other.is_null())):"},{"line_number":82,"context_line":"            return False"},{"line_number":83,"context_line":"        elif self.is_null() and not other.is_null():"},{"line_number":84,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":34,"id":"fa32b979_51d3e903","line":81,"in_reply_to":"fa32b979_bd233157","updated":"2015-06-25 16:13:25.000000000","message":"Yeah, I really like that simplification…","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"275606ac450420de281857369f35bc70e8ac20b4","unresolved":false,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    if api_version.is_latest():"},{"line_number":177,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d \"latest\""},{"line_number":178,"context_line":"    elif not api_version.is_null() and api_version.ver_minor !\u003d \"0\":"},{"line_number":179,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d api_version.get_string()"}],"source_content_type":"text/x-python","patch_set":34,"id":"3afb71cf_5b7872f2","line":178,"updated":"2015-06-08 13:27:45.000000000","message":"Api version stores int value, so below check never fails:\n\napi_version.ver_minor !\u003d \"0\"","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"e1c112a35d7d23ab9c9028d23acd5aa23bf0f416","unresolved":false,"context_lines":[{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    if api_version.is_latest():"},{"line_number":177,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d \"latest\""},{"line_number":178,"context_line":"    elif not api_version.is_null() and api_version.ver_minor !\u003d \"0\":"},{"line_number":179,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d api_version.get_string()"}],"source_content_type":"text/x-python","patch_set":34,"id":"fa32b979_b2512164","line":178,"in_reply_to":"3afb71cf_5b7872f2","updated":"2015-06-25 14:00:38.000000000","message":"Done","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"401aa2acf68d7624ab70d035f54920f33ca41f15","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        \"\"\""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        if self.is_null():"},{"line_number":129,"context_line":"            raise ValueError"},{"line_number":130,"context_line":"        if max_version.is_null() and min_version.is_null():"},{"line_number":131,"context_line":"            return True"},{"line_number":132,"context_line":"        elif max_version.is_null():"}],"source_content_type":"text/x-python","patch_set":35,"id":"fa32b979_11048115","line":129,"updated":"2015-06-25 16:23:13.000000000","message":"This should also be instantiated…","commit_id":"2331c9842cb1f9dba07da273174c8a38d25405a8"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"8f3bf7d49c453cade6b80f95183faccf3cec6da5","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        \"\"\""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        if self.is_null():"},{"line_number":129,"context_line":"            raise ValueError"},{"line_number":130,"context_line":"        if max_version.is_null() and min_version.is_null():"},{"line_number":131,"context_line":"            return True"},{"line_number":132,"context_line":"        elif max_version.is_null():"}],"source_content_type":"text/x-python","patch_set":36,"id":"fa32b979_14f0ef8f","line":129,"updated":"2015-06-25 16:28:57.000000000","message":"Still needs to be instantiated…","commit_id":"fa949a2a53d9ba077f4061349c9af624bb2d13b6"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a298926014c82ddf8af71c3666ffc0aba2a24e92","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    def is_latest(self):"},{"line_number":79,"context_line":"        return self.ver_minor \u003d\u003d float(\"inf\")"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def __lt__(self, other):"},{"line_number":82,"context_line":"        if not isinstance(other, APIVersion):"},{"line_number":83,"context_line":"            raise TypeError(_type_error_msg % {\"other\": other,"},{"line_number":84,"context_line":"                                               \"cls\": self.__class__})"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"        return ((self.ver_major, self.ver_minor) \u003c"},{"line_number":87,"context_line":"                (other.ver_major, other.ver_minor))"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def __eq__(self, other):"},{"line_number":90,"context_line":"        if not isinstance(other, APIVersion):"},{"line_number":91,"context_line":"            raise TypeError(_type_error_msg % {\"other\": other,"},{"line_number":92,"context_line":"                                               \"cls\": self.__class__})"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        return ((self.ver_major, self.ver_minor) \u003d\u003d"},{"line_number":95,"context_line":"                (other.ver_major, other.ver_minor))"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def __gt__(self, other):"},{"line_number":98,"context_line":"        if not isinstance(other, APIVersion):"},{"line_number":99,"context_line":"            raise TypeError(_type_error_msg % {\"other\": other,"},{"line_number":100,"context_line":"                                               \"cls\": self.__class__})"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"        return ((self.ver_major, self.ver_minor) \u003e"},{"line_number":103,"context_line":"                (other.ver_major, other.ver_minor))"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def __le__(self, other):"},{"line_number":106,"context_line":"        return self \u003c other or self \u003d\u003d other"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    def __ne__(self, other):"},{"line_number":109,"context_line":"        return not self.__eq__(other)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def __ge__(self, other):"},{"line_number":112,"context_line":"        return self \u003e other or self \u003d\u003d other"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def matches(self, min_version, max_version):"},{"line_number":115,"context_line":"        \"\"\"Returns whether the version object represents a version"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_15c0707b","line":112,"range":{"start_line":81,"start_character":0,"end_line":112,"end_character":44},"updated":"2015-07-07 22:19:50.000000000","message":"Is there a particular reason you didn\u0027t overload __cmp__ instead of all of these, as seen in the Nova implementation [1]?\n\n[1] https://github.com/openstack/nova/blob/578bafe/nova/api/openstack/api_version_request.py#L99-L103","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"c770b654ec15089cba52081d66353a34d9f7abc8","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        return not self.__eq__(other)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def __ge__(self, other):"},{"line_number":112,"context_line":"        return self \u003e other or self \u003d\u003d other"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def matches(self, min_version, max_version):"},{"line_number":115,"context_line":"        \"\"\"Returns whether the version object represents a version"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_e5ee62ec","line":112,"in_reply_to":"ba3cc151_15c0707b","updated":"2015-07-08 09:29:14.000000000","message":"Also, commit message include this information:)","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"05f49293d1c1cf866fa890ec134fa276ce5004f3","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        return not self.__eq__(other)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def __ge__(self, other):"},{"line_number":112,"context_line":"        return self \u003e other or self \u003d\u003d other"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def matches(self, min_version, max_version):"},{"line_number":115,"context_line":"        \"\"\"Returns whether the version object represents a version"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_f30aba25","line":112,"in_reply_to":"ba3cc151_15c0707b","updated":"2015-07-08 00:55:18.000000000","message":"cmp is a py2* feature and Python 3 doesn\u0027t support it. Btw, I have a patch to nova with rewriting comparison methods- https://review.openstack.org/#/c/169292/","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"7caed0c5826b5b7c5c7943dd03c8308f58953ea7","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        return not self.__eq__(other)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def __ge__(self, other):"},{"line_number":112,"context_line":"        return self \u003e other or self \u003d\u003d other"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def matches(self, min_version, max_version):"},{"line_number":115,"context_line":"        \"\"\"Returns whether the version object represents a version"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_25642320","line":112,"in_reply_to":"ba3cc151_e5ee62ec","updated":"2015-07-08 22:18:05.000000000","message":"Oh, sorry I missed it.","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a298926014c82ddf8af71c3666ffc0aba2a24e92","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        greater than or equal to the minimum version and less than"},{"line_number":117,"context_line":"        or equal to the maximum version."},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        @param min_version: Minimum acceptable version."},{"line_number":120,"context_line":"        @param max_version: Maximum acceptable version."},{"line_number":121,"context_line":"        @returns: boolean"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_a6fcf93e","line":119,"range":{"start_line":119,"start_character":8,"end_line":119,"end_character":14},"updated":"2015-07-07 22:19:50.000000000","message":"I think this has to be :param to render correctly","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"c770b654ec15089cba52081d66353a34d9f7abc8","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        greater than or equal to the minimum version and less than"},{"line_number":117,"context_line":"        or equal to the maximum version."},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        @param min_version: Minimum acceptable version."},{"line_number":120,"context_line":"        @param max_version: Maximum acceptable version."},{"line_number":121,"context_line":"        @returns: boolean"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_02ed7cb6","line":119,"in_reply_to":"ba3cc151_a6fcf93e","updated":"2015-07-08 09:29:14.000000000","message":"Done","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a298926014c82ddf8af71c3666ffc0aba2a24e92","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        or equal to the maximum version."},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        @param min_version: Minimum acceptable version."},{"line_number":120,"context_line":"        @param max_version: Maximum acceptable version."},{"line_number":121,"context_line":"        @returns: boolean"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        If min_version is null then there is no minimum limit."}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_66bcb16c","line":120,"range":{"start_line":120,"start_character":8,"end_line":120,"end_character":14},"updated":"2015-07-07 22:19:50.000000000","message":"Ditto","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"c770b654ec15089cba52081d66353a34d9f7abc8","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        or equal to the maximum version."},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        @param min_version: Minimum acceptable version."},{"line_number":120,"context_line":"        @param max_version: Maximum acceptable version."},{"line_number":121,"context_line":"        @returns: boolean"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        If min_version is null then there is no minimum limit."}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_a22cd002","line":120,"in_reply_to":"ba3cc151_66bcb16c","updated":"2015-07-08 09:29:14.000000000","message":"Done","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a298926014c82ddf8af71c3666ffc0aba2a24e92","unresolved":false,"context_lines":[{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        @param min_version: Minimum acceptable version."},{"line_number":120,"context_line":"        @param max_version: Maximum acceptable version."},{"line_number":121,"context_line":"        @returns: boolean"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        If min_version is null then there is no minimum limit."},{"line_number":124,"context_line":"        If max_version is null then there is no maximum limit."}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_e689a1cb","line":121,"range":{"start_line":121,"start_character":8,"end_line":121,"end_character":16},"updated":"2015-07-07 22:19:50.000000000","message":"I think this has to be :returns: to render correctly","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"c770b654ec15089cba52081d66353a34d9f7abc8","unresolved":false,"context_lines":[{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        @param min_version: Minimum acceptable version."},{"line_number":120,"context_line":"        @param max_version: Maximum acceptable version."},{"line_number":121,"context_line":"        @returns: boolean"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        If min_version is null then there is no minimum limit."},{"line_number":124,"context_line":"        If max_version is null then there is no maximum limit."}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_c231d45b","line":121,"in_reply_to":"ba3cc151_e689a1cb","updated":"2015-07-08 09:29:14.000000000","message":"Done","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a298926014c82ddf8af71c3666ffc0aba2a24e92","unresolved":false,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    if api_version.is_latest():"},{"line_number":170,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d \"latest\""},{"line_number":171,"context_line":"    elif not api_version.is_null() and api_version.ver_minor !\u003d 0:"},{"line_number":172,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d api_version.get_string()"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_0026f0cd","line":171,"range":{"start_line":171,"start_character":39,"end_line":171,"end_character":65},"updated":"2015-07-07 22:19:50.000000000","message":"Why isn\u0027t minor version 0 allowed? I understand that 2.0 doesn\u0027t support microversions but what about the future 3.0?","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"c770b654ec15089cba52081d66353a34d9f7abc8","unresolved":false,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    if api_version.is_latest():"},{"line_number":170,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d \"latest\""},{"line_number":171,"context_line":"    elif not api_version.is_null() and api_version.ver_minor !\u003d 0:"},{"line_number":172,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d api_version.get_string()"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_c5647eba","line":171,"in_reply_to":"ba3cc151_0026f0cd","updated":"2015-07-08 09:29:14.000000000","message":"The header should be specified only when microversion is used. Since X.0 is a main version of X, it doesn\u0027t require header.","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"cbb8f079baff09d4b2b0e2c878457820b60ade3a","unresolved":false,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    if api_version.is_latest():"},{"line_number":170,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d \"latest\""},{"line_number":171,"context_line":"    elif not api_version.is_null() and api_version.ver_minor !\u003d 0:"},{"line_number":172,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d api_version.get_string()"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_07a0dc40","line":171,"in_reply_to":"ba3cc151_055c7f7b","updated":"2015-07-09 13:32:19.000000000","message":"\u003eAre you saying that in future versions, the \"stable\" version will always be X.0?\n\nI suppose so.","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"7caed0c5826b5b7c5c7943dd03c8308f58953ea7","unresolved":false,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    if api_version.is_latest():"},{"line_number":170,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d \"latest\""},{"line_number":171,"context_line":"    elif not api_version.is_null() and api_version.ver_minor !\u003d 0:"},{"line_number":172,"context_line":"        headers[\"X-OpenStack-Nova-API-Version\"] \u003d api_version.get_string()"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_055c7f7b","line":171,"in_reply_to":"ba3cc151_c5647eba","updated":"2015-07-08 22:18:05.000000000","message":"Hm, okay. I guess we don\u0027t have a use case [1] for this combination. I was thinking about how if we omit the version header, Nova will use the current \"stable\" version. Right now, that would be 2.1, if we send a request to \"new Nova\" without version header, we get back 2.1. Are you saying that in future versions, the \"stable\" version will always be X.0?\n\n[1] http://specs.openstack.org/openstack/nova-specs/specs/liberty/approved/novaclient-api-microversions.html#use-cases","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"}],"novaclient/client.py":[{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"3a2d51e6bab388176c8aef9ceb6877f39f4192ff","unresolved":false,"context_lines":[{"line_number":425,"context_line":"            del kwargs[\u0027body\u0027]"},{"line_number":426,"context_line":"        if self.api_version and self.api_version[1]:"},{"line_number":427,"context_line":"            kwargs[\u0027headers\u0027][\u0027X-OpenStack-Compute-API-Version\u0027] \u003d \\"},{"line_number":428,"context_line":"                \u0027.\u0027.join(self.api_version)"},{"line_number":429,"context_line":"        if self.timeout is not None:"},{"line_number":430,"context_line":"            kwargs.setdefault(\u0027timeout\u0027, self.timeout)"},{"line_number":431,"context_line":"        kwargs[\u0027verify\u0027] \u003d self.verify_cert"}],"source_content_type":"text/x-python","patch_set":1,"id":"da86d52c_cf8c5f38","line":428,"updated":"2015-02-03 17:03:48.000000000","message":"If possible, please find a way to eliminate the backslash continuation.  For instance:\n\n    vers \u003d \u0027.\u0027.join(self.api_version)\n    kwargs[\u0027headers\u0027][\u0027X-OpenStack-Compute-API-Version\u0027] \u003d vers\n\nAn alternative may be to refactor this method like so:\n\n    kwargs.setdefault(\u0027headers\u0027, kwargs.get(\u0027headers\u0027, {}))\n    headers \u003d kwargs[\u0027headers\u0027]\n\nAnd then use \"headers\" in place of \"kwargs[\u0027headers\u0027]\"","commit_id":"43468132b92049f22ef04835f2e84291d39254a1"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"30b0dc3aeb71a358db4782ef84665f4f6e447eaf","unresolved":false,"context_lines":[{"line_number":425,"context_line":"            del kwargs[\u0027body\u0027]"},{"line_number":426,"context_line":"        if self.api_version and self.api_version[1]:"},{"line_number":427,"context_line":"            kwargs[\u0027headers\u0027][\u0027X-OpenStack-Compute-API-Version\u0027] \u003d \\"},{"line_number":428,"context_line":"                \u0027.\u0027.join(self.api_version)"},{"line_number":429,"context_line":"        if self.timeout is not None:"},{"line_number":430,"context_line":"            kwargs.setdefault(\u0027timeout\u0027, self.timeout)"},{"line_number":431,"context_line":"        kwargs[\u0027verify\u0027] \u003d self.verify_cert"}],"source_content_type":"text/x-python","patch_set":1,"id":"da86d52c_d80a3d25","line":428,"in_reply_to":"da86d52c_cf8c5f38","updated":"2015-02-04 17:45:31.000000000","message":"Done","commit_id":"43468132b92049f22ef04835f2e84291d39254a1"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"3a2d51e6bab388176c8aef9ceb6877f39f4192ff","unresolved":false,"context_lines":[{"line_number":778,"context_line":""},{"line_number":779,"context_line":""},{"line_number":780,"context_line":"def get_client_class(version):"},{"line_number":781,"context_line":"    warnings.warn(\"Function \u0027%(deprecated_func)s\u0027 is deprecated. \""},{"line_number":782,"context_line":"                  \"You should use \u0027%(correct_func)s\u0027.\" %"},{"line_number":783,"context_line":"                  {\"deprecated_func\": get_client_class.__name__,"},{"line_number":784,"context_line":"                   \"correct_func\": Client.__name__})"}],"source_content_type":"text/x-python","patch_set":1,"id":"da86d52c_0f3af735","line":781,"updated":"2015-02-03 17:03:48.000000000","message":"I believe there\u0027s an oslo library that incorporates deprecation decorators; I have a slight preference that you use that in place of this.","commit_id":"43468132b92049f22ef04835f2e84291d39254a1"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"30b0dc3aeb71a358db4782ef84665f4f6e447eaf","unresolved":false,"context_lines":[{"line_number":778,"context_line":""},{"line_number":779,"context_line":""},{"line_number":780,"context_line":"def get_client_class(version):"},{"line_number":781,"context_line":"    warnings.warn(\"Function \u0027%(deprecated_func)s\u0027 is deprecated. \""},{"line_number":782,"context_line":"                  \"You should use \u0027%(correct_func)s\u0027.\" %"},{"line_number":783,"context_line":"                  {\"deprecated_func\": get_client_class.__name__,"},{"line_number":784,"context_line":"                   \"correct_func\": Client.__name__})"}],"source_content_type":"text/x-python","patch_set":1,"id":"da86d52c_9b5b5ff5","line":781,"in_reply_to":"da86d52c_0f3af735","updated":"2015-02-04 17:45:31.000000000","message":"Yeah, there is a specific decorator in oslo-incubator[1], but it works only with openstack releases[2], not with library version, so it seems we can\u0027t use it in clients:(\n\nBtw, I found that this function is needed for some cases in other openstack projects, so we should keep it.\n\n[1] - https://github.com/openstack/oslo-incubator/blob/master/openstack/common/versionutils.py#L42\n[2] - https://github.com/openstack/oslo-incubator/blob/master/openstack/common/versionutils.py#L87-L97","commit_id":"43468132b92049f22ef04835f2e84291d39254a1"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"d5bb2f5ab48a8c0ed37fe6799038972afa38ffee","unresolved":false,"context_lines":[{"line_number":795,"context_line":"            \"\u0027%(deprecated_version)s\u0027 version is deprecated, \""},{"line_number":796,"context_line":"            \"contrib modules from V%(alternative)s will be used \""},{"line_number":797,"context_line":"            \"instead.\" % {\"deprecated_version\": version,"},{"line_number":798,"context_line":"                          \"alternative\": vers})"},{"line_number":799,"context_line":"    else:"},{"line_number":800,"context_line":"        vers \u003d version"},{"line_number":801,"context_line":"    return vers"}],"source_content_type":"text/x-python","patch_set":2,"id":"da86d52c_cff98d81","line":798,"updated":"2015-02-04 17:41:06.000000000","message":"OK, that\u0027s clearer…","commit_id":"19515aebd23f907e88359076891a8d774c4f99fc"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"eed663cbc193107405ff936f41b2d685e12a12ca","unresolved":false,"context_lines":[{"line_number":51,"context_line":"from novaclient import service_catalog"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"DEPRECATED_VERSIONS \u003d [\"1.1\", \"3\"]"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"class TCPKeepAliveAdapter(adapters.HTTPAdapter):"}],"source_content_type":"text/x-python","patch_set":4,"id":"da86d52c_1b32eb5e","line":54,"updated":"2015-02-05 12:25:45.000000000","message":"is \u00273\u0027 really deprecated? I think it\u0027s not released? \n\nguess 1.1 here will be sufficient","commit_id":"2a138747ac64546df491712b88d79eb7488e2ebf"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"40c2b32ce40ba5df5c9f80c2c33743fc3511c1f2","unresolved":false,"context_lines":[{"line_number":51,"context_line":"from novaclient import service_catalog"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"DEPRECATED_VERSIONS \u003d [\"1.1\", \"3\"]"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"class TCPKeepAliveAdapter(adapters.HTTPAdapter):"}],"source_content_type":"text/x-python","patch_set":4,"id":"da86d52c_ed455843","line":54,"in_reply_to":"da86d52c_1b32eb5e","updated":"2015-02-05 13:02:01.000000000","message":"V3 was implemented and supported by novaclient. I think it was not used by anyone, but, imo, we should mark it as deprecated, just for compliance with generally accepted practices (first mark/deprecate, then delete).","commit_id":"2a138747ac64546df491712b88d79eb7488e2ebf"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"eac393d4a42d0b401cdfa195f9ed15f472ab02d4","unresolved":false,"context_lines":[{"line_number":51,"context_line":"from novaclient import service_catalog"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"DEPRECATED_VERSIONS \u003d [\"1.1\", \"3\"]"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"class TCPKeepAliveAdapter(adapters.HTTPAdapter):"}],"source_content_type":"text/x-python","patch_set":4,"id":"da86d52c_8b6900fb","line":54,"in_reply_to":"da86d52c_ba1ff459","updated":"2015-02-06 09:47:06.000000000","message":"okey, I\u0027ll remove it","commit_id":"2a138747ac64546df491712b88d79eb7488e2ebf"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"1610e91927197fc601143d6fbde483eaf584a041","unresolved":false,"context_lines":[{"line_number":51,"context_line":"from novaclient import service_catalog"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"DEPRECATED_VERSIONS \u003d [\"1.1\", \"3\"]"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"class TCPKeepAliveAdapter(adapters.HTTPAdapter):"}],"source_content_type":"text/x-python","patch_set":4,"id":"da86d52c_ba1ff459","line":54,"in_reply_to":"da86d52c_ed455843","updated":"2015-02-06 06:33:37.000000000","message":"hrm it was always left as state \"experimental\" and never made \"current\" so I think we can safely just pretend it never existed","commit_id":"2a138747ac64546df491712b88d79eb7488e2ebf"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"1610e91927197fc601143d6fbde483eaf584a041","unresolved":false,"context_lines":[{"line_number":781,"context_line":""},{"line_number":782,"context_line":""},{"line_number":783,"context_line":"def _check_versions(version):"},{"line_number":784,"context_line":"    supported_versions \u003d [\"1.1\", \"2\", \"3\"]"},{"line_number":785,"context_line":""},{"line_number":786,"context_line":"    if version not in supported_versions:"},{"line_number":787,"context_line":"        msg \u003d _(\"Invalid client version \u0027%(version)s\u0027. Must be one of: \""}],"source_content_type":"text/x-python","patch_set":4,"id":"da86d52c_ba6d34ce","line":784,"updated":"2015-02-06 06:33:37.000000000","message":"has it ever been valid to request 1.1? I don\u0027t think there is any distinguishing between 1.1 and 2 in the nova server code - maybe there was some keystone registry/novaclient interaction\n\nAlso v3 doesn\u0027t really exist as it was before now as some of it was reverted to support v2 running on v2.1 (which is the former v3 code)","commit_id":"2a138747ac64546df491712b88d79eb7488e2ebf"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"eac393d4a42d0b401cdfa195f9ed15f472ab02d4","unresolved":false,"context_lines":[{"line_number":781,"context_line":""},{"line_number":782,"context_line":""},{"line_number":783,"context_line":"def _check_versions(version):"},{"line_number":784,"context_line":"    supported_versions \u003d [\"1.1\", \"2\", \"3\"]"},{"line_number":785,"context_line":""},{"line_number":786,"context_line":"    if version not in supported_versions:"},{"line_number":787,"context_line":"        msg \u003d _(\"Invalid client version \u0027%(version)s\u0027. Must be one of: \""}],"source_content_type":"text/x-python","patch_set":4,"id":"da86d52c_8b6d7fce","line":784,"in_reply_to":"da86d52c_ba6d34ce","updated":"2015-02-06 09:47:06.000000000","message":"Few days ago(https://review.openstack.org/#/c/149006/), V1.1 was a default api version in novaclient, so I propose to keep it for now.","commit_id":"2a138747ac64546df491712b88d79eb7488e2ebf"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"1610e91927197fc601143d6fbde483eaf584a041","unresolved":false,"context_lines":[{"line_number":819,"context_line":"    if not version.startswith(\"2.\"):"},{"line_number":820,"context_line":"        api_version \u003d [_check_versions(version), None]"},{"line_number":821,"context_line":"    else:"},{"line_number":822,"context_line":"        api_version \u003d version.split(\".\", 1)"},{"line_number":823,"context_line":""},{"line_number":824,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":825,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"}],"source_content_type":"text/x-python","patch_set":4,"id":"da86d52c_1a49e030","line":822,"updated":"2015-02-06 06:33:37.000000000","message":"So the server will catch it, but versions like 2.01 are not valid","commit_id":"2a138747ac64546df491712b88d79eb7488e2ebf"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"eac393d4a42d0b401cdfa195f9ed15f472ab02d4","unresolved":false,"context_lines":[{"line_number":819,"context_line":"    if not version.startswith(\"2.\"):"},{"line_number":820,"context_line":"        api_version \u003d [_check_versions(version), None]"},{"line_number":821,"context_line":"    else:"},{"line_number":822,"context_line":"        api_version \u003d version.split(\".\", 1)"},{"line_number":823,"context_line":""},{"line_number":824,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":825,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"}],"source_content_type":"text/x-python","patch_set":4,"id":"da86d52c_6b7f6be0","line":822,"in_reply_to":"da86d52c_1a49e030","updated":"2015-02-06 09:47:06.000000000","message":"okey, I will use your regexp:)","commit_id":"2a138747ac64546df491712b88d79eb7488e2ebf"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"ca159b937bc27df805d3ad83ad8019387e2c5fd7","unresolved":false,"context_lines":[{"line_number":796,"context_line":"                \"instead.\" % {\"deprecated_version\": version,"},{"line_number":797,"context_line":"                              \"alternative\": 2})"},{"line_number":798,"context_line":"        return \"2\", None"},{"line_number":799,"context_line":"    elif version.find(\".\") !\u003d -1:"},{"line_number":800,"context_line":"        versions \u003d re.findall(r\"^([1-9]\\d*)\\.([1-9]\\d*|0)$\", version)"},{"line_number":801,"context_line":"        if not versions:"},{"line_number":802,"context_line":"            msg \u003d _(\"Invalid format of client version \u0027%s\u0027.\") % version"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_dd63d0ae","line":799,"updated":"2015-02-12 16:39:08.000000000","message":"I would advocate for:\n\n    elif \u0027.\u0027 in version:\n\nThat would be a bit clearer.","commit_id":"1ac3e69d24d5009819019a8a161e7864e973c009"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"67102a515829f5a850779b06327a6a87367ba624","unresolved":false,"context_lines":[{"line_number":796,"context_line":"                \"instead.\" % {\"deprecated_version\": version,"},{"line_number":797,"context_line":"                              \"alternative\": 2})"},{"line_number":798,"context_line":"        return \"2\", None"},{"line_number":799,"context_line":"    elif version.find(\".\") !\u003d -1:"},{"line_number":800,"context_line":"        versions \u003d re.findall(r\"^([1-9]\\d*)\\.([1-9]\\d*|0)$\", version)"},{"line_number":801,"context_line":"        if not versions:"},{"line_number":802,"context_line":"            msg \u003d _(\"Invalid format of client version \u0027%s\u0027.\") % version"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_c0c844aa","line":799,"in_reply_to":"da86d52c_dd63d0ae","updated":"2015-02-12 17:35:55.000000000","message":"Done","commit_id":"1ac3e69d24d5009819019a8a161e7864e973c009"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"ca159b937bc27df805d3ad83ad8019387e2c5fd7","unresolved":false,"context_lines":[{"line_number":801,"context_line":"        if not versions:"},{"line_number":802,"context_line":"            msg \u003d _(\"Invalid format of client version \u0027%s\u0027.\") % version"},{"line_number":803,"context_line":"            raise exceptions.UnsupportedVersion(msg)"},{"line_number":804,"context_line":"        return versions[0]"},{"line_number":805,"context_line":"    elif version \u003d\u003d \"latest\":"},{"line_number":806,"context_line":"        return \"2\", \"latest\""},{"line_number":807,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_1dad689b","line":804,"updated":"2015-02-12 16:39:08.000000000","message":"One of these returns is not like the others.  Although I\u0027ve confirmed that this does indeed return a 2-tuple, I\u0027d strongly suggest including a comment explaining that it does.  For that matter, this function would strongly benefit from a docstring explaining its purpose…","commit_id":"1ac3e69d24d5009819019a8a161e7864e973c009"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"67102a515829f5a850779b06327a6a87367ba624","unresolved":false,"context_lines":[{"line_number":801,"context_line":"        if not versions:"},{"line_number":802,"context_line":"            msg \u003d _(\"Invalid format of client version \u0027%s\u0027.\") % version"},{"line_number":803,"context_line":"            raise exceptions.UnsupportedVersion(msg)"},{"line_number":804,"context_line":"        return versions[0]"},{"line_number":805,"context_line":"    elif version \u003d\u003d \"latest\":"},{"line_number":806,"context_line":"        return \"2\", \"latest\""},{"line_number":807,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_e0d2a8cf","line":804,"in_reply_to":"da86d52c_1dad689b","updated":"2015-02-12 17:35:55.000000000","message":"Done","commit_id":"1ac3e69d24d5009819019a8a161e7864e973c009"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"ca159b937bc27df805d3ad83ad8019387e2c5fd7","unresolved":false,"context_lines":[{"line_number":818,"context_line":""},{"line_number":819,"context_line":""},{"line_number":820,"context_line":"def get_client_class(version):"},{"line_number":821,"context_line":"    vers, _ \u003d _check_versions(version)"},{"line_number":822,"context_line":""},{"line_number":823,"context_line":"    return importutils.import_class(\"novaclient.v%s.client.Client\" % vers)"},{"line_number":824,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_3dd06c1e","line":821,"updated":"2015-02-12 16:39:08.000000000","message":"I highly recommend avoiding the use of bare \"_\" for throw-away variables.  Instead, use an \u0027_\u0027-prefix variable name, e.g., \"_minor\"","commit_id":"1ac3e69d24d5009819019a8a161e7864e973c009"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"67102a515829f5a850779b06327a6a87367ba624","unresolved":false,"context_lines":[{"line_number":818,"context_line":""},{"line_number":819,"context_line":""},{"line_number":820,"context_line":"def get_client_class(version):"},{"line_number":821,"context_line":"    vers, _ \u003d _check_versions(version)"},{"line_number":822,"context_line":""},{"line_number":823,"context_line":"    return importutils.import_class(\"novaclient.v%s.client.Client\" % vers)"},{"line_number":824,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_a0d51044","line":821,"in_reply_to":"da86d52c_3dd06c1e","updated":"2015-02-12 17:35:55.000000000","message":"Done","commit_id":"1ac3e69d24d5009819019a8a161e7864e973c009"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"8378253c27d2f6a89837ffca10ce6ec1584a87ae","unresolved":false,"context_lines":[{"line_number":545,"context_line":"        if resp.status_code \u003d\u003d 200 or resp.status_code \u003d\u003d 201:"},{"line_number":546,"context_line":"            try:"},{"line_number":547,"context_line":"                self.auth_url \u003d url"},{"line_number":548,"context_line":"                self.service_catalog \u003d service_catalog.ServiceCatalog(body)"},{"line_number":549,"context_line":"                if extract_token:"},{"line_number":550,"context_line":"                    self.auth_token \u003d self.service_catalog.get_token()"},{"line_number":551,"context_line":"                    self.tenant_id \u003d self.service_catalog.get_tenant_id()"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_e6b1e0e0","line":548,"updated":"2015-02-12 17:53:41.000000000","message":"Out of scope of this patch?","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"6f9efe9f210b2fd1b3e12d293c0ac3176c181979","unresolved":false,"context_lines":[{"line_number":545,"context_line":"        if resp.status_code \u003d\u003d 200 or resp.status_code \u003d\u003d 201:"},{"line_number":546,"context_line":"            try:"},{"line_number":547,"context_line":"                self.auth_url \u003d url"},{"line_number":548,"context_line":"                self.service_catalog \u003d service_catalog.ServiceCatalog(body)"},{"line_number":549,"context_line":"                if extract_token:"},{"line_number":550,"context_line":"                    self.auth_token \u003d self.service_catalog.get_token()"},{"line_number":551,"context_line":"                    self.tenant_id \u003d self.service_catalog.get_tenant_id()"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_f53163ee","line":548,"in_reply_to":"da86d52c_de03aa0d","updated":"2015-02-13 12:17:08.000000000","message":"Agree to leave it as it is","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"784547d1ee98a288f7f112053c421064348cf790","unresolved":false,"context_lines":[{"line_number":545,"context_line":"        if resp.status_code \u003d\u003d 200 or resp.status_code \u003d\u003d 201:"},{"line_number":546,"context_line":"            try:"},{"line_number":547,"context_line":"                self.auth_url \u003d url"},{"line_number":548,"context_line":"                self.service_catalog \u003d service_catalog.ServiceCatalog(body)"},{"line_number":549,"context_line":"                if extract_token:"},{"line_number":550,"context_line":"                    self.auth_token \u003d self.service_catalog.get_token()"},{"line_number":551,"context_line":"                    self.tenant_id \u003d self.service_catalog.get_tenant_id()"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_8bb49f82","line":548,"in_reply_to":"da86d52c_e6b1e0e0","updated":"2015-02-12 23:07:09.000000000","message":"yes, but I think it\u0027s a nit and this change not deserve a -1","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"0088b67e82582bee1fb72fa9a61ac8cd5115fd6e","unresolved":false,"context_lines":[{"line_number":545,"context_line":"        if resp.status_code \u003d\u003d 200 or resp.status_code \u003d\u003d 201:"},{"line_number":546,"context_line":"            try:"},{"line_number":547,"context_line":"                self.auth_url \u003d url"},{"line_number":548,"context_line":"                self.service_catalog \u003d service_catalog.ServiceCatalog(body)"},{"line_number":549,"context_line":"                if extract_token:"},{"line_number":550,"context_line":"                    self.auth_token \u003d self.service_catalog.get_token()"},{"line_number":551,"context_line":"                    self.tenant_id \u003d self.service_catalog.get_tenant_id()"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_de03aa0d","line":548,"in_reply_to":"da86d52c_e6b1e0e0","updated":"2015-02-13 07:55:02.000000000","message":"yes, this out of scope, but I do it here, because new hacking check marks such lines like wrong(H904  Wrap long lines in parentheses instead of a backslash) and, since I\u0027m already changed something in this module, it would be nice(as for me) to fix this issue too.","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"8378253c27d2f6a89837ffca10ce6ec1584a87ae","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_66a6d0ac","line":839,"updated":"2015-02-12 17:53:41.000000000","message":"Can we left here existent logic and just call get_client_class instead of code duplication","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"be381dea89b49324ce33bf48890edc87232f39ca","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_e31d2ec0","line":839,"in_reply_to":"da86d52c_19d2bc5b","updated":"2015-02-13 11:13:59.000000000","message":"I am not sure about it... I take back my -1 and see whether others have more thoughts .. thanks","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"b434b8fd36b8acacbdcf5f074ef0dc27d93c3303","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_3216b159","line":839,"in_reply_to":"da86d52c_3ebd9dd8","updated":"2015-02-13 12:11:25.000000000","message":"Oh, sorry...I have new comment for this.\nWe cannot use here get_client_class, because we need parsed api_version, which will be used in initialization of Client.","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"6f9efe9f210b2fd1b3e12d293c0ac3176c181979","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_751e5361","line":839,"in_reply_to":"da86d52c_3ebd9dd8","updated":"2015-02-13 12:17:08.000000000","message":"So if you plan to remove get_client_class after no projects will use it? Can you please leave a TODO or add line to docstring for others not to use it?","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"0088b67e82582bee1fb72fa9a61ac8cd5115fd6e","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_19d2bc5b","line":839,"in_reply_to":"da86d52c_66a6d0ac","updated":"2015-02-13 07:55:02.000000000","message":"Function `get_class_class` is used only in small number of places throughout whole OpenStack. I found only two places and they should be used only for getting contrib modules(for more details look at https://review.openstack.org/#/c/152907/4/neutron/notifiers/nova.py ). After this patch will be merged and new version will be released, there will be no reasons to use this function in OpenStack(since novaclient.client.get_contrib_module and novaclient.client.Client will be used instead), so I see no reasons to use it in Client function because get_client_class should be unused and can be removed.","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"784547d1ee98a288f7f112053c421064348cf790","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_6b4f6b92","line":839,"in_reply_to":"da86d52c_66a6d0ac","updated":"2015-02-12 23:07:09.000000000","message":"I agree here, looks we can reuse previous one","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"3bf1d4bb1cac0845afa632dcc7561ab2eb9e6bb9","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_35293bf3","line":839,"in_reply_to":"da86d52c_751e5361","updated":"2015-02-13 12:26:59.000000000","message":"Imo, such notes should be added only with some log or warning message, otherwise, developers from other projects will be ignore such note.\n\nIf this function will print some warnings, guys from neutron and openstackclient will not accept my patches and will use direct import of client class. it\u0027s much worse.","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"f518e5721f9940d1eb53eccd532f03d4e7c30251","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_43f19a69","line":839,"in_reply_to":"da86d52c_e31d2ec0","updated":"2015-02-13 11:16:26.000000000","message":"I have found only 2 projects, which use(should use) this function: neutron and openstackclient.","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"4c8fac8a70c6d63de3aecb7e8c40ae93834943b5","unresolved":false,"context_lines":[{"line_number":836,"context_line":""},{"line_number":837,"context_line":""},{"line_number":838,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":839,"context_line":"    api_version \u003d check_versions(version)"},{"line_number":840,"context_line":"    client_class \u003d importutils.import_class("},{"line_number":841,"context_line":"        \"novaclient.v%s.client.Client\" % api_version[0])"},{"line_number":842,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_3ebd9dd8","line":839,"in_reply_to":"da86d52c_e31d2ec0","updated":"2015-02-13 11:33:41.000000000","message":"Since I\u0027m interested in positive mark, I\u0027ll fix this issue:)","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"4520152f9d264d3a6b8ac7b6ecaa71029047d88c","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"DEPRECATED_VERSIONS \u003d [\"1.1\"]"},{"line_number":55,"context_line":"LATEST_API_VERSION \u003d (\"2\", \"latest\")"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"class TCPKeepAliveAdapter(adapters.HTTPAdapter):"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_a98af017","line":55,"updated":"2015-02-16 14:54:52.000000000","message":"Don\u0027t like handling this stuff as constants, but can\u0027t suggest anything more graceful, so let it be for now","commit_id":"3d9e1dffeca9a1cd982eb06064ec69c5d2343e86"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"ef3bc4e4171621592551cab93bfc8fe37a1391b2","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"DEPRECATED_VERSIONS \u003d [\"1.1\"]"},{"line_number":55,"context_line":"LATEST_API_VERSION \u003d (\"2\", \"latest\")"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"class TCPKeepAliveAdapter(adapters.HTTPAdapter):"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_e684b2d4","line":55,"in_reply_to":"da86d52c_a98af017","updated":"2015-02-18 17:58:20.000000000","message":"stuff around LATEST_API_VERSION will be changed a little bit later in next patch.","commit_id":"3d9e1dffeca9a1cd982eb06064ec69c5d2343e86"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"4520152f9d264d3a6b8ac7b6ecaa71029047d88c","unresolved":false,"context_lines":[{"line_number":793,"context_line":"    :return: tuple where first element is api version and second one is"},{"line_number":794,"context_line":"             microversion."},{"line_number":795,"context_line":"    \"\"\""},{"line_number":796,"context_line":"    supported_versions_of_v2 \u003d [\"1.1\", \"2\"]"},{"line_number":797,"context_line":"    if version in supported_versions_of_v2:"},{"line_number":798,"context_line":"        if version in DEPRECATED_VERSIONS:"},{"line_number":799,"context_line":"            warnings.warn("}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_69c2b854","line":796,"updated":"2015-02-16 14:54:52.000000000","message":"As I understood below bunch of code is temporal and should be changed after removing of v1_1, so could you please left comment why we should have supported_versions and that they should be removed later","commit_id":"3d9e1dffeca9a1cd982eb06064ec69c5d2343e86"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"ef3bc4e4171621592551cab93bfc8fe37a1391b2","unresolved":false,"context_lines":[{"line_number":793,"context_line":"    :return: tuple where first element is api version and second one is"},{"line_number":794,"context_line":"             microversion."},{"line_number":795,"context_line":"    \"\"\""},{"line_number":796,"context_line":"    supported_versions_of_v2 \u003d [\"1.1\", \"2\"]"},{"line_number":797,"context_line":"    if version in supported_versions_of_v2:"},{"line_number":798,"context_line":"        if version in DEPRECATED_VERSIONS:"},{"line_number":799,"context_line":"            warnings.warn("}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_46c01e2b","line":796,"in_reply_to":"da86d52c_69c2b854","updated":"2015-02-18 17:58:20.000000000","message":"Imo, such comment will be duplicate of warning message on L799-L803, so it doesn\u0027t needed.","commit_id":"3d9e1dffeca9a1cd982eb06064ec69c5d2343e86"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"2364ff76af58c0d6a6a16a81132d0d9d33ad7710","unresolved":false,"context_lines":[{"line_number":729,"context_line":"                \"contrib modules from V%(alternative)s will be used \""},{"line_number":730,"context_line":"                \"instead.\" % {\"deprecated_version\": version,"},{"line_number":731,"context_line":"                              \"alternative\": 2})"},{"line_number":732,"context_line":"        return \"2\", None"},{"line_number":733,"context_line":"    elif \".\" in version:"},{"line_number":734,"context_line":"        versions \u003d re.findall(r\"^([1-9]\\d*)\\.([1-9]\\d*|0)$\", version)"},{"line_number":735,"context_line":"        # NOTE(andreykurilin): Method `re.findall` returns a list with all"}],"source_content_type":"text/x-python","patch_set":11,"id":"9a80dd14_8d219cfd","line":732,"updated":"2015-03-05 22:47:14.000000000","message":"I think I\u0027d like to see supported_versions_of_v2 as a global constant (it would be ideal if this would still \"just work\" when we add versions later hopefully just by modifying the globals. And could \"2\" could be BASE_API_VERSION instead of hard-coding it here and L731. What do you think?","commit_id":"41f92e09ba466f3582f98cc97ce03f4bf6c65b41"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"ad3b1264d5e91793d112506fd3f8f1fa2a62fa46","unresolved":false,"context_lines":[{"line_number":729,"context_line":"                \"contrib modules from V%(alternative)s will be used \""},{"line_number":730,"context_line":"                \"instead.\" % {\"deprecated_version\": version,"},{"line_number":731,"context_line":"                              \"alternative\": 2})"},{"line_number":732,"context_line":"        return \"2\", None"},{"line_number":733,"context_line":"    elif \".\" in version:"},{"line_number":734,"context_line":"        versions \u003d re.findall(r\"^([1-9]\\d*)\\.([1-9]\\d*|0)$\", version)"},{"line_number":735,"context_line":"        # NOTE(andreykurilin): Method `re.findall` returns a list with all"}],"source_content_type":"text/x-python","patch_set":11,"id":"9a80dd14_77718043","line":732,"in_reply_to":"9a80dd14_8d219cfd","updated":"2015-03-06 09:46:04.000000000","message":"Yeah, good idea.","commit_id":"41f92e09ba466f3582f98cc97ce03f4bf6c65b41"},{"author":{"_account_id":10224,"name":"Feodor Tersin","email":"ftersin@hotmail.com","username":"ftersin"},"change_message_id":"3b7da345667a08a9f7206682f3c45285bfbec92b","unresolved":false,"context_lines":[{"line_number":679,"context_line":"                           auth\u003dNone, user_agent\u003d\u0027python-novaclient\u0027,"},{"line_number":680,"context_line":"                           interface\u003dNone, api_version\u003dNone, **kwargs):"},{"line_number":681,"context_line":"    if session:"},{"line_number":682,"context_line":"        return SessionClient(session\u003dsession,"},{"line_number":683,"context_line":"                             auth\u003dauth,"},{"line_number":684,"context_line":"                             interface\u003dinterface or endpoint_type,"},{"line_number":685,"context_line":"                             service_type\u003dservice_type,"}],"source_content_type":"text/x-python","patch_set":12,"id":"9a80dd14_71d98821","line":682,"updated":"2015-03-06 11:57:10.000000000","message":"Nova cli uses this Client to do requests. But api version is not supplied to it, therefore nova cli doesn\u0027t add an api version header to requests, and nova-api server doesn\u0027t return microversion related info.\n\nIs this behavior expected at the moment? Or this is just an omission?","commit_id":"1d5a29591db4b12f95e8ad776a74cbb4246d96a5"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"c7451169f15ab72eff60b8505eb112a14ace9cf6","unresolved":false,"context_lines":[{"line_number":679,"context_line":"                           auth\u003dNone, user_agent\u003d\u0027python-novaclient\u0027,"},{"line_number":680,"context_line":"                           interface\u003dNone, api_version\u003dNone, **kwargs):"},{"line_number":681,"context_line":"    if session:"},{"line_number":682,"context_line":"        return SessionClient(session\u003dsession,"},{"line_number":683,"context_line":"                             auth\u003dauth,"},{"line_number":684,"context_line":"                             interface\u003dinterface or endpoint_type,"},{"line_number":685,"context_line":"                             service_type\u003dservice_type,"}],"source_content_type":"text/x-python","patch_set":12,"id":"9a80dd14_4ad3e603","line":682,"in_reply_to":"9a80dd14_71d98821","updated":"2015-03-06 15:07:06.000000000","message":"My fault. Fixed.","commit_id":"1d5a29591db4b12f95e8ad776a74cbb4246d96a5"},{"author":{"_account_id":10224,"name":"Feodor Tersin","email":"ftersin@hotmail.com","username":"ftersin"},"change_message_id":"8653a62ea0d3172ff6e46780d3b0e9829522edc3","unresolved":false,"context_lines":[{"line_number":369,"context_line":"            kwargs[\u0027headers\u0027][\u0027Content-Type\u0027] \u003d \u0027application/json\u0027"},{"line_number":370,"context_line":"            kwargs[\u0027data\u0027] \u003d json.dumps(kwargs[\u0027body\u0027])"},{"line_number":371,"context_line":"            del kwargs[\u0027body\u0027]"},{"line_number":372,"context_line":"        _update_headers_with_api_version(kwargs[\"headers\"], self.api_version)"},{"line_number":373,"context_line":"        if self.timeout is not None:"},{"line_number":374,"context_line":"            kwargs.setdefault(\u0027timeout\u0027, self.timeout)"},{"line_number":375,"context_line":"        kwargs[\u0027verify\u0027] \u003d self.verify_cert"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a80dd14_38160356","line":372,"updated":"2015-03-06 17:28:01.000000000","message":"You specify headers at the first argument here, but called function expects kwargs. As a result i get an exception:\n\n   File \"/opt/stack/python-novaclient/novaclient/client.py\", line 372, in request\n     _update_headers_with_api_version(kwargs[\"headers\"], self.api_version)\n   File \"/opt/stack/python-novaclient/novaclient/client.py\", line 91, in _update_headers_with_api_version\n     kwargs[\u0027headers\u0027][\u0027X-OpenStack-Nova-API-Version\u0027] \u003d vers\n KeyError: \u0027headers\u0027","commit_id":"2ff4030d0e9feb1ad371ab3e280dd0d83069ae3d"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"21f584167e395c5ef95ad1939545ca47492ba685","unresolved":false,"context_lines":[{"line_number":369,"context_line":"            kwargs[\u0027headers\u0027][\u0027Content-Type\u0027] \u003d \u0027application/json\u0027"},{"line_number":370,"context_line":"            kwargs[\u0027data\u0027] \u003d json.dumps(kwargs[\u0027body\u0027])"},{"line_number":371,"context_line":"            del kwargs[\u0027body\u0027]"},{"line_number":372,"context_line":"        _update_headers_with_api_version(kwargs[\"headers\"], self.api_version)"},{"line_number":373,"context_line":"        if self.timeout is not None:"},{"line_number":374,"context_line":"            kwargs.setdefault(\u0027timeout\u0027, self.timeout)"},{"line_number":375,"context_line":"        kwargs[\u0027verify\u0027] \u003d self.verify_cert"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a80dd14_4372ecad","line":372,"in_reply_to":"9a80dd14_38160356","updated":"2015-03-06 17:30:31.000000000","message":"oh...how can I miss this?! Fixed","commit_id":"2ff4030d0e9feb1ad371ab3e280dd0d83069ae3d"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"52c1a7f113e05fb4a1d7cc91fc39bd4633eeb5cd","unresolved":false,"context_lines":[{"line_number":47,"context_line":"from novaclient import service_catalog"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"DEPRECATED_VERSIONS \u003d [\"1.1\"]"},{"line_number":51,"context_line":"BASE_API_VERSION \u003d (\"2\", None)"},{"line_number":52,"context_line":"# NOTE(andreykurilin): this variable is used only to select latest"},{"line_number":53,"context_line":"#                      implementation at client side."}],"source_content_type":"text/x-python","patch_set":17,"id":"9a80dd14_62012906","line":50,"updated":"2015-03-17 04:42:36.000000000","message":"I\u0027m wondering if there is any advantage to marking 1.1 as deprecated now or just leave it and remove it when v2 goes away","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"25788d2caa48e4c68863f2882d415244e3d53600","unresolved":false,"context_lines":[{"line_number":47,"context_line":"from novaclient import service_catalog"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"DEPRECATED_VERSIONS \u003d [\"1.1\"]"},{"line_number":51,"context_line":"BASE_API_VERSION \u003d (\"2\", None)"},{"line_number":52,"context_line":"# NOTE(andreykurilin): this variable is used only to select latest"},{"line_number":53,"context_line":"#                      implementation at client side."}],"source_content_type":"text/x-python","patch_set":17,"id":"9a80dd14_09fc4e71","line":50,"in_reply_to":"9a80dd14_62012906","updated":"2015-03-20 16:02:30.000000000","message":"I prefer to mark it as deprecated for now and remove when v2 gone away.","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"52c1a7f113e05fb4a1d7cc91fc39bd4633eeb5cd","unresolved":false,"context_lines":[{"line_number":53,"context_line":"#                      implementation at client side."},{"line_number":54,"context_line":"LATEST_API_VERSION \u003d (\"2\", \"latest\")"},{"line_number":55,"context_line":"# NOTE(andreykurilin): v1_1 uses implementation of v2"},{"line_number":56,"context_line":"SUPPORTED_VERSIONS_OF_V2 \u003d [\"1.1\", \"2\"]"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"class TCPKeepAliveAdapter(adapters.HTTPAdapter):"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a80dd14_e52363a5","line":56,"updated":"2015-03-17 04:42:36.000000000","message":"I\u0027m not sure if we\u0027ll the above two if we use separate flags for api implementation to use and version of the api we want","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"52c1a7f113e05fb4a1d7cc91fc39bd4633eeb5cd","unresolved":false,"context_lines":[{"line_number":688,"context_line":"    # NOTE(andreykurilin): we should use v2.1 entry point if microversions"},{"line_number":689,"context_line":"    # feature is used."},{"line_number":690,"context_line":"    if service_type \u003d\u003d \u0027compute\u0027 and (api_version and api_version[1]):"},{"line_number":691,"context_line":"        service_type \u003d \u0027computev21\u0027"},{"line_number":692,"context_line":""},{"line_number":693,"context_line":"    if session:"},{"line_number":694,"context_line":"        return SessionClient(session\u003dsession,"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a80dd14_25465b22","line":691,"updated":"2015-03-17 04:42:36.000000000","message":"I\u0027m not sure we should be trying to autodetect this. Perhaps make it use computev21 by default otherwise use compute v2 if the nova server doesn\u0027t support it. Either way I\u0027d like a better name for computev21 but I think that can wait till later.\n\nService type could be specified on the command line like earlier suggested separating service type request from api version request","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"25788d2caa48e4c68863f2882d415244e3d53600","unresolved":false,"context_lines":[{"line_number":688,"context_line":"    # NOTE(andreykurilin): we should use v2.1 entry point if microversions"},{"line_number":689,"context_line":"    # feature is used."},{"line_number":690,"context_line":"    if service_type \u003d\u003d \u0027compute\u0027 and (api_version and api_version[1]):"},{"line_number":691,"context_line":"        service_type \u003d \u0027computev21\u0027"},{"line_number":692,"context_line":""},{"line_number":693,"context_line":"    if session:"},{"line_number":694,"context_line":"        return SessionClient(session\u003dsession,"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a80dd14_e409e1dd","line":691,"in_reply_to":"9a80dd14_25465b22","updated":"2015-03-20 16:02:30.000000000","message":"\u003ePerhaps make it use computev21 by default\n\n+1 for this suggestion\n\n\u003eEither way I\u0027d like a better name for computev21\n\nyeah, this name is not good. Maybe we should start a mailing thread for discussion of better one?","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"e38c0a47d63231df11ae918a3405a9d4627bee68","unresolved":false,"context_lines":[{"line_number":688,"context_line":"    # NOTE(andreykurilin): we should use v2.1 entry point if microversions"},{"line_number":689,"context_line":"    # feature is used."},{"line_number":690,"context_line":"    if service_type \u003d\u003d \u0027compute\u0027 and (api_version and api_version[1]):"},{"line_number":691,"context_line":"        service_type \u003d \u0027computev21\u0027"},{"line_number":692,"context_line":""},{"line_number":693,"context_line":"    if session:"},{"line_number":694,"context_line":"        return SessionClient(session\u003dsession,"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a6ced46_e617d74f","line":691,"in_reply_to":"9a80dd14_25465b22","updated":"2015-03-23 16:53:42.000000000","message":"Done","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"f3cd252092baf1e9a5575f1e8334ea143c63b287","unresolved":false,"context_lines":[{"line_number":798,"context_line":"        msg \u003d _(\"Invalid client version \u0027%(version)s\u0027. Major version part \""},{"line_number":799,"context_line":"                \"must be one of: %(keys)s.\") % {"},{"line_number":800,"context_line":"            \u0027version\u0027: version,"},{"line_number":801,"context_line":"            \u0027keys\u0027: \u0027, \u0027.join(_get_available_client_versions())}"},{"line_number":802,"context_line":"        raise exceptions.UnsupportedVersion(msg)"},{"line_number":803,"context_line":""},{"line_number":804,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"ba3cc151_08ad769a","line":801,"updated":"2015-07-08 22:21:15.000000000","message":"This function is where we have checking for invalid version.","commit_id":"5b8a4a34fedfccec134690a9879ef5948bb67580"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3fd646619075aae11514eab75a1da22f6ff37f07","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"ba3cc151_bae481e0","line":795,"updated":"2015-07-10 03:23:30.000000000","message":"Begin from here, this is API bit.\n\nLooks like \u00272.latest\u0027 is valid value at here. So what means \u00272.latest\u0027? If it means the recently version between client and server. That means you will introduce version negotiation at here.\n\nSo we have agreement on the version negotiation is only for CLI bit, right?","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"6d82e833d2654bea3cf85ea61bef4bd8baa8744e","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"9a41bdd9_2a11e352","line":795,"in_reply_to":"9a41bdd9_abcae74d","updated":"2015-07-12 20:25:06.000000000","message":"please, lets do it before Friday(July 17), since I\u0027ll be on vacation starting on July 20 and will not be back until July 31(inclusively).","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"d78a2a5e8b5efbc6b26c62ac87d7f11b1b049ce5","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"ba3cc151_8644bcb7","line":795,"in_reply_to":"ba3cc151_267290b1","updated":"2015-07-10 10:47:55.000000000","message":"Yes, client will try to discover \"latest\" version, but discovered version will be used in header and not \"2.latest\" value, so I don\u0027t see any problems with that.","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"db401808d745de6b2cd4c14a848b4a58b6ca46e3","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"ba3cc151_7c4d8498","line":795,"in_reply_to":"ba3cc151_61a88221","updated":"2015-07-10 12:46:18.000000000","message":"Sorry, I misunderstood you.\n\n\u003eSo the version discovered at probably at nova/shell.py, then find out a most recent version, then use that version create client.Client.\n\nWhat are the positive aspects of this?\nAs for me, which should not operate \"latest\" version in terms of whole client.\n\nFirst of all, it require to store and always update constant values of min and max versions. Maybe it normal for server-side( https://github.com/openstack/nova/blob/master/nova/api/openstack/api_version_request.py#L55-L56 ), since it should return supported versions, but for client side, imo, it is redundant.\n\nThe second one, each api method can have own max version, which can be lower than global max client version. For example, user call method list-a, which is deprecated in N-version(N-version is not the lates global version) and instead of execute this method, client will raise an exception. It looks like not user-friendly way. To make it more user-friendly we can add additional command for discovering the latest version supporting for single method, but why we need this overhead and why we can do it by default?\n\nPS: I am not against change spec, but I want get final decision about implementation before changing something drastically once again.","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"dd90aca43e086058b0b4c9507774bf0b654c94a3","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"9a41bdd9_abcae74d","line":795,"in_reply_to":"ba3cc151_7c4d8498","updated":"2015-07-12 13:10:53.000000000","message":"yea, after the discussion in the nova api meeting, we better have meeting to chat those final decision. I will send email and try to setup a chat for this.","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"c9cc9081efc5461777cfdd753389e52163eb42e7","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"ba3cc151_61a88221","line":795,"in_reply_to":"ba3cc151_81726610","updated":"2015-07-10 11:17:20.000000000","message":"Let me explain more. I\u0027m not concern on you use \u00272.latest\u0027, I\u0027m concern on version negotiation in the API bit. We didn\u0027t want the API bit doing any version negotiation. That means:\n\nSDK user, use our python client as sdk. He will write code like this:\n\ncs \u003d client.Client(...)\n\ncs.keypairs.create(...)\n\nThis is the \u0027API bit\u0027 what we said. We expect no version discover at here. So user only need specified specific version in the code. like this:\n\ncs \u003d client.Client(\u00272.2\u0027)\n\nIf the server didn\u0027t support it, then it can failed directly.\n\n\nThe version discover is happened in the CLI layer. the CLI layer is in the \u0027shell.py\u0027\n\nSo the version discovered at probably at nova/shell.py, then find out a most recent version, then use that version create client.Client.\n\nThis is what I understand...","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"5bccfa2bfcd4fecf39c155b0481851ddc507e84a","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"ba3cc151_81726610","line":795,"in_reply_to":"ba3cc151_8644bcb7","updated":"2015-07-10 11:09:45.000000000","message":"Emm....I mean \u0027cs.keypairs.create\u0027 this is the API,  API won\u0027t do any version negotiation. You discovered version and use it in the header, that means version negotiation.","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"4037e85539489c2095a4d57c176b8da56278d3da","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"ba3cc151_fbad2185","line":795,"in_reply_to":"ba3cc151_bae481e0","updated":"2015-07-10 10:23:21.000000000","message":"\u003eLooks like \u00272.latest\u0027 is valid value at here.\nyes.\n\n\u003eIf it means the recently version between client and server. That means you will introduce version negotiation at here.\n\nno. \"2.latest\" indicates to client to use Client class for V2 and use \"latest\" in the header. I mean value \"2.latest\" is used only at client side, not in header.","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"e9f7a7e97ae7357a3367b8a2d1a1f8eee5e8b3bf","unresolved":false,"context_lines":[{"line_number":792,"context_line":"    return client_class"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":""},{"line_number":795,"context_line":"def Client(version, *args, **kwargs):"},{"line_number":796,"context_line":"    \"\"\"Initialize client object based on given version.\"\"\""},{"line_number":797,"context_line":"    api_version, client_class \u003d _get_client_class_and_version(version)"},{"line_number":798,"context_line":"    return client_class(api_version\u003dapi_version, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":39,"id":"ba3cc151_267290b1","line":795,"in_reply_to":"ba3cc151_fbad2185","updated":"2015-07-10 10:36:16.000000000","message":"But when you execute API code as below:\n\ncs \u003d client.Client(\u00272.latest\u0027)\ncs.keypairs.create(...)\n\n\u0027cs.keypairs.create\u0027 is going to line 283 at https://review.openstack.org/#/c/184281/7/novaclient/api_versions.py\n\nThen begin to execute version negotiation. Correct me if misunderstood something.","commit_id":"c9a6d64208c78f25faad3a5a2d2465716c881784"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"37a46d15a4480bff918dc47c85ae25bc4980ccf7","unresolved":false,"context_lines":[{"line_number":100,"context_line":"                                                            raise_exc\u003dFalse,"},{"line_number":101,"context_line":"                                                            **kwargs)"},{"line_number":102,"context_line":"        if raise_exc and resp.status_code \u003e\u003d 400:"},{"line_number":103,"context_line":"            raise exceptions.from_response(resp, body, url, method)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        return resp, body"},{"line_number":106,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"9a41bdd9_da798e83","line":103,"updated":"2015-07-15 12:30:05.000000000","message":"looks like you want to check no microversion support at https://review.openstack.org/#/c/188816/","commit_id":"67ed9d586c26204aa94f945655aa8418e8124ed6"}],"novaclient/exceptions.py":[{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"8378253c27d2f6a89837ffca10ce6ec1584a87ae","unresolved":false,"context_lines":[{"line_number":159,"context_line":"    message \u003d \"Method Not Allowed\""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"class NotAcceptable(ClientException):"},{"line_number":163,"context_line":"    \"\"\""},{"line_number":164,"context_line":"    HTTP 406 - Not Acceptable"},{"line_number":165,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_66289097","line":162,"updated":"2015-02-12 17:53:41.000000000","message":"Sorry, haven\u0027t found usages of this exception, can you clarify the reason to add it now?","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"784547d1ee98a288f7f112053c421064348cf790","unresolved":false,"context_lines":[{"line_number":159,"context_line":"    message \u003d \"Method Not Allowed\""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"class NotAcceptable(ClientException):"},{"line_number":163,"context_line":"    \"\"\""},{"line_number":164,"context_line":"    HTTP 406 - Not Acceptable"},{"line_number":165,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_cb03f73f","line":162,"in_reply_to":"da86d52c_66289097","updated":"2015-02-12 23:07:09.000000000","message":"It\u0027s a HTTP return error \nused below","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"0088b67e82582bee1fb72fa9a61ac8cd5115fd6e","unresolved":false,"context_lines":[{"line_number":159,"context_line":"    message \u003d \"Method Not Allowed\""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"class NotAcceptable(ClientException):"},{"line_number":163,"context_line":"    \"\"\""},{"line_number":164,"context_line":"    HTTP 406 - Not Acceptable"},{"line_number":165,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_993b0cd0","line":162,"in_reply_to":"da86d52c_66289097","updated":"2015-02-13 07:55:02.000000000","message":"yes, jichenjc is right and it can be returned from API side when api version is wrong.","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":9550,"name":"Eugeniya Kudryashova","email":"ekudryashova@mirantis.com","username":"ekudryashova"},"change_message_id":"6f9efe9f210b2fd1b3e12d293c0ac3176c181979","unresolved":false,"context_lines":[{"line_number":159,"context_line":"    message \u003d \"Method Not Allowed\""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"class NotAcceptable(ClientException):"},{"line_number":163,"context_line":"    \"\"\""},{"line_number":164,"context_line":"    HTTP 406 - Not Acceptable"},{"line_number":165,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_35993bd1","line":162,"in_reply_to":"da86d52c_993b0cd0","updated":"2015-02-13 12:17:08.000000000","message":"Thanks, now I\u0027m ok with it","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"784547d1ee98a288f7f112053c421064348cf790","unresolved":false,"context_lines":[{"line_number":207,"context_line":"#"},{"line_number":208,"context_line":"# Instead, we have to hardcode it:"},{"line_number":209,"context_line":"_error_classes \u003d [BadRequest, Unauthorized, Forbidden, NotFound,"},{"line_number":210,"context_line":"                  MethodNotAllowed, NotAcceptable, Conflict, OverLimit,"},{"line_number":211,"context_line":"                  RateLimit, HTTPNotImplemented]"},{"line_number":212,"context_line":"_code_map \u003d dict((c.http_status, c) for c in _error_classes)"},{"line_number":213,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_6bf3eb72","line":210,"updated":"2015-02-12 23:07:09.000000000","message":"here, nova microversion will return it","commit_id":"7aeaa208f11c0b4b70187aa04f8a570e5fae17aa"}],"novaclient/shell.py":[{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"3a2d51e6bab388176c8aef9ceb6877f39f4192ff","unresolved":false,"context_lines":[{"line_number":440,"context_line":""},{"line_number":441,"context_line":"        actions_module \u003d shell_v2"},{"line_number":442,"context_line":""},{"line_number":443,"context_line":"        # TODO(akurilin): discover actions based on microversions"},{"line_number":444,"context_line":"        self._find_actions(subparsers, actions_module)"},{"line_number":445,"context_line":"        self._find_actions(subparsers, self)"},{"line_number":446,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"da86d52c_8f4a67aa","line":443,"updated":"2015-02-03 17:03:48.000000000","message":"Probably looking at some sort of decorator-based implementation…","commit_id":"43468132b92049f22ef04835f2e84291d39254a1"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"8a308bb3e2c237914b432d178ca1de2be41a7819","unresolved":false,"context_lines":[{"line_number":409,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":410,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":411,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":412,"context_line":"            help\u003d_(\u0027Accepts 1.1 or 3, \u0027"},{"line_number":413,"context_line":"                   \u0027defaults to env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":414,"context_line":"        parser.add_argument("},{"line_number":415,"context_line":"            \u0027--os_compute_api_version\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"ba7be1f8_dc49ed61","line":412,"updated":"2015-02-26 20:47:24.000000000","message":"I think we need to update this","commit_id":"081e964748c870c84db1dfec797e20d56d7e9b87"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"1bbf82ab4a685bf94d72a7a200dfbcecd02f555a","unresolved":false,"context_lines":[{"line_number":409,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":410,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":411,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":412,"context_line":"            help\u003d_(\u0027Accepts 1.1 or 3, \u0027"},{"line_number":413,"context_line":"                   \u0027defaults to env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":414,"context_line":"        parser.add_argument("},{"line_number":415,"context_line":"            \u0027--os_compute_api_version\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"ba7be1f8_4b543c21","line":412,"in_reply_to":"ba7be1f8_dc49ed61","updated":"2015-02-27 10:30:16.000000000","message":"Oh...sure","commit_id":"081e964748c870c84db1dfec797e20d56d7e9b87"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"76b2b3f05e8bc828a8847d6136234ff68045db93","unresolved":false,"context_lines":[{"line_number":409,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":410,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":411,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":412,"context_line":"            help\u003d_(\u0027Accepts 1.1 or 3, \u0027"},{"line_number":413,"context_line":"                   \u0027defaults to env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":414,"context_line":"        parser.add_argument("},{"line_number":415,"context_line":"            \u0027--os_compute_api_version\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"ba7be1f8_3e53bd6d","line":412,"in_reply_to":"ba7be1f8_dc49ed61","updated":"2015-02-27 13:31:44.000000000","message":"fixed. Also docs was updated.","commit_id":"081e964748c870c84db1dfec797e20d56d7e9b87"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"52c1a7f113e05fb4a1d7cc91fc39bd4633eeb5cd","unresolved":false,"context_lines":[{"line_number":409,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":410,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":411,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":412,"context_line":"            help\u003d_(\u0027Accepts 2, 2.x (where \"x\" is microversion) or \"latest\", \u0027"},{"line_number":413,"context_line":"                   \u0027defaults to env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":414,"context_line":"        parser.add_argument("},{"line_number":415,"context_line":"            \u0027--os_compute_api_version\u0027,"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a80dd14_6515b3e4","line":412,"updated":"2015-03-17 04:42:36.000000000","message":"strictly speaking 3.x or 10.5 would also be valid microversions but thats a long way away. Just want to make sure we don\u0027t end up too hard coded on it starting with 2 but its probably not a biggie now.","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"e38c0a47d63231df11ae918a3405a9d4627bee68","unresolved":false,"context_lines":[{"line_number":409,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":410,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":411,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":412,"context_line":"            help\u003d_(\u0027Accepts 2, 2.x (where \"x\" is microversion) or \"latest\", \u0027"},{"line_number":413,"context_line":"                   \u0027defaults to env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":414,"context_line":"        parser.add_argument("},{"line_number":415,"context_line":"            \u0027--os_compute_api_version\u0027,"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a6ced46_a6e23fd3","line":412,"in_reply_to":"9a80dd14_6515b3e4","updated":"2015-03-23 16:53:42.000000000","message":"Done","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"52c1a7f113e05fb4a1d7cc91fc39bd4633eeb5cd","unresolved":false,"context_lines":[{"line_number":440,"context_line":""},{"line_number":441,"context_line":"        actions_module \u003d shell_v2"},{"line_number":442,"context_line":""},{"line_number":443,"context_line":"        # TODO(akurilin): discover actions based on microversions"},{"line_number":444,"context_line":"        self._find_actions(subparsers, actions_module)"},{"line_number":445,"context_line":"        self._find_actions(subparsers, self)"},{"line_number":446,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"9a80dd14_c5dbbf4d","line":443,"updated":"2015-03-17 04:42:36.000000000","message":"yea I think this will eventually be implemented using json-home but I don\u0027t think its going to be straightforward and in the end having something cached may be necessary","commit_id":"9c2a359e6606b5c6f51add86ebd81a2f2edca815"},{"author":{"_account_id":10608,"name":"Matthew Edmonds","email":"edmondsw@us.ibm.com","username":"edmondsw"},"change_message_id":"4071a8cac81f4004e2998aad9391df80230f935b","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":61,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":62,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"1a6ced46_64464425","line":62,"updated":"2015-03-24 20:24:46.000000000","message":"version should not be part of the service type. Clients should strip off the \"/v2/{tenant_id}\" portion of the url if they want to talk another version, rather than play games in the service catalog, until such time as we can remove the version from the url (that should never have been there).","commit_id":"bc97dbe4d8a79797721e47379ee3427636ff2517"},{"author":{"_account_id":10608,"name":"Matthew Edmonds","email":"edmondsw@us.ibm.com","username":"edmondsw"},"change_message_id":"e1e13a4da90a83c2e70f2af25d442b1e23a08209","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":61,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":62,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"1a6ced46_f8c014e2","line":62,"in_reply_to":"1a6ced46_449b0867","updated":"2015-03-24 21:14:35.000000000","message":"Isn\u0027t this patch adding computev21? Where do you see that before this patch?","commit_id":"bc97dbe4d8a79797721e47379ee3427636ff2517"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"79e1d5e0c7f7b93166e09e3cc0c5f8b4c4852db7","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":61,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":62,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"1a6ced46_ee168ea6","line":62,"in_reply_to":"1a6ced46_4e21624c","updated":"2015-03-24 22:23:49.000000000","message":"I see. I guess I\u0027m not sure what to do here then, other than map \u00272.1\u0027 to \u0027computev2\u0027 or some such thing the way it was. I\u0027d be interested to get Chris\u0027s opinion.","commit_id":"bc97dbe4d8a79797721e47379ee3427636ff2517"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"49e5da1bc3de0a4cb7968b46784a0be23a8bc37d","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":61,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":62,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"1a6ced46_449b0867","line":62,"in_reply_to":"1a6ced46_64464425","updated":"2015-03-24 20:32:05.000000000","message":"I agree with you, but it doesn\u0027t relate to this patch. Service catalog already have computev21 service, which supports microversions","commit_id":"bc97dbe4d8a79797721e47379ee3427636ff2517"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"3a6064b936c6357adcc121b30721e76ef9cc7df7","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":61,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":62,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"1a6ced46_4e21624c","line":62,"in_reply_to":"1a6ced46_9bbaba21","updated":"2015-03-24 22:08:06.000000000","message":"oh... it is difficult topic, which are started in https://review.openstack.org/#/c/152569/17/novaclient/client.py\n\nok, I agreed that \"compute\" is reasonable value for service_type.","commit_id":"bc97dbe4d8a79797721e47379ee3427636ff2517"},{"author":{"_account_id":10224,"name":"Feodor Tersin","email":"ftersin@hotmail.com","username":"ftersin"},"change_message_id":"1bb71e63ee00d1698bcd5758682e52ffd10cc95d","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":61,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":62,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"1a6ced46_f91004aa","line":62,"in_reply_to":"1a6ced46_ee168ea6","updated":"2015-03-25 09:56:20.000000000","message":"If v1.1 is obsolete, could we set devstack to register v2.1 endpoint as \u0027compute\u0027 type? And to register v1.1 endpoint as \u0027computev11\u0027 for example if v1.1 endpoint is still needed for some reason.","commit_id":"bc97dbe4d8a79797721e47379ee3427636ff2517"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"60dfe978a72fef5967b79c15cb1215644d2ba8c5","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":61,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":62,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"1a6ced46_9bbaba21","line":62,"in_reply_to":"1a6ced46_f8c014e2","updated":"2015-03-24 21:36:53.000000000","message":"Hm, yeah. I don\u0027t think we can have anything other than \u0027compute\u0027 for a default.\n\nThe computev21 (and the old computev3) endpoint is just something that devstack creates [1] and not something we can or should force all deployments to have.\n\nI\u0027m guessing the reason computev3 is/was in here is because 1) it\u0027s optional, 2) if a deployer chose to enable v3 and expose it as a separate version-coded endpoint. I\u0027m not sure if that\u0027s a documented usage, exposing two versions of the api at the same time and encoding it into the endpoint name. I would think usually if a deployer wants to run for example nova api v2.1 they would have the \u0027compute\u0027 endpoint set up to point at v2.1.\n\n[1] https://github.com/openstack-dev/devstack/blob/d2287cf/lib/nova#L369","commit_id":"bc97dbe4d8a79797721e47379ee3427636ff2517"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"31c322b9570441730e98496b6a61ed4ad09e195d","unresolved":false,"context_lines":[{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":61,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":62,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"1a6ced46_dbbb52e3","line":62,"in_reply_to":"1a6ced46_f8c014e2","updated":"2015-03-24 21:34:35.000000000","message":"latest devstack + `keystone service-list`:\nhttp://paste.openstack.org/show/196200/\n\nThis line just changes default service_type","commit_id":"bc97dbe4d8a79797721e47379ee3427636ff2517"},{"author":{"_account_id":10608,"name":"Matthew Edmonds","email":"edmondsw@us.ibm.com","username":"edmondsw"},"change_message_id":"72b94c7675853286e602f50931021bee1731ae9e","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":62,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":63,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"1a6ced46_ce7ab2f0","line":63,"updated":"2015-03-24 22:22:58.000000000","message":"so based on your last comment in the previous patch set I expect you\u0027re changing this to \"compute\" and we will not hardcode \"computev21\" anywhere. Thanks.","commit_id":"01b2346ddd2ac0c73143959b85c6c2013dabcd1b"},{"author":{"_account_id":5292,"name":"Christopher Yeoh","email":"cbkyeoh@gmail.com","username":"cyeoh-0"},"change_message_id":"1f07fba91a2a56ae87b9eff90b36d861e6ee85e9","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"DEFAULT_OS_COMPUTE_API_VERSION \u003d \"2\""},{"line_number":62,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":63,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d \u0027computev21\u0027"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"logger \u003d logging.getLogger(__name__)"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"1a6ced46_c2c44361","line":63,"in_reply_to":"1a6ced46_ce7ab2f0","updated":"2015-03-25 00:54:56.000000000","message":"That is the long term goal. It will probably stay while the old Nova V2 API code exists","commit_id":"01b2346ddd2ac0c73143959b85c6c2013dabcd1b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"914f8acc3279590c8b6690ff3fc373004434a72c","unresolved":false,"context_lines":[{"line_number":645,"context_line":"            endpoint_type +\u003d \u0027URL\u0027"},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"        if not service_type:"},{"line_number":648,"context_line":"            service_type \u003d DEFAULT_NOVA_SERVICE_TYPE"},{"line_number":649,"context_line":"            service_type \u003d cliutils.get_service_type(args.func) or service_type"},{"line_number":650,"context_line":""},{"line_number":651,"context_line":"        # If we have an auth token but no management_url, we must auth anyway."}],"source_content_type":"text/x-python","patch_set":25,"id":"fa963961_6ff39274","line":648,"updated":"2015-03-27 14:33:26.000000000","message":"So, depending on the given --os-compute-api-version value, the nova service type should be either \u0027compute\u0027 or \u0027computev21\u0027 like this:\n\n    if --os-compute-api-version 2.0 \u003d\u003e \u0027compute\u0027 should be used.\n    if --os-compute-api-version 2.1 or higher \u003d\u003e \u0027computev21\u0027 should be used.\n\nBasically, what \u0027compute\u0027 and \u0027computev21\u0027 means is:\n\n   \u0027compute\u0027 - tells nova-api to use old contrib modules.\n   \u0027computev21\u0027 - tells nova-api to use new plugins/v3 modules. (including microversions)\n\nSo, I think a function would still be needed to determine the service_type, depending on the given --os-compute-api-version value.\n\nFor example, if a user requests --os-compute-api-version 2.2, the service type should be \u0027computev21\u0027, since it\u0027s clear that it requests the v2.2 microversion and desires to use that feature. It would be unexpected / wrong to receive the results from the nova-api contrib modules \n\nOfcourse, if no --os-compute-api-version is given, DEFAULT_NOVA_SERVICE_TYPE should be used.\n\nAlso, as it currently is, nova-api plugins/v3 (+microversions) is unusable by default, only usable if the user specifies the compute-service-type \u003d \u0027computev21\u0027.","commit_id":"1f8588d3c02eed63348bad8d7dd8ba0f52cfd480"},{"author":{"_account_id":10608,"name":"Matthew Edmonds","email":"edmondsw@us.ibm.com","username":"edmondsw"},"change_message_id":"167765ed32f362a852cf287bf26d7a96dad33597","unresolved":false,"context_lines":[{"line_number":58,"context_line":"from novaclient import utils"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"DEFAULT_NOVA_ENDPOINT_TYPE \u003d \u0027publicURL\u0027"},{"line_number":61,"context_line":"DEFAULT_NOVA_SERVICE_TYPE \u003d {\"legacy\": \"compute\","},{"line_number":62,"context_line":"                             \"microversions\": \"computev21\"}"},{"line_number":63,"context_line":"DEFAULT_OS_COMPUTE_API_TYPE \u003d \"legacy\""},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"9aa53dc9_2e5ff70f","line":61,"updated":"2015-04-06 14:32:57.000000000","message":"The default service type should always be \"compute\", totally regardless of API version. The service type \"computev21\" is a temporary bastardization created by devstack and specific to devstack. Obviously novaclient should not include code that is specific to a given deployment, whether that\u0027s devstack or something else. If someone wants to use a non-standard service type like \"computev21\", then they can do that by specifying --service-type.","commit_id":"7c87d94bbe312081ef944b2fbd70c4dfaf959018"},{"author":{"_account_id":10608,"name":"Matthew Edmonds","email":"edmondsw@us.ibm.com","username":"edmondsw"},"change_message_id":"167765ed32f362a852cf287bf26d7a96dad33597","unresolved":false,"context_lines":[{"line_number":582,"context_line":"            except KeyError:"},{"line_number":583,"context_line":"                raise exc.CommandError("},{"line_number":584,"context_line":"                    _(\"os-compute-api-type is wrong, please select one of next\""},{"line_number":585,"context_line":"                      \" types: %s.\") % \", \".join(DEFAULT_NOVA_SERVICE_TYPE))"},{"line_number":586,"context_line":"        else:"},{"line_number":587,"context_line":"            api_version \u003d api_versions.get_api_version("},{"line_number":588,"context_line":"                options.os_compute_api_version)"}],"source_content_type":"text/x-python","patch_set":26,"id":"9aa53dc9_cef2cb06","line":585,"updated":"2015-04-06 14:32:57.000000000","message":"using DEFAULT_NOVA_SERVICE_TYPE this way is correct, but will not work with the incorrect definition of that var at the top of this file (which sets it to a dict rather than a string). Need to fix the definition at the top (see comment there), and other locations that are currently (incorrectly) expecting that to be a dict.","commit_id":"7c87d94bbe312081ef944b2fbd70c4dfaf959018"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"a1fc7510a99aec43de4f14f57c12f7a919d8b6a6","unresolved":false,"context_lines":[{"line_number":403,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":404,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":405,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":406,"context_line":"            help\u003d_(\u0027Accepts X, X.Y(where X is major and Y is minor part) or \u0027"},{"line_number":407,"context_line":"                   \u0027\"latest\"  API version, defaults to \u0027"},{"line_number":408,"context_line":"                   \u0027env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":409,"context_line":"        parser.add_argument("}],"source_content_type":"text/x-python","patch_set":34,"id":"7a016987_176a74ed","line":406,"updated":"2015-05-29 20:03:22.000000000","message":"femtonit: insert a space between \u0027Y\u0027 and \u0027(\u0027 and eliminate \u0027 part\u0027 from the end of the parenthesized text.  That would cause this line to read:\n\n    help\u003d_(\u0027Accepts X, X.Y (where X is major and Y is minor) or \u0027","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"e1c112a35d7d23ab9c9028d23acd5aa23bf0f416","unresolved":false,"context_lines":[{"line_number":403,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":404,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":405,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":406,"context_line":"            help\u003d_(\u0027Accepts X, X.Y(where X is major and Y is minor part) or \u0027"},{"line_number":407,"context_line":"                   \u0027\"latest\"  API version, defaults to \u0027"},{"line_number":408,"context_line":"                   \u0027env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":409,"context_line":"        parser.add_argument("}],"source_content_type":"text/x-python","patch_set":34,"id":"fa32b979_1dd81d52","line":406,"in_reply_to":"7a016987_176a74ed","updated":"2015-06-25 14:00:38.000000000","message":"Done","commit_id":"85c1eea18f5e769f68fb90db9b1e2d8e8125ddaf"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"401aa2acf68d7624ab70d035f54920f33ca41f15","unresolved":false,"context_lines":[{"line_number":403,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":404,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":405,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":406,"context_line":"            help\u003d_(\u0027Accepts X, X.Y(where X is major and Y is minor part) or \u0027"},{"line_number":407,"context_line":"                   \u0027\"latest\"  API version, defaults to \u0027"},{"line_number":408,"context_line":"                   \u0027env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":409,"context_line":"        parser.add_argument("}],"source_content_type":"text/x-python","patch_set":35,"id":"fa32b979_1147a1bc","line":406,"updated":"2015-06-25 16:23:13.000000000","message":"You said \"Done\" but didn\u0027t change this line; forget a \u0027git add\u0027?  :)","commit_id":"2331c9842cb1f9dba07da273174c8a38d25405a8"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"d4848a0cfcd9ecb680b6c5504369b14e409bcc6c","unresolved":false,"context_lines":[{"line_number":403,"context_line":"            metavar\u003d\u0027\u003ccompute-api-ver\u003e\u0027,"},{"line_number":404,"context_line":"            default\u003dcliutils.env(\u0027OS_COMPUTE_API_VERSION\u0027,"},{"line_number":405,"context_line":"                                 default\u003dDEFAULT_OS_COMPUTE_API_VERSION),"},{"line_number":406,"context_line":"            help\u003d_(\u0027Accepts X, X.Y(where X is major and Y is minor part) or \u0027"},{"line_number":407,"context_line":"                   \u0027\"latest\"  API version, defaults to \u0027"},{"line_number":408,"context_line":"                   \u0027env[OS_COMPUTE_API_VERSION].\u0027))"},{"line_number":409,"context_line":"        parser.add_argument("}],"source_content_type":"text/x-python","patch_set":35,"id":"fa32b979_d4d4c720","line":406,"in_reply_to":"fa32b979_1147a1bc","updated":"2015-06-25 16:24:17.000000000","message":"yeah:( one moment, please","commit_id":"2331c9842cb1f9dba07da273174c8a38d25405a8"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a298926014c82ddf8af71c3666ffc0aba2a24e92","unresolved":false,"context_lines":[{"line_number":434,"context_line":"        subparsers \u003d parser.add_subparsers(metavar\u003d\u0027\u003csubcommand\u003e\u0027)"},{"line_number":435,"context_line":""},{"line_number":436,"context_line":"        actions_module \u003d importutils.import_module("},{"line_number":437,"context_line":"            \"novaclient.v%s.shell\" % version.ver_major)"},{"line_number":438,"context_line":""},{"line_number":439,"context_line":"        # TODO(andreykurilin): discover actions based on microversions"},{"line_number":440,"context_line":"        self._find_actions(subparsers, actions_module)"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_41a877db","line":437,"updated":"2015-07-07 22:19:50.000000000","message":"This raises ImportError if I put an invalid API version for example:\n\n nova --os-compute-api-version 3 list\n\n ERROR (ImportError): No module named v3.shell\n\nPerhaps we should catch ImportError and raise UnsupportedVersion or something more helpful to the user?","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"05f49293d1c1cf866fa890ec134fa276ce5004f3","unresolved":false,"context_lines":[{"line_number":434,"context_line":"        subparsers \u003d parser.add_subparsers(metavar\u003d\u0027\u003csubcommand\u003e\u0027)"},{"line_number":435,"context_line":""},{"line_number":436,"context_line":"        actions_module \u003d importutils.import_module("},{"line_number":437,"context_line":"            \"novaclient.v%s.shell\" % version.ver_major)"},{"line_number":438,"context_line":""},{"line_number":439,"context_line":"        # TODO(andreykurilin): discover actions based on microversions"},{"line_number":440,"context_line":"        self._find_actions(subparsers, actions_module)"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_d642043e","line":437,"in_reply_to":"ba3cc151_41a877db","updated":"2015-07-08 00:55:18.000000000","message":"This method is called with cheched api version( \"main\" method calls novaclient.api_versions.get_api_version, which checks all supported and deprecated versions)","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"7caed0c5826b5b7c5c7943dd03c8308f58953ea7","unresolved":false,"context_lines":[{"line_number":434,"context_line":"        subparsers \u003d parser.add_subparsers(metavar\u003d\u0027\u003csubcommand\u003e\u0027)"},{"line_number":435,"context_line":""},{"line_number":436,"context_line":"        actions_module \u003d importutils.import_module("},{"line_number":437,"context_line":"            \"novaclient.v%s.shell\" % version.ver_major)"},{"line_number":438,"context_line":""},{"line_number":439,"context_line":"        # TODO(andreykurilin): discover actions based on microversions"},{"line_number":440,"context_line":"        self._find_actions(subparsers, actions_module)"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_a8148a43","line":437,"in_reply_to":"ba3cc151_d642043e","updated":"2015-07-08 22:18:05.000000000","message":"It checks for deprecated versions but it doesn\u0027t check for supported versions. The code on master does this:\n\n nova --os-compute-api-version 3 list\n ERROR (UnsupportedVersion): Invalid client version \u00273\u0027. must be one of: 1.1, 2\n\nAnd this patch does this:\n\n nova --os-compute-api-version 3 list\n ERROR (ImportError): No module named v3.shell","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"f3cd252092baf1e9a5575f1e8334ea143c63b287","unresolved":false,"context_lines":[{"line_number":434,"context_line":"        subparsers \u003d parser.add_subparsers(metavar\u003d\u0027\u003csubcommand\u003e\u0027)"},{"line_number":435,"context_line":""},{"line_number":436,"context_line":"        actions_module \u003d importutils.import_module("},{"line_number":437,"context_line":"            \"novaclient.v%s.shell\" % version.ver_major)"},{"line_number":438,"context_line":""},{"line_number":439,"context_line":"        # TODO(andreykurilin): discover actions based on microversions"},{"line_number":440,"context_line":"        self._find_actions(subparsers, actions_module)"}],"source_content_type":"text/x-python","patch_set":38,"id":"ba3cc151_e87e121a","line":437,"updated":"2015-07-08 22:21:15.000000000","message":"But here there is no checking, so we get ImportError because get_subcommand_parser is called before Client is created","commit_id":"5b8a4a34fedfccec134690a9879ef5948bb67580"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"ccdfe799b26e1f4507969c8c3f7ecaa51acca528","unresolved":false,"context_lines":[{"line_number":434,"context_line":"        subparsers \u003d parser.add_subparsers(metavar\u003d\u0027\u003csubcommand\u003e\u0027)"},{"line_number":435,"context_line":""},{"line_number":436,"context_line":"        actions_module \u003d importutils.import_module("},{"line_number":437,"context_line":"            \"novaclient.v%s.shell\" % version.ver_major)"},{"line_number":438,"context_line":""},{"line_number":439,"context_line":"        # TODO(andreykurilin): discover actions based on microversions"},{"line_number":440,"context_line":"        self._find_actions(subparsers, actions_module)"}],"source_content_type":"text/x-python","patch_set":38,"id":"ba3cc151_7514f59e","line":437,"in_reply_to":"ba3cc151_e87e121a","updated":"2015-07-09 13:31:02.000000000","message":"you are right. fixed","commit_id":"5b8a4a34fedfccec134690a9879ef5948bb67580"}],"novaclient/tests/unit/test_api_versions.py":[{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a298926014c82ddf8af71c3666ffc0aba2a24e92","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        api_versions.update_headers(headers, api_version)"},{"line_number":141,"context_line":"        self.assertEqual("},{"line_number":142,"context_line":"            {\"X-OpenStack-Nova-API-Version\": api_version.get_string()},"},{"line_number":143,"context_line":"            headers)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"class GetAPIVersionTestCase(utils.TestCase):"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_dcdd4c71","line":143,"updated":"2015-07-07 22:19:50.000000000","message":"In the code, a version with 0 minor version would get empty headers. If that code is intended (which I think is not, see my comment in api_versions.py), we should have a test where minor version is 0 to verify the behavior that we want empty headers in that case.","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"c770b654ec15089cba52081d66353a34d9f7abc8","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        api_versions.update_headers(headers, api_version)"},{"line_number":141,"context_line":"        self.assertEqual("},{"line_number":142,"context_line":"            {\"X-OpenStack-Nova-API-Version\": api_version.get_string()},"},{"line_number":143,"context_line":"            headers)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"class GetAPIVersionTestCase(utils.TestCase):"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_e21df8be","line":143,"in_reply_to":"ba3cc151_dcdd4c71","updated":"2015-07-08 09:29:14.000000000","message":"Done","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"}],"novaclient/tests/unit/test_shell.py":[{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a298926014c82ddf8af71c3666ffc0aba2a24e92","unresolved":false,"context_lines":[{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    @mock.patch(\u0027novaclient.client.Client\u0027)"},{"line_number":346,"context_line":"    def test_v_unknown_service_type(self, mock_client):"},{"line_number":347,"context_line":"        self.assertRaises(exceptions.UnsupportedVersion,"},{"line_number":348,"context_line":"                          self._test_service_type,"},{"line_number":349,"context_line":"                          \u0027unknown\u0027, \u0027compute\u0027, mock_client)"},{"line_number":350,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_3c70f8db","line":347,"updated":"2015-07-07 22:19:50.000000000","message":"Can you explain how this changed? Unknown service_type is supposed to raise UnsupportedVersion?","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"05f49293d1c1cf866fa890ec134fa276ce5004f3","unresolved":false,"context_lines":[{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    @mock.patch(\u0027novaclient.client.Client\u0027)"},{"line_number":346,"context_line":"    def test_v_unknown_service_type(self, mock_client):"},{"line_number":347,"context_line":"        self.assertRaises(exceptions.UnsupportedVersion,"},{"line_number":348,"context_line":"                          self._test_service_type,"},{"line_number":349,"context_line":"                          \u0027unknown\u0027, \u0027compute\u0027, mock_client)"},{"line_number":350,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"ba3cc151_b6b8a012","line":347,"in_reply_to":"ba3cc151_3c70f8db","updated":"2015-07-08 00:55:18.000000000","message":"The validation is moved from initialization of client object to earlier step(shell.main method), so when version is \"unknown\", the validation will raise an exception","commit_id":"de3b0dfb15020ef8dc48f1387890ed3200da851e"}]}
