)]}'
{"neutronclient/common/extension.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"1a930d6b_432e258d","updated":"2015-01-27 17:16:00.000000000","message":"There are many copy-and-paste logic from neutronclient/neutorn/v2_0/__init__ Such approach should be avoided,","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2012 OpenStack Foundation."},{"line_number":2,"context_line":"# All Rights Reserved"},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_806483b9","line":1,"updated":"2015-01-27 17:16:00.000000000","message":"2015","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":10980,"name":"Doug Wiegley","email":"dougwig@parkside.io","username":"dougw"},"change_message_id":"0f0f66ff8395bd2aae7779f1e97f3dede658521a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2012 OpenStack Foundation."},{"line_number":2,"context_line":"# All Rights Reserved"},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_b91f6f6b","line":1,"in_reply_to":"1a930d6b_806483b9","updated":"2015-02-03 21:32:27.000000000","message":"And Rackspace, unless you\u0027re employed by OpenStack Foundation","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":5127,"name":"Justin Hammond","email":"runningempty@gmail.com","username":"justin-hammond"},"change_message_id":"97f0ad33b43e5c8b0cc9992d3b3999dca6da12e6","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2012 OpenStack Foundation."},{"line_number":2,"context_line":"# All Rights Reserved"},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_03745866","line":1,"in_reply_to":"da86d52c_b91f6f6b","updated":"2015-02-04 21:37:15.000000000","message":"That never made sense to me. Aren\u0027t all these things for OpenStack as a whole? Copyright rules are strange in open source.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    @classmethod"},{"line_number":29,"context_line":"    def get_logger(kls, suffix):"},{"line_number":30,"context_line":"        return logging.getLogger(\"%s.%s\" % (__name__, suffix))"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class ClientExtensionList(NeutronClientExtension, neutronV20.ListCommand):"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_00f7b3d3","line":30,"updated":"2015-01-27 17:16:00.000000000","message":"In the latest code, NeutronCommandMeta does the same. Doesn\u0027t it work?","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":5127,"name":"Justin Hammond","email":"runningempty@gmail.com","username":"justin-hammond"},"change_message_id":"97f0ad33b43e5c8b0cc9992d3b3999dca6da12e6","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    @classmethod"},{"line_number":29,"context_line":"    def get_logger(kls, suffix):"},{"line_number":30,"context_line":"        return logging.getLogger(\"%s.%s\" % (__name__, suffix))"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class ClientExtensionList(NeutronClientExtension, neutronV20.ListCommand):"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_5d1e6464","line":30,"in_reply_to":"1a930d6b_00f7b3d3","updated":"2015-02-04 21:37:15.000000000","message":"Done","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    def get_logger(kls, suffix):"},{"line_number":30,"context_line":"        return logging.getLogger(\"%s.%s\" % (__name__, suffix))"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class ClientExtensionList(NeutronClientExtension, neutronV20.ListCommand):"},{"line_number":34,"context_line":"    def get_data(self, parsed_args):"},{"line_number":35,"context_line":"        # NOTE(mdietz): Calls \u0027execute\u0027 to provide a consistent pattern"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_c084cb0c","line":32,"updated":"2015-01-27 17:16:00.000000000","message":"ClientExtensionShow does not exists. It is inconsistent.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class ClientExtensionList(NeutronClientExtension, neutronV20.ListCommand):"},{"line_number":34,"context_line":"    def get_data(self, parsed_args):"},{"line_number":35,"context_line":"        # NOTE(mdietz): Calls \u0027execute\u0027 to provide a consistent pattern"},{"line_number":36,"context_line":"        #               for any implementers adding extensions with"},{"line_number":37,"context_line":"        #               regard to any other extension verb."}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_f1e99cb7","line":34,"updated":"2015-01-27 17:16:00.000000000","message":"(just a comment) get_data() is just an alias of take_action() and it is a bad convention in neutronclient.common.OpenStackCommand.\nIf we don\u0027t have it, we can just override take_action()..... and there is no need to use execute().... At the moment it is a good idea to provide a consistent pattern by execute.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        #               regard to any other extension verb."},{"line_number":53,"context_line":"        return self.execute(parsed_args)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def execute(self, parsed_args):"},{"line_number":56,"context_line":"        self.log.debug(\u0027run(%s)\u0027 % parsed_args)"},{"line_number":57,"context_line":"        neutron_client \u003d self.get_client()"},{"line_number":58,"context_line":"        neutron_client.format \u003d parsed_args.request_format"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_e028e7e3","line":55,"updated":"2015-01-27 17:16:00.000000000","message":"The content of this method is almost a copy of DeleteCommand.\nWe hate copy-and-paste strategy. Can\u0027t you avoid it?\nOnly difference is the logic which calls neutron server (how to get _obj_deleter in this case).\n\nThe comment applies to other classes.\n\nThough it is not a usual style, the following works:\n\n  def execute(self, parsed_args):\n    super(ClientExtensionDelete).run(parsed_args)","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        self.log.debug(\u0027run(%s)\u0027 % parsed_args)"},{"line_number":57,"context_line":"        neutron_client \u003d self.get_client()"},{"line_number":58,"context_line":"        neutron_client.format \u003d parsed_args.request_format"},{"line_number":59,"context_line":"        _id \u003d parsed_args.id"},{"line_number":60,"context_line":"        neutron_client.delete(\"%s/%s\" % (self.resource_path, _id))"},{"line_number":61,"context_line":"        self.log.debug(\u0027Deleted %(resource)s: %(id)s\u0027 % {\u0027id\u0027: parsed_args.id,"},{"line_number":62,"context_line":"                       \u0027resource\u0027: self.resource})"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_a0e6dfe5","line":59,"updated":"2015-01-27 17:16:00.000000000","message":"It is better to use find_resourceid_by_name_or_id and honor allow_names.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":1923,"name":"Mohammad Banikazemi","email":"mbanikazemi@gmail.com","username":"mb-s"},"change_message_id":"aff9ce72d0304299f394cb2eb7ddf537be9646ce","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        neutron_client.put(\"%s/%s\" % (self.resource_path, _id), body)"},{"line_number":117,"context_line":"        self.log.debug((\u0027Updated %(resource)s: %(id)s\u0027) %"},{"line_number":118,"context_line":"                       {\u0027id\u0027: parsed_args.id, \u0027resource\u0027: self.resource})"},{"line_number":119,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa81d914_6f92cc58","line":119,"updated":"2015-01-28 19:53:34.000000000","message":"not necessary.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":5127,"name":"Justin Hammond","email":"runningempty@gmail.com","username":"justin-hammond"},"change_message_id":"97f0ad33b43e5c8b0cc9992d3b3999dca6da12e6","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        neutron_client.put(\"%s/%s\" % (self.resource_path, _id), body)"},{"line_number":117,"context_line":"        self.log.debug((\u0027Updated %(resource)s: %(id)s\u0027) %"},{"line_number":118,"context_line":"                       {\u0027id\u0027: parsed_args.id, \u0027resource\u0027: self.resource})"},{"line_number":119,"context_line":"        return"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_c30de0e9","line":119,"in_reply_to":"fa81d914_6f92cc58","updated":"2015-02-04 21:37:15.000000000","message":"Done","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"bd64c106f1f3696b6d80480057caa0fe740fd03f","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"def _discover_via_entry_points():"},{"line_number":53,"context_line":"    for ep in pkg_resources.iter_entry_points(\u0027neutronclient.extension\u0027):"},{"line_number":54,"context_line":"        name \u003d ep.name"},{"line_number":55,"context_line":"        module \u003d ep.load()"},{"line_number":56,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"da86d52c_fd88bdc7","line":53,"updated":"2015-02-18 19:56:38.000000000","message":"This would be something like:\n\n  from stevedore import extension\n  epmgr \u003d extension.ExtensionManager(\u0027neutronclient.extension\u0027, invoke_on_load\u003dFalse)\n  return ((ep.name, ep.plugin) for ep in epmgr)","commit_id":"e878d7c6c3b82478412f8aced1c95c0af2eb7cfe"},{"author":{"_account_id":10980,"name":"Doug Wiegley","email":"dougwig@parkside.io","username":"dougw"},"change_message_id":"1cb9554cc573d365f81af2014a41432fe4d7a8f6","unresolved":false,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"def _discover_via_entry_points():"},{"line_number":53,"context_line":"    emgr \u003d extension.ExtensionManager(\u0027neuronclient.extension\u0027,"},{"line_number":54,"context_line":"                                      invoke_on_load\u003dFalse)"},{"line_number":55,"context_line":"    return ((ext.name, ext.plugin) for ext in emgr)"},{"line_number":56,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"da86d52c_dbc93c5b","line":53,"updated":"2015-02-18 22:35:27.000000000","message":"neuron?","commit_id":"7053dc7692df523f9db56a8cad6fd12f8bc791bd"}],"neutronclient/neutron/v2_0/contrib/fox_sockets.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"129e86f08c4aae25fa590ae80527a1da211a7784","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"da86d52c_2f65c9ae","updated":"2015-02-18 14:32:23.000000000","message":"I think this module is an example.\nI would like not to see subcommands fox-* in the command list. Could you change the filename to the one which starts with an underscore (if this direction gets an consensus successfully)?","commit_id":"e878d7c6c3b82478412f8aced1c95c0af2eb7cfe"}],"neutronclient/shell.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":646,"context_line":"                options.add(option)"},{"line_number":647,"context_line":"        print(\u0027 \u0027.join(commands | options))"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def _discover_extensions(self, version):"},{"line_number":650,"context_line":"        self._load_contrib_extensions(version)"},{"line_number":651,"context_line":"        self._load_external_extensions()"},{"line_number":652,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_a056df03","line":649,"updated":"2015-01-27 17:16:00.000000000","message":"I prefer to a coding style in nova client as follows.\n\n  for module in itertools.chain(\n          self._discover_via_contrib_path(),\n          self._discover_via_python_path(),\n          self._discover_via_entry_points()):\n      register_extension_module(module, version)\n\nIn addition, this method registers extension commands, so the method name should be \u0027register_extensions\u0027 rather than \u0027discover\u0027.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def _discover_extensions(self, version):"},{"line_number":650,"context_line":"        self._load_contrib_extensions(version)"},{"line_number":651,"context_line":"        self._load_external_extensions()"},{"line_number":652,"context_line":""},{"line_number":653,"context_line":"    def _load_contrib_extensions(self, version):"},{"line_number":654,"context_line":"        module_path \u003d os.path.dirname(os.path.abspath(__file__))"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_4c6bb784","line":651,"updated":"2015-01-27 17:16:00.000000000","message":"Could you add entry_points based extension too as novaclient does?\n\n  for ep in pkg_resources.iter_entry_points(\u0027neutronclient.extension\u0027):\n     module \u003d ep.load()","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":652,"context_line":""},{"line_number":653,"context_line":"    def _load_contrib_extensions(self, version):"},{"line_number":654,"context_line":"        module_path \u003d os.path.dirname(os.path.abspath(__file__))"},{"line_number":655,"context_line":"        ext_path \u003d os.path.join(module_path, \u0027v%s\u0027 % version, \"contrib\")"},{"line_number":656,"context_line":"        ext_glob \u003d os.path.join(ext_path, \"*.py\")"},{"line_number":657,"context_line":"        for ext_path in glob.iglob(ext_glob):"},{"line_number":658,"context_line":"            name \u003d os.path.basename(ext_path)[:-3]"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_ac9b3b16","line":655,"updated":"2015-01-27 17:16:00.000000000","message":"This searchs extension modules under neutronclient.v2.0.contrib. \nCommand class is placed at neutronclient.neutron.v2_0 directory, so it seems not a right place. I prefer to neutronclient.contrib (or neutronclient.neutron.contrib).\n\nVERSION is not \u00272_0\u0027 but \u00272.0\u0027 so it is not a valid pass. we need to use \u00272_0\u0027.\n\nCOMMANDS in shell.py has the following style:\n\n  {\"2.0\": COMMAND_V2}\n\nHow about using COMMANDS definition like:\n\n  {API_VERSION: {\u0027xxx-list\u0027: LlistXXXX,\n                  \u0027xxx-create\u0027: ....\n\nBy this style, one contrib moudle supports various version.\n\nPlease consider my comment at L.649.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":657,"context_line":"        for ext_path in glob.iglob(ext_glob):"},{"line_number":658,"context_line":"            name \u003d os.path.basename(ext_path)[:-3]"},{"line_number":659,"context_line":"            if name \u003d\u003d \"__init__\":"},{"line_number":660,"context_line":"                continue"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"            module \u003d imp.load_source(name, ext_path)"},{"line_number":663,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_e0c62799","line":660,"updated":"2015-01-27 17:16:00.000000000","message":"Can\u0027t we skip a module whose name starts with underscore?\nIt allows us to disable some contrib extensions.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c4c8a37701b4c099a70280e38d490b1ee6f39f7a","unresolved":false,"context_lines":[{"line_number":660,"context_line":"                continue"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"            module \u003d imp.load_source(name, ext_path)"},{"line_number":663,"context_line":""},{"line_number":664,"context_line":"            if getattr(module, \"COMMANDS\"):"},{"line_number":665,"context_line":"                for attr_name, attr_value in module.COMMANDS.items():"},{"line_number":666,"context_line":"                    try:"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a930d6b_ac1edb6d","line":663,"updated":"2015-01-27 17:16:00.000000000","message":"Could you make L.664-669 a separate method?\nBy doing so, we can split a step which finds extension module and a step which registers module.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":10980,"name":"Doug Wiegley","email":"dougwig@parkside.io","username":"dougw"},"change_message_id":"0f0f66ff8395bd2aae7779f1e97f3dede658521a","unresolved":false,"context_lines":[{"line_number":672,"context_line":"        for (module_loader, name, _ispkg) in pkgutil.iter_modules():"},{"line_number":673,"context_line":"            if name.endswith(\u0027_python_neutronclient_ext\u0027):"},{"line_number":674,"context_line":"                if not hasattr(module_loader, \u0027load_module\u0027):"},{"line_number":675,"context_line":"                    # Python 2.6 compat: actually get an ImpImporter obj"},{"line_number":676,"context_line":"                    module_loader \u003d module_loader.find_module(name)"},{"line_number":677,"context_line":""},{"line_number":678,"context_line":"                module \u003d module_loader.load_module(name)"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_f93e47d9","line":675,"updated":"2015-02-03 21:32:27.000000000","message":"No need for py26 tweaks anymore","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"24dcabbbdfeef223181d312aeecc5b731a3777c1","unresolved":false,"context_lines":[{"line_number":672,"context_line":"        for (module_loader, name, _ispkg) in pkgutil.iter_modules():"},{"line_number":673,"context_line":"            if name.endswith(\u0027_python_neutronclient_ext\u0027):"},{"line_number":674,"context_line":"                if not hasattr(module_loader, \u0027load_module\u0027):"},{"line_number":675,"context_line":"                    # Python 2.6 compat: actually get an ImpImporter obj"},{"line_number":676,"context_line":"                    module_loader \u003d module_loader.find_module(name)"},{"line_number":677,"context_line":""},{"line_number":678,"context_line":"                module \u003d module_loader.load_module(name)"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_7b422b69","line":675,"in_reply_to":"da86d52c_f93e47d9","updated":"2015-02-04 16:21:36.000000000","message":"In the client library, we still need to care python2.6 because it is used for the released versions (juno and icehouse) and both of the versions support python 2.6. This is the reason we still have python26 check in the check job for client libraries.","commit_id":"ebbb06e8f9758d97b6f76c0c69025540bd62c243"}]}
