)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cb86145714fa4d9cdd526d1de67a99beb91ebfd6","unresolved":false,"context_lines":[{"line_number":17,"context_line":"using nested or shared RPs."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"resources_from_request_spec now produces a ResourceRequest object which"},{"line_number":20,"context_line":"is passed directly into the scheduler\u0027s get_allocation_candidates"},{"line_number":21,"context_line":"method.  However, get_allocation_candidates currently just extracts the"},{"line_number":22,"context_line":"(unnumbered) \u0027resources\u0027 dict out, resulting in precisely the"},{"line_number":23,"context_line":"pre-existing behavior.  Later in the series, when GET"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"3f4b6375_e360d703","line":20,"range":{"start_line":20,"start_character":28,"end_line":20,"end_character":37},"updated":"2017-11-06 15:39:40.000000000","message":"scheduler *client*\u0027s :)","commit_id":"dc4d98b4519c1dc32fe8fe19412c77546d7e8406"}],"nova/scheduler/client/report.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2e8bb3e571ee24568416fdf9a1cec2b47329d19e","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        # existing behavior.  Once the GET /allocation_candidates API is"},{"line_number":350,"context_line":"        # prepped to accept the whole shebang, we\u0027ll join up all the resources"},{"line_number":351,"context_line":"        # and traits in the query string (via a new method on ResourceRequest)."},{"line_number":352,"context_line":"        resources \u003d resources._rg_by_id[\u00270\u0027].resources"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"        resource_query \u003d \",\".join("},{"line_number":355,"context_line":"            sorted(\"%s:%s\" % (rc, amount)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_2f9d2666","line":352,"range":{"start_line":352,"start_character":30,"end_line":352,"end_character":39},"updated":"2017-10-30 14:37:51.000000000","message":"If we introduce some encapsulation then we should try not to access the internals directly.","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fa673d184d19f98e6369322b03a50645ebdff102","unresolved":false,"context_lines":[{"line_number":349,"context_line":"        # existing behavior.  Once the GET /allocation_candidates API is"},{"line_number":350,"context_line":"        # prepped to accept the whole shebang, we\u0027ll join up all the resources"},{"line_number":351,"context_line":"        # and traits in the query string (via a new method on ResourceRequest)."},{"line_number":352,"context_line":"        resources \u003d resources._rg_by_id[\u00270\u0027].resources"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"        resource_query \u003d \",\".join("},{"line_number":355,"context_line":"            sorted(\"%s:%s\" % (rc, amount)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_25fc253d","line":352,"range":{"start_line":352,"start_character":30,"end_line":352,"end_character":39},"in_reply_to":"3f4b6375_2f9d2666","updated":"2017-10-30 20:22:59.000000000","message":"Oh, totally agree - this is *temporary* until we\u0027re passing the whole thing down.  That\u0027ll probably be the last thing to happen in the series, once the API is ready with the new microversion.","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"}],"nova/scheduler/utils.py":[{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"09f6988fe2438715b9cbe002d19c4fda682a89ca","unresolved":false,"context_lines":[{"line_number":231,"context_line":"    disk \u003d ((0 if is_bfv else flavor.root_gb) +"},{"line_number":232,"context_line":"            swap_in_gb + flavor.ephemeral_gb)"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    flv_resources \u003d {"},{"line_number":235,"context_line":"        fields.ResourceClass.VCPU: flavor.vcpus,"},{"line_number":236,"context_line":"        fields.ResourceClass.MEMORY_MB: flavor.memory_mb,"},{"line_number":237,"context_line":"        fields.ResourceClass.DISK_GB: disk,"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_4ebf92a9","line":234,"updated":"2017-10-26 12:06:48.000000000","message":"flv is a flavor? Can we have flavor_resources instead please?","commit_id":"97bc785482c5842e15ade74ce42e0238e66df3fd"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f07daae6e705cd78685daf4686bc3f756e581e03","unresolved":false,"context_lines":[{"line_number":231,"context_line":"    disk \u003d ((0 if is_bfv else flavor.root_gb) +"},{"line_number":232,"context_line":"            swap_in_gb + flavor.ephemeral_gb)"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    flv_resources \u003d {"},{"line_number":235,"context_line":"        fields.ResourceClass.VCPU: flavor.vcpus,"},{"line_number":236,"context_line":"        fields.ResourceClass.MEMORY_MB: flavor.memory_mb,"},{"line_number":237,"context_line":"        fields.ResourceClass.DISK_GB: disk,"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_e95ab880","line":234,"in_reply_to":"3f4b6375_4ebf92a9","updated":"2017-10-26 12:34:43.000000000","message":"Sure.","commit_id":"97bc785482c5842e15ade74ce42e0238e66df3fd"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"09f6988fe2438715b9cbe002d19c4fda682a89ca","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        # pass them along.  This will need to be adjusted when nested and/or"},{"line_number":244,"context_line":"        # shared RPs are in play."},{"line_number":245,"context_line":"        xs_res \u003d {}"},{"line_number":246,"context_line":"        for g, r in _process_extra_specs_granular(flavor.extra_specs).items():"},{"line_number":247,"context_line":"            if g.startswith(\u0027resources\u0027):"},{"line_number":248,"context_line":"                for rc in set(xs_res) | set(r):"},{"line_number":249,"context_line":"                    xs_res[rc] \u003d xs_res.get(rc, 0) + r.get(rc, 0)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_ae6f2629","line":246,"updated":"2017-10-26 12:06:48.000000000","message":"what\u0027s a g? what\u0027s an r?\n\nWe\u0027ve gone to all this trouble to use a nice readable language that allows nice big variable names...","commit_id":"97bc785482c5842e15ade74ce42e0238e66df3fd"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"f07daae6e705cd78685daf4686bc3f756e581e03","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        # pass them along.  This will need to be adjusted when nested and/or"},{"line_number":244,"context_line":"        # shared RPs are in play."},{"line_number":245,"context_line":"        xs_res \u003d {}"},{"line_number":246,"context_line":"        for g, r in _process_extra_specs_granular(flavor.extra_specs).items():"},{"line_number":247,"context_line":"            if g.startswith(\u0027resources\u0027):"},{"line_number":248,"context_line":"                for rc in set(xs_res) | set(r):"},{"line_number":249,"context_line":"                    xs_res[rc] \u003d xs_res.get(rc, 0) + r.get(rc, 0)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_8953446b","line":246,"in_reply_to":"3f4b6375_ae6f2629","updated":"2017-10-26 12:34:43.000000000","message":"Yeah, was trying to cheat line width.  I can split it up and rename the vars.","commit_id":"97bc785482c5842e15ade74ce42e0238e66df3fd"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9202421619d9af883db29333d039a84ba0bc1039","unresolved":false,"context_lines":[{"line_number":253,"context_line":"        # Copy the items list so we can modify the dict in the loop"},{"line_number":254,"context_line":"        for rc, amt in list(xs_res.items()):"},{"line_number":255,"context_line":"            popped \u003d False"},{"line_number":256,"context_line":"            if rc in flavor_resources:"},{"line_number":257,"context_line":"                popped \u003d flavor_resources.pop(rc, None)"},{"line_number":258,"context_line":"            if amt:"},{"line_number":259,"context_line":"                # Replace"},{"line_number":260,"context_line":"                xs_res[rc] \u003d amt"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_7479f4c5","line":257,"range":{"start_line":256,"start_character":0,"end_line":257,"end_character":55},"updated":"2017-10-26 17:28:30.000000000","message":"as you already checked that the rc is in the falvor_resource you don\u0027t need to be careful with the popping by providing the default None value.","commit_id":"b64291a479fa144ea17ada85b49204da4ae65452"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9202421619d9af883db29333d039a84ba0bc1039","unresolved":false,"context_lines":[{"line_number":256,"context_line":"            if rc in flavor_resources:"},{"line_number":257,"context_line":"                popped \u003d flavor_resources.pop(rc, None)"},{"line_number":258,"context_line":"            if amt:"},{"line_number":259,"context_line":"                # Replace"},{"line_number":260,"context_line":"                xs_res[rc] \u003d amt"},{"line_number":261,"context_line":"            else:"},{"line_number":262,"context_line":"                # Delete"},{"line_number":263,"context_line":"                xs_res.pop(rc, None)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_6f15a13f","line":260,"range":{"start_line":259,"start_character":0,"end_line":260,"end_character":32},"updated":"2017-10-26 17:28:30.000000000","message":"I don\u0027t get this. The amt is already equal to xs_res[rc] as you are iterating xs_res in the first place. So I don\u0027t see how this replace anything.","commit_id":"b64291a479fa144ea17ada85b49204da4ae65452"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9202421619d9af883db29333d039a84ba0bc1039","unresolved":false,"context_lines":[{"line_number":259,"context_line":"                # Replace"},{"line_number":260,"context_line":"                xs_res[rc] \u003d amt"},{"line_number":261,"context_line":"            else:"},{"line_number":262,"context_line":"                # Delete"},{"line_number":263,"context_line":"                xs_res.pop(rc, None)"},{"line_number":264,"context_line":"                # If this wasn\u0027t us deleting a standard resources, warn."},{"line_number":265,"context_line":"                if not popped:"},{"line_number":266,"context_line":"                    LOG.warning(\"Received an invalid ResourceClass \u0027%(key)s\u0027 \""}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_ef019106","line":263,"range":{"start_line":262,"start_character":0,"end_line":263,"end_character":36},"updated":"2017-10-26 17:28:30.000000000","message":"Does this mean that we delete items from xs_res where xs_res[rc] \u003d\u003d 0 ?","commit_id":"b64291a479fa144ea17ada85b49204da4ae65452"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9202421619d9af883db29333d039a84ba0bc1039","unresolved":false,"context_lines":[{"line_number":329,"context_line":"        # if it was given as zero."},{"line_number":330,"context_line":"        # Copy the keys so we can modify the dict in the loop"},{"line_number":331,"context_line":"        for group in list(ret):"},{"line_number":332,"context_line":"            if group.startswith(\u0027resources\u0027):"},{"line_number":333,"context_line":"                # Copy the items list so we can modify the dict in the loop."},{"line_number":334,"context_line":"                for rc, amt in list(ret[group].items()):"},{"line_number":335,"context_line":"                    popped \u003d False"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_148be067","line":332,"updated":"2017-10-26 17:28:30.000000000","message":"This could be avoided if the return value of _process_extra_specs_granular is more user friendly and separates the resource from the traits.","commit_id":"b64291a479fa144ea17ada85b49204da4ae65452"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9202421619d9af883db29333d039a84ba0bc1039","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        # Copy the keys so we can modify the dict in the loop"},{"line_number":331,"context_line":"        for group in list(ret):"},{"line_number":332,"context_line":"            if group.startswith(\u0027resources\u0027):"},{"line_number":333,"context_line":"                # Copy the items list so we can modify the dict in the loop."},{"line_number":334,"context_line":"                for rc, amt in list(ret[group].items()):"},{"line_number":335,"context_line":"                    popped \u003d False"},{"line_number":336,"context_line":"                    if rc in spec_resources:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_94deb03b","line":333,"updated":"2017-10-26 17:28:30.000000000","message":"We copy couple of things just to be able to modify the big dict in place. Would it be simpler to generate a new dict while processing the current one?\n\nAlso I think that some of the nesting is here because we want to solve everything in one iteration. If this is performance sensitive then I would agree with this approach but I think it is not the case. I feel that it would be more readable as a sequence of small loops instead of one big one.\n1) get the resource we want to work with\n2) add standard resource from the flavor field that are not in the extra spec\n3) remove resources that has 0 amount\n4) delete empty groups","commit_id":"b64291a479fa144ea17ada85b49204da4ae65452"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9202421619d9af883db29333d039a84ba0bc1039","unresolved":false,"context_lines":[{"line_number":338,"context_line":"                    # Always delete zeroed entries from the return dict"},{"line_number":339,"context_line":"                    if amt \u003d\u003d 0:"},{"line_number":340,"context_line":"                        if popped:"},{"line_number":341,"context_line":"                            LOG.debug("},{"line_number":342,"context_line":"                                \"Deleting standard resource %(rc)s from \""},{"line_number":343,"context_line":"                                \"request spec because it was zeroed in \""},{"line_number":344,"context_line":"                                \"extra_specs.\", {\"rc\": rc})"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_34bedcfe","line":341,"updated":"2017-10-26 17:28:30.000000000","message":"This is the 6th level of nesting in this function. There should be a way to help the future reader by refactoring this  a bit.","commit_id":"b64291a479fa144ea17ada85b49204da4ae65452"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2e8bb3e571ee24568416fdf9a1cec2b47329d19e","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        for rg in self._rg_by_id.values():"},{"line_number":160,"context_line":"            yield rg.resources"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    def merged_resources(self):"},{"line_number":163,"context_line":"        \"\"\"Returns a merge of {resource_class: amount} for all resource groups."},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"        Amounts of the same resource class from different groups are added"}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_327589fb","line":162,"range":{"start_line":162,"start_character":8,"end_line":162,"end_character":24},"updated":"2017-10-30 14:37:51.000000000","message":"we could even call it flatten_resource_groups but that is just bikeshedding on naming.","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2e8bb3e571ee24568416fdf9a1cec2b47329d19e","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        \"\"\""},{"line_number":170,"context_line":"        ret \u003d {}"},{"line_number":171,"context_line":"        for resource_dict in self.resource_groups():"},{"line_number":172,"context_line":"            for rclass in set(ret) | set(resource_dict):"},{"line_number":173,"context_line":"                ret[rclass] \u003d ret.get(rclass, 0) + resource_dict.get(rclass, 0)"},{"line_number":174,"context_line":"        return ret"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def _clean_empties(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_d22e35f9","line":173,"range":{"start_line":172,"start_character":0,"end_line":173,"end_character":79},"updated":"2017-10-30 14:37:51.000000000","message":"This does a bit more addition that is needed as it does ret[rclass] +\u003d 0 even if resource_dict does not contain the rclass. I guess here using ret \u003d defaultdict(int) could help.\n\n    ret \u003d collections.defaultdict(int)\n    for group in self.resource_groups():\n        for resource_class, resource_amount in group.items():\n            ret[resource_class] +\u003d resource_amount\n    return ret","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"5ed7885dd97ad8aea102ccce2ee435e1553e8d1d","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        \"\"\""},{"line_number":170,"context_line":"        ret \u003d {}"},{"line_number":171,"context_line":"        for resource_dict in self.resource_groups():"},{"line_number":172,"context_line":"            for rclass in set(ret) | set(resource_dict):"},{"line_number":173,"context_line":"                ret[rclass] \u003d ret.get(rclass, 0) + resource_dict.get(rclass, 0)"},{"line_number":174,"context_line":"        return ret"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def _clean_empties(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_21451c16","line":173,"range":{"start_line":172,"start_character":0,"end_line":173,"end_character":79},"in_reply_to":"3f4b6375_a807cc18","updated":"2017-10-31 10:40:51.000000000","message":"Sorry for not being clear above. It took me a while to understand why your code needs to iterate not only the keys of the resource_dict but also the keys of the return value. Then I figured out that iterating on the keys in ret is not even needed as we want to add in amounts coming from the resource_dict to the ret dict. Therefore I think the \u0027set(ret) | \u0027 can be removed. Then using get(rclass, 0) or using defaultdict is just a matter of style. If you want to define the default value more explicitly then you can say\n\n   ret \u003d defaultdict(lambda:0)","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fa673d184d19f98e6369322b03a50645ebdff102","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        \"\"\""},{"line_number":170,"context_line":"        ret \u003d {}"},{"line_number":171,"context_line":"        for resource_dict in self.resource_groups():"},{"line_number":172,"context_line":"            for rclass in set(ret) | set(resource_dict):"},{"line_number":173,"context_line":"                ret[rclass] \u003d ret.get(rclass, 0) + resource_dict.get(rclass, 0)"},{"line_number":174,"context_line":"        return ret"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def _clean_empties(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_a807cc18","line":173,"range":{"start_line":172,"start_character":0,"end_line":173,"end_character":79},"in_reply_to":"3f4b6375_d22e35f9","updated":"2017-10-30 20:22:59.000000000","message":"Is your objection that the code is inefficient, or that it\u0027s ugly?  If the former, I kinda doubt the overhead of .get(rclass, 0) is higher than the overhead of the defaultdict.  If the latter, I\u0027m a bit ooked out by exploiting the fact that int() is zero, which seems like a pretty esoteric nuance.","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2e8bb3e571ee24568416fdf9a1cec2b47329d19e","unresolved":false,"context_lines":[{"line_number":186,"context_line":"                if resource_dict[rclass] \u003d\u003d 0:"},{"line_number":187,"context_line":"                    resource_dict.pop(rclass)"},{"line_number":188,"context_line":"        self._clean_empties()"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"def build_request_spec(ctxt, image, instances, instance_type\u003dNone):"},{"line_number":192,"context_line":"    \"\"\"Build a request_spec for the scheduler."}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_324ea9c1","line":189,"updated":"2017-10-30 14:37:51.000000000","message":"+1 on the small functions. Now it is a lot easier to comprehend for me what is happening.","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fa673d184d19f98e6369322b03a50645ebdff102","unresolved":false,"context_lines":[{"line_number":186,"context_line":"                if resource_dict[rclass] \u003d\u003d 0:"},{"line_number":187,"context_line":"                    resource_dict.pop(rclass)"},{"line_number":188,"context_line":"        self._clean_empties()"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"def build_request_spec(ctxt, image, instances, instance_type\u003dNone):"},{"line_number":192,"context_line":"    \"\"\"Build a request_spec for the scheduler."}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_6811d453","line":189,"in_reply_to":"3f4b6375_324ea9c1","updated":"2017-10-30 20:22:59.000000000","message":"I agree, thank you for the suggestion.","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2e8bb3e571ee24568416fdf9a1cec2b47329d19e","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        # shared RPs are in play."},{"line_number":257,"context_line":"        xs_resources \u003d ResourceRequest.from_extra_specs("},{"line_number":258,"context_line":"            flavor.extra_specs).merged_resources()"},{"line_number":259,"context_line":"        for resource_class, amount in resources.items():"},{"line_number":260,"context_line":"            # If it\u0027s in there - even if zero - ignore the one from the flavor."},{"line_number":261,"context_line":"            if resource_class not in xs_resources:"},{"line_number":262,"context_line":"                xs_resources[resource_class] \u003d amount"},{"line_number":263,"context_line":"        # Now strip zeros"},{"line_number":264,"context_line":"        resources \u003d {rc: amt for rc, amt in xs_resources.items() if amt}"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"    return resources"},{"line_number":267,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_0f038a11","line":264,"range":{"start_line":259,"start_character":1,"end_line":264,"end_character":72},"updated":"2017-10-30 14:37:51.000000000","message":"This could be function of the ResourceRequest object like, merge_flavor_resources() that reuses the strip_zeros() function.","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fa673d184d19f98e6369322b03a50645ebdff102","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        # shared RPs are in play."},{"line_number":257,"context_line":"        xs_resources \u003d ResourceRequest.from_extra_specs("},{"line_number":258,"context_line":"            flavor.extra_specs).merged_resources()"},{"line_number":259,"context_line":"        for resource_class, amount in resources.items():"},{"line_number":260,"context_line":"            # If it\u0027s in there - even if zero - ignore the one from the flavor."},{"line_number":261,"context_line":"            if resource_class not in xs_resources:"},{"line_number":262,"context_line":"                xs_resources[resource_class] \u003d amount"},{"line_number":263,"context_line":"        # Now strip zeros"},{"line_number":264,"context_line":"        resources \u003d {rc: amt for rc, amt in xs_resources.items() if amt}"},{"line_number":265,"context_line":""},{"line_number":266,"context_line":"    return resources"},{"line_number":267,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_085f000f","line":264,"range":{"start_line":259,"start_character":1,"end_line":264,"end_character":72},"in_reply_to":"3f4b6375_0f038a11","updated":"2017-10-30 20:22:59.000000000","message":"Sort of.  I did consider that, but the usage is different *enough* to make that impractical.  To make strip_zeros work, I would have to convert the dict from merged_resources into a ResourceRequest object itself.\n\nHowever, I can fold this functionality into merged_resources itself with a kwarg.","commit_id":"c09fb805ec6be26fb09144fd3e53d85535dff575"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d9b0f3532c29038e7388a75356f6d6e5be258cb7","unresolved":false,"context_lines":[{"line_number":173,"context_line":"        \"\"\""},{"line_number":174,"context_line":"        ret \u003d {}"},{"line_number":175,"context_line":"        for resource_dict in self.resource_groups():"},{"line_number":176,"context_line":"            for rclass in set(ret) | set(resource_dict):"},{"line_number":177,"context_line":"                ret[rclass] \u003d ret.get(rclass, 0) + resource_dict.get(rclass, 0)"},{"line_number":178,"context_line":"        if flavor_resources:"},{"line_number":179,"context_line":"            for resource_class, amount in flavor_resources.items():"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_8134d04b","line":176,"range":{"start_line":176,"start_character":26,"end_line":176,"end_character":36},"updated":"2017-10-31 10:51:20.000000000","message":"I think this is not needed. See my comment in PS6","commit_id":"e8c4f3ad5f7bdc329a0956f14b75bd1c7cd839bf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"79db18602e3fe40b45332773424ac0a6acf2f284","unresolved":false,"context_lines":[{"line_number":173,"context_line":"        \"\"\""},{"line_number":174,"context_line":"        ret \u003d {}"},{"line_number":175,"context_line":"        for resource_dict in self.resource_groups():"},{"line_number":176,"context_line":"            for rclass in set(ret) | set(resource_dict):"},{"line_number":177,"context_line":"                ret[rclass] \u003d ret.get(rclass, 0) + resource_dict.get(rclass, 0)"},{"line_number":178,"context_line":"        if flavor_resources:"},{"line_number":179,"context_line":"            for resource_class, amount in flavor_resources.items():"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_16e6e145","line":176,"range":{"start_line":176,"start_character":26,"end_line":176,"end_character":36},"in_reply_to":"3f4b6375_8134d04b","updated":"2017-10-31 13:56:42.000000000","message":"Oh, I see - ret is empty coming into this loop.  (That must have been a holdover from some interim rev where I was folding in the flavor resources at the same time.)\n\nAnd I dig the lambda:0 idea.\n\nWill fix.","commit_id":"e8c4f3ad5f7bdc329a0956f14b75bd1c7cd839bf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d9b0f3532c29038e7388a75356f6d6e5be258cb7","unresolved":false,"context_lines":[{"line_number":181,"context_line":"                # flavor."},{"line_number":182,"context_line":"                if resource_class not in ret:"},{"line_number":183,"context_line":"                    ret[resource_class] \u003d amount"},{"line_number":184,"context_line":"            # Now strip zeros.  This has to be done after the above - we can\u0027t"},{"line_number":185,"context_line":"            # use strip_zeros :("},{"line_number":186,"context_line":"            ret \u003d {rc: amt for rc, amt in ret.items() if amt}"},{"line_number":187,"context_line":"        return ret"},{"line_number":188,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_818290c7","line":185,"range":{"start_line":184,"start_character":0,"end_line":185,"end_character":32},"updated":"2017-10-31 10:51:20.000000000","message":"I see the reason now. Don\u0027t worry about it :)","commit_id":"e8c4f3ad5f7bdc329a0956f14b75bd1c7cd839bf"}],"nova/tests/unit/scheduler/client/test_report.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"646d5d1dbd02918b33232f8c47454e0289153a62","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"3f4b6375_d8643de8","updated":"2017-10-27 17:50:28.000000000","message":"whoops, missed these","commit_id":"2cd3c413748d8d8e6127946d5f8f2527c10e4d4a"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"e3865d7c5479e31ae725d44cbe38ce70195a732e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"3f4b6375_1881b54b","in_reply_to":"3f4b6375_d8643de8","updated":"2017-10-27 17:51:19.000000000","message":"Done","commit_id":"2cd3c413748d8d8e6127946d5f8f2527c10e4d4a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cb86145714fa4d9cdd526d1de67a99beb91ebfd6","unresolved":false,"context_lines":[{"line_number":1180,"context_line":"            \u0027resources:MEMORY_MB\u0027: \u00271024\u0027,"},{"line_number":1181,"context_line":"            \u0027resources1:DISK_GB\u0027: \u002730\u0027,"},{"line_number":1182,"context_line":"            \u0027trait:CUSTOM_TRAIT1\u0027: \u0027required\u0027,"},{"line_number":1183,"context_line":"            \u0027trait:CUSTOM_TRAIT2\u0027: \u0027preferred\u0027,"},{"line_number":1184,"context_line":"        })"},{"line_number":1185,"context_line":""},{"line_number":1186,"context_line":"        resp_mock.json.return_value \u003d json_data"}],"source_content_type":"text/x-python","patch_set":12,"id":"3f4b6375_35d5c51c","line":1183,"updated":"2017-11-06 15:39:40.000000000","message":"please remove this one since we do not yet support anything other than required traits.","commit_id":"78167bfae3e4a6f70a3bd288b184f519d2bebc93"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fc8ca3bc80e7f65e9f6fe9e53c6c612c8e04912b","unresolved":false,"context_lines":[{"line_number":1180,"context_line":"            \u0027resources:MEMORY_MB\u0027: \u00271024\u0027,"},{"line_number":1181,"context_line":"            \u0027resources1:DISK_GB\u0027: \u002730\u0027,"},{"line_number":1182,"context_line":"            \u0027trait:CUSTOM_TRAIT1\u0027: \u0027required\u0027,"},{"line_number":1183,"context_line":"            \u0027trait:CUSTOM_TRAIT2\u0027: \u0027preferred\u0027,"},{"line_number":1184,"context_line":"        })"},{"line_number":1185,"context_line":""},{"line_number":1186,"context_line":"        resp_mock.json.return_value \u003d json_data"}],"source_content_type":"text/x-python","patch_set":12,"id":"3f4b6375_551a81c5","line":1183,"in_reply_to":"3f4b6375_35d5c51c","updated":"2017-11-06 15:53:49.000000000","message":"That\u0027s totally the point: the code is currently ignoring numbered groupings and all traits.  This (kind of) test case will continue to be relevant because we\u0027ll continue to deliberately ignore (with warning log) anything that\u0027s not spelled the way we expect it.","commit_id":"78167bfae3e4a6f70a3bd288b184f519d2bebc93"}],"nova/tests/unit/scheduler/test_utils.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9202421619d9af883db29333d039a84ba0bc1039","unresolved":false,"context_lines":[{"line_number":156,"context_line":"                         \u0027resources1:VGPU_DISPLAY_HEAD\u0027: \u00272\u0027,"},{"line_number":157,"context_line":"                         # Replace"},{"line_number":158,"context_line":"                         \u0027resources3:VCPU\u0027: \u00272\u0027,"},{"line_number":159,"context_line":"                         # Stay separate (don\u0027t sum)"},{"line_number":160,"context_line":"                         \u0027resources42:SRIOV_NET_VF\u0027: \u00271\u0027,"},{"line_number":161,"context_line":"                         \u0027resources24:SRIOV_NET_VF\u0027: \u00272\u0027,"},{"line_number":162,"context_line":"                         # Ignore"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_efd4f149","line":159,"range":{"start_line":159,"start_character":25,"end_line":159,"end_character":52},"updated":"2017-10-26 17:28:30.000000000","message":"Note to the other reviewers: It is not summed as resources_from_request_spec() doesn\u0027t sum at all, it is the resources_from_flavor() that sums.","commit_id":"b64291a479fa144ea17ada85b49204da4ae65452"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d9b0f3532c29038e7388a75356f6d6e5be258cb7","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            \u0027DISK_GB\u0027: 5,"},{"line_number":388,"context_line":"        }"},{"line_number":389,"context_line":"        expected._rg_by_id[\u00273\u0027] \u003d rg"},{"line_number":390,"context_line":""},{"line_number":391,"context_line":"        self.assertResourceRequestsEqual("},{"line_number":392,"context_line":"            expected, utils.ResourceRequest.from_extra_specs(extra_specs))"},{"line_number":393,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_2183dcab","line":390,"updated":"2017-10-31 10:51:20.000000000","message":"nit: seems unrelated.","commit_id":"e8c4f3ad5f7bdc329a0956f14b75bd1c7cd839bf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"79db18602e3fe40b45332773424ac0a6acf2f284","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            \u0027DISK_GB\u0027: 5,"},{"line_number":388,"context_line":"        }"},{"line_number":389,"context_line":"        expected._rg_by_id[\u00273\u0027] \u003d rg"},{"line_number":390,"context_line":""},{"line_number":391,"context_line":"        self.assertResourceRequestsEqual("},{"line_number":392,"context_line":"            expected, utils.ResourceRequest.from_extra_specs(extra_specs))"},{"line_number":393,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_5621f94c","line":390,"in_reply_to":"3f4b6375_2183dcab","updated":"2017-10-31 13:56:42.000000000","message":"Yah, must have got caught in the rebase crossfire, will fix.","commit_id":"e8c4f3ad5f7bdc329a0956f14b75bd1c7cd839bf"}]}
