)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"3b889193cdf566789b871817f7ca21048c417a38","unresolved":false,"context_lines":[{"line_number":3,"context_line":"AuthorDate: 2019-06-21 19:53:15 +0100"},{"line_number":4,"context_line":"Commit:     Sean Mooney \u003cwork@seanmooney.info\u003e"},{"line_number":5,"context_line":"CommitDate: 2019-07-15 11:44:46 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"[WIP] Libvirt: report storage bus traits"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change add dynamic trait reporting based on the currently"},{"line_number":10,"context_line":"enabled virt type."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"7faddb67_c1d4c5eb","line":7,"range":{"start_line":6,"start_character":0,"end_line":7,"end_character":5},"updated":"2019-07-15 16:29:50.000000000","message":"i can proably drop this at this point.\ni think this patch is fine as it is. the next patch extend it and using the new domcap api instead which should be more accurate but approch is still correct.","commit_id":"c274e6011abae2c0669df73307c16ae19df19b6c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9d3768079ea6e03fa319c38e0f2c2da39338ea6d","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Libvirt: report storage bus traits"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change add dynamic trait reporting based on the currently"},{"line_number":10,"context_line":"enabled virt type."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I1c31cfd317d089026fa30d401157f661b6049cd3"},{"line_number":13,"context_line":"Partial-Implements: blueprint image-metadata-prefiltering"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"7faddb67_48bd38d6","line":10,"range":{"start_line":9,"start_character":0,"end_line":10,"end_character":18},"updated":"2019-08-19 23:34:29.000000000","message":"TODO i need to update the commit to mention the intoduction of the traits cache and flatten iterable methods.","commit_id":"2254b5fcd30421eb5c53258867b3825cd08732ce"},{"author":{"_account_id":10135,"name":"Lee Yarwood","display_name":"Lee Yarwood","email":"lyarwood@redhat.com","username":"lyarwood"},"change_message_id":"10b24e058b209e9b214da6f3f6ca995955cc5321","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Sean Mooney \u003cwork@seanmooney.info\u003e"},{"line_number":5,"context_line":"CommitDate: 2019-10-07 20:29:24 +0100"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Libvirt: report storage bus traits"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change adds dynamic trait reporting based on the currently"},{"line_number":10,"context_line":"enabled virt type. To simplify that and follow-up patches,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"3fa7e38b_2c00be35","line":7,"range":{"start_line":7,"start_character":16,"end_line":7,"end_character":23},"updated":"2019-11-07 12:44:13.000000000","message":"Any reason for using storage over disk bus here? AFAIK we only refer to the latter at the moment in terms of code and extra specs.","commit_id":"c7df461050aa12e3f63490019f2e47cf0bfdc42a"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"3d7bc657199bc21ed4f351abee3b5f58e3da03e6","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Sean Mooney \u003cwork@seanmooney.info\u003e"},{"line_number":5,"context_line":"CommitDate: 2019-10-07 20:29:24 +0100"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Libvirt: report storage bus traits"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change adds dynamic trait reporting based on the currently"},{"line_number":10,"context_line":"enabled virt type. To simplify that and follow-up patches,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"3fa7e38b_ac2d8eaf","line":7,"range":{"start_line":7,"start_character":16,"end_line":7,"end_character":23},"in_reply_to":"3fa7e38b_2c00be35","updated":"2019-11-07 12:53:40.000000000","message":"we have a commone set of traits for the hw_disk_bus and hw_cdrom_bus image properties so i chose storage as the common name for both\n\nhttps://github.com/openstack/os-traits/blob/master/os_traits/compute/storage.py","commit_id":"c7df461050aa12e3f63490019f2e47cf0bfdc42a"},{"author":{"_account_id":10135,"name":"Lee Yarwood","display_name":"Lee Yarwood","email":"lyarwood@redhat.com","username":"lyarwood"},"change_message_id":"c8f79c4c3f0103129bda1700fab435c4c5e41653","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Sean Mooney \u003cwork@seanmooney.info\u003e"},{"line_number":5,"context_line":"CommitDate: 2019-10-07 20:29:24 +0100"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Libvirt: report storage bus traits"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change adds dynamic trait reporting based on the currently"},{"line_number":10,"context_line":"enabled virt type. To simplify that and follow-up patches,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"3fa7e38b_c261b1aa","line":7,"range":{"start_line":7,"start_character":16,"end_line":7,"end_character":23},"in_reply_to":"3fa7e38b_ac2d8eaf","updated":"2019-11-07 14:43:22.000000000","message":"Ah! I thought you would have a reason, thanks Sean.","commit_id":"c7df461050aa12e3f63490019f2e47cf0bfdc42a"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"a21790749cc3564adfe00b1b296cfbd0cda5027f","unresolved":false,"context_lines":[{"line_number":7,"context_line":"libvirt: Report storage bus traits"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change adds dynamic trait reporting based on the currently"},{"line_number":10,"context_line":"enabled virt type. To simplify that and follow-up patches,"},{"line_number":11,"context_line":"this change also introduces a traits cache for caching"},{"line_number":12,"context_line":"trait validation, and a number of helper functions."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I1c31cfd317d089026fa30d401157f661b6049cd3"},{"line_number":15,"context_line":"Partially-Implements: blueprint image-metadata-prefiltering"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":20,"id":"3fa7e38b_b35b7f5f","line":12,"range":{"start_line":10,"start_character":19,"end_line":12,"end_character":51},"updated":"2020-02-20 17:07:06.000000000","message":"This is no longer true","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"}],"nova/tests/unit/test_utils.py":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9ed6e9260c4d67e0846740c430acc7df6f68bcea","unresolved":false,"context_lines":[{"line_number":249,"context_line":""},{"line_number":250,"context_line":"    def test_flatten_iterable(self):"},{"line_number":251,"context_line":"        data \u003d [[1, 2], [3, 4]]"},{"line_number":252,"context_line":"        expected \u003d [1, 2, 3, 4]"},{"line_number":253,"context_line":"        self.assertIsInstance(utils.flatten_iterable(data), list)"},{"line_number":254,"context_line":"        self.assertEqual(expected, utils.flatten_iterable(data))"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_9f7a1a23","line":252,"updated":"2019-08-26 14:09:53.000000000","message":"honestly, transforming lists into sets and unioning them would make the deal too without getting too much confusion.... and would also prevent duplicate entries :)\n \u003e\u003e\u003e a \u003d [2, 3]\n \u003e\u003e\u003e b \u003d [3, 4]\n \u003e\u003e\u003e set(a).union(set(b))\n {2, 3, 4}","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"694cc336c867ef33889b2066b5dd285b78dcf226","unresolved":false,"context_lines":[{"line_number":249,"context_line":""},{"line_number":250,"context_line":"    def test_flatten_iterable(self):"},{"line_number":251,"context_line":"        data \u003d [[1, 2], [3, 4]]"},{"line_number":252,"context_line":"        expected \u003d [1, 2, 3, 4]"},{"line_number":253,"context_line":"        self.assertIsInstance(utils.flatten_iterable(data), list)"},{"line_number":254,"context_line":"        self.assertEqual(expected, utils.flatten_iterable(data))"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_f36ee5fe","line":252,"in_reply_to":"7faddb67_9f7a1a23","updated":"2019-08-26 17:24:41.000000000","message":"it would but i wanted to add a generic helper function that could be used to replace the other place we do this as we keep doing it slowly with different code.\n\nso i wanted to have a fast way to do it in a untility funtion and then just always use that.\n\nas i said in my other respoce i think ill just make it a generator since that will will be ease to read and fast.","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"}],"nova/tests/unit/virt/libvirt/test_driver.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fc13af0fba444bded1a6b3e53186b1b5f2727be9","unresolved":false,"context_lines":[{"line_number":23084,"context_line":"            for bus in buses:"},{"line_number":23085,"context_line":"                trait \u003d f\u0027COMPUTE_STORAGE_BUS_{bus.upper()}\u0027"},{"line_number":23086,"context_line":"                self.assertIn(trait, bus_traits)"},{"line_number":23087,"context_line":"                self.assertTrue(bus_traits[trait])"},{"line_number":23088,"context_line":"                all_traits.add(trait)"},{"line_number":23089,"context_line":""},{"line_number":23090,"context_line":"        # ..and all the traits reported are valid os_trait traits"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_76ae55a2","line":23087,"updated":"2020-02-20 17:30:56.000000000","message":"This doesn\u0027t validate that the unsupported traits are present and False.\n\nThis is one of those cases where it\u0027s hard to unit test without the test simply reproducing the logic of the method being tested.\n\nWhat if we used ot.get_traits(\u0027COMPUTE_STORAGE_BUS_\u0027) as the list of all_traits? Then we could assert ``trait in all_traits`` here rather than below, and also check for the False ones.","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"6c70e23877dd294e430297b072d5eeced2ee848c","unresolved":false,"context_lines":[{"line_number":23084,"context_line":"            for bus in buses:"},{"line_number":23085,"context_line":"                trait \u003d f\u0027COMPUTE_STORAGE_BUS_{bus.upper()}\u0027"},{"line_number":23086,"context_line":"                self.assertIn(trait, bus_traits)"},{"line_number":23087,"context_line":"                self.assertTrue(bus_traits[trait])"},{"line_number":23088,"context_line":"                all_traits.add(trait)"},{"line_number":23089,"context_line":""},{"line_number":23090,"context_line":"        # ..and all the traits reported are valid os_trait traits"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_d9b88ac2","line":23087,"in_reply_to":"3fa7e38b_76ae55a2","updated":"2020-02-21 17:49:27.000000000","message":"I don\u0027t think we can, since we don\u0027t necessarily report every one of the \u0027COMPUTE_STORAGE_BUS_*\u0027 traits. Aware of the gap too but figured this was good enough :)","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8ff46e6e9d19228c09e4658e753a8f07c5add1da","unresolved":false,"context_lines":[{"line_number":23084,"context_line":"            for bus in buses:"},{"line_number":23085,"context_line":"                trait \u003d f\u0027COMPUTE_STORAGE_BUS_{bus.upper()}\u0027"},{"line_number":23086,"context_line":"                self.assertIn(trait, bus_traits)"},{"line_number":23087,"context_line":"                self.assertTrue(bus_traits[trait])"},{"line_number":23088,"context_line":"                all_traits.add(trait)"},{"line_number":23089,"context_line":""},{"line_number":23090,"context_line":"        # ..and all the traits reported are valid os_trait traits"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_0f67b4bb","line":23087,"in_reply_to":"3fa7e38b_d9b88ac2","updated":"2020-02-21 20:03:59.000000000","message":"\u003e I don\u0027t think we can, since we don\u0027t necessarily report every one\n \u003e of the \u0027COMPUTE_STORAGE_BUS_*\u0027 traits.\n\nHm, if we don\u0027t, we should, shouldn\u0027t we? /me checks...\n\n...yeah, they\u0027re all there. It would have been pretty weird/bad if they weren\u0027t. To the extent that, IMO, adding the logic I suggest would serve as extra enforcement, ensuring that we keep our os-traits req up to date etc.","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fc13af0fba444bded1a6b3e53186b1b5f2727be9","unresolved":false,"context_lines":[{"line_number":23087,"context_line":"                self.assertTrue(bus_traits[trait])"},{"line_number":23088,"context_line":"                all_traits.add(trait)"},{"line_number":23089,"context_line":""},{"line_number":23090,"context_line":"        # ..and all the traits reported are valid os_trait traits"},{"line_number":23091,"context_line":"        valid_traits \u003d ot.check_traits(all_traits)"},{"line_number":23092,"context_line":"        self.assertEqual(len(all_traits), len(valid_traits[0]))"},{"line_number":23093,"context_line":"        self.assertEqual(0, len(valid_traits[1]))"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_f64c8541","line":23090,"range":{"start_line":23090,"start_character":50,"end_line":23090,"end_character":58},"updated":"2020-02-20 17:30:56.000000000","message":"os-traits","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"6c70e23877dd294e430297b072d5eeced2ee848c","unresolved":false,"context_lines":[{"line_number":23087,"context_line":"                self.assertTrue(bus_traits[trait])"},{"line_number":23088,"context_line":"                all_traits.add(trait)"},{"line_number":23089,"context_line":""},{"line_number":23090,"context_line":"        # ..and all the traits reported are valid os_trait traits"},{"line_number":23091,"context_line":"        valid_traits \u003d ot.check_traits(all_traits)"},{"line_number":23092,"context_line":"        self.assertEqual(len(all_traits), len(valid_traits[0]))"},{"line_number":23093,"context_line":"        self.assertEqual(0, len(valid_traits[1]))"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_b9a4aea5","line":23090,"range":{"start_line":23090,"start_character":50,"end_line":23090,"end_character":58},"in_reply_to":"3fa7e38b_f64c8541","updated":"2020-02-21 17:49:27.000000000","message":"Done","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8ff46e6e9d19228c09e4658e753a8f07c5add1da","unresolved":false,"context_lines":[{"line_number":23087,"context_line":"                self.assertTrue(bus_traits[trait])"},{"line_number":23088,"context_line":"                all_traits.add(trait)"},{"line_number":23089,"context_line":""},{"line_number":23090,"context_line":"        # ..and all the traits reported are valid os-trait traits"},{"line_number":23091,"context_line":"        valid_traits \u003d ot.check_traits(all_traits)"},{"line_number":23092,"context_line":"        self.assertEqual(len(all_traits), len(valid_traits[0]))"},{"line_number":23093,"context_line":"        self.assertEqual(0, len(valid_traits[1]))"}],"source_content_type":"text/x-python","patch_set":21,"id":"3fa7e38b_cf0e7cd7","line":23090,"range":{"start_line":23090,"start_character":53,"end_line":23090,"end_character":58},"updated":"2020-02-21 20:03:59.000000000","message":"traits","commit_id":"633616258523be9acbf445dada245cb1bd0eaa9a"}],"nova/utils.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c6d07068577ceccfb1ded7f1ae1a875618e061a2","unresolved":false,"context_lines":[{"line_number":1414,"context_line":"    # NOTE(sean-k-mooney): this should not be called directly"},{"line_number":1415,"context_line":"    # as the os_traits.check_traits call is non trivial as it"},{"line_number":1416,"context_line":"    # it needs to iterate over all the sub modules of os-traits"},{"line_number":1417,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1418,"context_line":"    global _TRAITS_CACHE"},{"line_number":1419,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"},{"line_number":1420,"context_line":"    return valid"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_484d3898","line":1417,"range":{"start_line":1417,"start_character":4,"end_line":1417,"end_character":56},"updated":"2019-08-20 03:32:22.000000000","message":"i should explain what this is doing in the comment too.","commit_id":"2254b5fcd30421eb5c53258867b3825cd08732ce"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9ed6e9260c4d67e0846740c430acc7df6f68bcea","unresolved":false,"context_lines":[{"line_number":1390,"context_line":""},{"line_number":1391,"context_line":""},{"line_number":1392,"context_line":"def flatten_iterable(iterable):"},{"line_number":1393,"context_line":"    \"\"\"Accepts an iterable of iterables and returns a list\"\"\""},{"line_number":1394,"context_line":"    return functools.reduce(operator.iconcat, iterable, [])"},{"line_number":1395,"context_line":""},{"line_number":1396,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_ffcd4eb7","line":1393,"updated":"2019-08-26 14:09:53.000000000","message":"It will technically takes all elements from the subiterable and will sum up them thanks to the iconcat method but since you pass an empty list, it will just return the single element.\na nit would be to ask for a better docstring since you don\u0027t explain which parameter types you expect of the subiterable and what kind of operation you will do in order to translate into a flatten list.","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"70b056ffcf8e6a9b4668752844328c0b67c59c3e","unresolved":false,"context_lines":[{"line_number":1390,"context_line":""},{"line_number":1391,"context_line":""},{"line_number":1392,"context_line":"def flatten_iterable(iterable):"},{"line_number":1393,"context_line":"    \"\"\"Accepts an iterable of iterables and returns a list\"\"\""},{"line_number":1394,"context_line":"    return functools.reduce(operator.iconcat, iterable, [])"},{"line_number":1395,"context_line":""},{"line_number":1396,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_356777ed","line":1393,"in_reply_to":"7faddb67_13edc18d","updated":"2019-08-27 10:08:00.000000000","message":"I\u0027m cool with this plan.\nAfter all, you can have some generators as parameters, so it would be sad to just return a container (list, set, etc.) instead.","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"694cc336c867ef33889b2066b5dd285b78dcf226","unresolved":false,"context_lines":[{"line_number":1390,"context_line":""},{"line_number":1391,"context_line":""},{"line_number":1392,"context_line":"def flatten_iterable(iterable):"},{"line_number":1393,"context_line":"    \"\"\"Accepts an iterable of iterables and returns a list\"\"\""},{"line_number":1394,"context_line":"    return functools.reduce(operator.iconcat, iterable, [])"},{"line_number":1395,"context_line":""},{"line_number":1396,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_13edc18d","line":1393,"in_reply_to":"7faddb67_ffcd4eb7","updated":"2019-08-26 17:24:41.000000000","message":"i have been debating makeing it simpler.\n\ni really want this to be able to take any iterable that contains sub iterable and retrun them\n\nto do that i have been thing of rewriting this as a generator function instead that will be simpler to read and similar in perfomace in most casess and possible faster in my current usecase.\n\ne.g\n\nfor inner in iterable:\n for item in inner:\n   yield item\n\n\nthen you can decide what data stucture you want to create as the caller by doing. set(flatten_iterable(date)) or list(flatten_iterable(date))\n\n\ni could spcalise for iterables of mapping/dicts to yeild the item touple so you can also do dict(flatten_iterable(date)) to flatten a list of dict.\n\n\nthis is really what i want this to do so that we can stop writing slow versions of this everywhere we use it.","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9ed6e9260c4d67e0846740c430acc7df6f68bcea","unresolved":false,"context_lines":[{"line_number":1406,"context_line":""},{"line_number":1407,"context_line":"# NOTE(sean-k-mooney): we initialize the traits cache with"},{"line_number":1408,"context_line":"# all standard traits so that we only have to check CUSTOM_"},{"line_number":1409,"context_line":"# traits at runtime."},{"line_number":1410,"context_line":"_reset_trait_cache()"},{"line_number":1411,"context_line":""},{"line_number":1412,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_5fbca205","line":1409,"updated":"2019-08-26 14:09:53.000000000","message":"*nods*","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9ed6e9260c4d67e0846740c430acc7df6f68bcea","unresolved":false,"context_lines":[{"line_number":1413,"context_line":"def _validate_trait(trait):"},{"line_number":1414,"context_line":"    # NOTE(sean-k-mooney): this should not be called directly"},{"line_number":1415,"context_line":"    # as the os_traits.check_traits call is non trivial as it"},{"line_number":1416,"context_line":"    # it needs to iterate over all the sub modules of os-traits"},{"line_number":1417,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1418,"context_line":"    global _TRAITS_CACHE"},{"line_number":1419,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_ff5b0ef3","line":1416,"updated":"2019-08-26 14:09:53.000000000","message":"a proper FIXME would consist in improving os_traits.check_traits then.","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"694cc336c867ef33889b2066b5dd285b78dcf226","unresolved":false,"context_lines":[{"line_number":1413,"context_line":"def _validate_trait(trait):"},{"line_number":1414,"context_line":"    # NOTE(sean-k-mooney): this should not be called directly"},{"line_number":1415,"context_line":"    # as the os_traits.check_traits call is non trivial as it"},{"line_number":1416,"context_line":"    # it needs to iterate over all the sub modules of os-traits"},{"line_number":1417,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1418,"context_line":"    global _TRAITS_CACHE"},{"line_number":1419,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_734995b5","line":1416,"in_reply_to":"7faddb67_ff5b0ef3","updated":"2019-08-26 17:24:41.000000000","message":"we this is not really a fixme but i guess it could be i just wanted to state why we do it this way","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9ed6e9260c4d67e0846740c430acc7df6f68bcea","unresolved":false,"context_lines":[{"line_number":1414,"context_line":"    # NOTE(sean-k-mooney): this should not be called directly"},{"line_number":1415,"context_line":"    # as the os_traits.check_traits call is non trivial as it"},{"line_number":1416,"context_line":"    # it needs to iterate over all the sub modules of os-traits"},{"line_number":1417,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1418,"context_line":"    global _TRAITS_CACHE"},{"line_number":1419,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"},{"line_number":1420,"context_line":"    return valid"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_df0bb2d2","line":1417,"updated":"2019-08-26 14:09:53.000000000","message":"that sounds a hack to me.","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"694cc336c867ef33889b2066b5dd285b78dcf226","unresolved":false,"context_lines":[{"line_number":1414,"context_line":"    # NOTE(sean-k-mooney): this should not be called directly"},{"line_number":1415,"context_line":"    # as the os_traits.check_traits call is non trivial as it"},{"line_number":1416,"context_line":"    # it needs to iterate over all the sub modules of os-traits"},{"line_number":1417,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1418,"context_line":"    global _TRAITS_CACHE"},{"line_number":1419,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"},{"line_number":1420,"context_line":"    return valid"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_f35d8579","line":1417,"in_reply_to":"7faddb67_df0bb2d2","updated":"2019-08-26 17:24:41.000000000","message":"its not. the check_traits fucntion takes a list of traits and returns a tuple contianing a list of the  valid traits in postion 0 and invalid traits in postion 1\n\nso a triat is valid if the invalid list is empty which is what this is doing.","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"70b056ffcf8e6a9b4668752844328c0b67c59c3e","unresolved":false,"context_lines":[{"line_number":1414,"context_line":"    # NOTE(sean-k-mooney): this should not be called directly"},{"line_number":1415,"context_line":"    # as the os_traits.check_traits call is non trivial as it"},{"line_number":1416,"context_line":"    # it needs to iterate over all the sub modules of os-traits"},{"line_number":1417,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1418,"context_line":"    global _TRAITS_CACHE"},{"line_number":1419,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"},{"line_number":1420,"context_line":"    return valid"}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_75f08ffe","line":1417,"in_reply_to":"7faddb67_f35d8579","updated":"2019-08-27 10:08:00.000000000","message":"Sure, I\u0027m just saying we\u0027re supposing that check_traits will always return this way.\nI\u0027m just saying (for code maintenance) that having some explicit attributes would help (and would raise some error in case the returned object changes).\neg.\n\n valid_traits, invalid_traits \u003d os_traits.check_traits([trait])\n valid \u003d (invalid_traits is None)","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"0e0b462e3ae54d89dd3c7ebfbaeda28068ae174f","unresolved":false,"context_lines":[{"line_number":29,"context_line":"import re"},{"line_number":30,"context_line":"import shutil"},{"line_number":31,"context_line":"import tempfile"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"from collections import Mapping"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"import eventlet"},{"line_number":36,"context_line":"from keystoneauth1 import exceptions as ks_exc"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_0e7908c4","line":33,"range":{"start_line":32,"start_character":0,"end_line":33,"end_character":31},"updated":"2019-08-27 12:58:41.000000000","message":"You can\u0027t do this. It\u0027s deprecated behavior that will be removed in Python 3.8. You need to do something like:\n\n  if hasattr(collections, \u0027abc\u0027):  # Python 3\n      from collections.abc import Mapping\n  else:  # Python 2\n      from collections import Mapping","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"6a82f5ed79420371f9e79a6f4bced26103984f4d","unresolved":false,"context_lines":[{"line_number":29,"context_line":"import re"},{"line_number":30,"context_line":"import shutil"},{"line_number":31,"context_line":"import tempfile"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"from collections import Mapping"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"import eventlet"},{"line_number":36,"context_line":"from keystoneauth1 import exceptions as ks_exc"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_e984a65f","line":33,"range":{"start_line":32,"start_character":0,"end_line":33,"end_character":31},"in_reply_to":"7faddb67_0e7908c4","updated":"2019-08-27 13:03:55.000000000","message":"ya you are right.\ni did come across that a few weeks ago.\nthat said we can run on 3.7 yet let alone 3.8\nthe unit test pass but the compute agent hange last time i checked. i think its an eventlet issue or libvirt-python.\n\nthat said yes i should use six to do the import properly","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"0e0b462e3ae54d89dd3c7ebfbaeda28068ae174f","unresolved":false,"context_lines":[{"line_number":1167,"context_line":"    return norm_name"},{"line_number":1168,"context_line":""},{"line_number":1169,"context_line":""},{"line_number":1170,"context_line":"def flatten_iterable(iterable):"},{"line_number":1171,"context_line":"    \"\"\"Accepts an iterable of iterables and and yields the sub items."},{"line_number":1172,"context_line":"       This is a generator function that support iterables of mapping (dict)"},{"line_number":1173,"context_line":"       and non mapping types such as lists, tuples and sets of iterables."}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_2e22c4bb","line":1170,"updated":"2019-08-27 12:58:41.000000000","message":"This only appears to have a single caller. Can you move it there rather than leaving it here? utils modules are a bit of a grab bag that should only be used when absolutely necessary, IMO.\n\nOn a related note, this is a _lot_ of code for that single caller, especially when you include the unit tests. If you really want to use the \u0027functools.reduce\u0027 approach from PS6 then do. I\u0027d prefer it to having to carry all this","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"6a82f5ed79420371f9e79a6f4bced26103984f4d","unresolved":false,"context_lines":[{"line_number":1167,"context_line":"    return norm_name"},{"line_number":1168,"context_line":""},{"line_number":1169,"context_line":""},{"line_number":1170,"context_line":"def flatten_iterable(iterable):"},{"line_number":1171,"context_line":"    \"\"\"Accepts an iterable of iterables and and yields the sub items."},{"line_number":1172,"context_line":"       This is a generator function that support iterables of mapping (dict)"},{"line_number":1173,"context_line":"       and non mapping types such as lists, tuples and sets of iterables."}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_095262df","line":1170,"in_reply_to":"7faddb67_2e22c4bb","updated":"2019-08-27 13:03:55.000000000","message":"it will have more and i want to remove exsiting use of sum for this kind of thing later.","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"4312275880f2cd578372f8792664873d31bbe37e","unresolved":false,"context_lines":[{"line_number":1169,"context_line":""},{"line_number":1170,"context_line":"def flatten_iterable(iterable):"},{"line_number":1171,"context_line":"    \"\"\"Accepts an iterable of iterables and and yields the sub items."},{"line_number":1172,"context_line":"       This is a generator function that support iterables of mapping (dict)"},{"line_number":1173,"context_line":"       and non mapping types such as lists, tuples and sets of iterables."},{"line_number":1174,"context_line":"    \"\"\""},{"line_number":1175,"context_line":"    outer \u003d iterable.values() if isinstance(iterable, Mapping) else iterable"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_1597db47","line":1172,"range":{"start_line":1172,"start_character":49,"end_line":1172,"end_character":76},"updated":"2019-08-27 10:16:14.000000000","message":"you should mention that you\u0027ll iterate over values in the case of dicts.","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"dcbab49c6e883a30a9ce4997644aa203e3485b85","unresolved":false,"context_lines":[{"line_number":1169,"context_line":""},{"line_number":1170,"context_line":"def flatten_iterable(iterable):"},{"line_number":1171,"context_line":"    \"\"\"Accepts an iterable of iterables and and yields the sub items."},{"line_number":1172,"context_line":"       This is a generator function that support iterables of mapping (dict)"},{"line_number":1173,"context_line":"       and non mapping types such as lists, tuples and sets of iterables."},{"line_number":1174,"context_line":"    \"\"\""},{"line_number":1175,"context_line":"    outer \u003d iterable.values() if isinstance(iterable, Mapping) else iterable"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_2b95d688","line":1172,"range":{"start_line":1172,"start_character":49,"end_line":1172,"end_character":76},"in_reply_to":"7faddb67_1597db47","updated":"2019-08-27 12:20:31.000000000","message":"yes ill add that.","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"4312275880f2cd578372f8792664873d31bbe37e","unresolved":false,"context_lines":[{"line_number":1172,"context_line":"       This is a generator function that support iterables of mapping (dict)"},{"line_number":1173,"context_line":"       and non mapping types such as lists, tuples and sets of iterables."},{"line_number":1174,"context_line":"    \"\"\""},{"line_number":1175,"context_line":"    outer \u003d iterable.values() if isinstance(iterable, Mapping) else iterable"},{"line_number":1176,"context_line":"    for inner in outer:"},{"line_number":1177,"context_line":"        for sub_item in inner:"},{"line_number":1178,"context_line":"            yield inner[sub_item] if isinstance(inner, Mapping) else sub_item"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_1514bbe8","line":1175,"range":{"start_line":1175,"start_character":12,"end_line":1175,"end_character":29},"updated":"2019-08-27 10:16:14.000000000","message":"bve careful, .values() doesn\u0027t return the same things between py2 and py3.\n\nFortunately, since you only use it for getting an iterator to loop over, that doesn\u0027t really change (but FWIW, I prefer using six.itervalues() for making this clear (at least till 2020 ;-) )","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"dcbab49c6e883a30a9ce4997644aa203e3485b85","unresolved":false,"context_lines":[{"line_number":1172,"context_line":"       This is a generator function that support iterables of mapping (dict)"},{"line_number":1173,"context_line":"       and non mapping types such as lists, tuples and sets of iterables."},{"line_number":1174,"context_line":"    \"\"\""},{"line_number":1175,"context_line":"    outer \u003d iterable.values() if isinstance(iterable, Mapping) else iterable"},{"line_number":1176,"context_line":"    for inner in outer:"},{"line_number":1177,"context_line":"        for sub_item in inner:"},{"line_number":1178,"context_line":"            yield inner[sub_item] if isinstance(inner, Mapping) else sub_item"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_6b7bce7a","line":1175,"range":{"start_line":1175,"start_character":12,"end_line":1175,"end_character":29},"in_reply_to":"7faddb67_1514bbe8","updated":"2019-08-27 12:20:31.000000000","message":"yes so do i but people have started objected to it.\n\nill refactor to use it.","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ab36060b6b9f3b316f2cc3c5aaa3b365985c6287","unresolved":false,"context_lines":[{"line_number":1164,"context_line":"    return norm_name"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":""},{"line_number":1167,"context_line":"_TRAITS_CACHE \u003d {}"},{"line_number":1168,"context_line":""},{"line_number":1169,"context_line":""},{"line_number":1170,"context_line":"def _reset_trait_cache():"}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_68765e0f","line":1167,"range":{"start_line":1167,"start_character":0,"end_line":1167,"end_character":18},"updated":"2019-08-28 09:10:53.000000000","message":"nit: it would be nice if this was at the top of the file with the other constants","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"50507259e13ee58dedf5635a5b91d1981e478afc","unresolved":false,"context_lines":[{"line_number":1164,"context_line":"    return norm_name"},{"line_number":1165,"context_line":""},{"line_number":1166,"context_line":""},{"line_number":1167,"context_line":"_TRAITS_CACHE \u003d {}"},{"line_number":1168,"context_line":""},{"line_number":1169,"context_line":""},{"line_number":1170,"context_line":"def _reset_trait_cache():"}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_b295a48a","line":1167,"range":{"start_line":1167,"start_character":0,"end_line":1167,"end_character":18},"in_reply_to":"7faddb67_68765e0f","updated":"2019-08-28 09:51:21.000000000","message":"i was trying to group it with the where it was used to keep the locality of the declaration and and use","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ab36060b6b9f3b316f2cc3c5aaa3b365985c6287","unresolved":false,"context_lines":[{"line_number":1174,"context_line":"    }"},{"line_number":1175,"context_line":""},{"line_number":1176,"context_line":""},{"line_number":1177,"context_line":"# NOTE(sean-k-mooney): we initialize the traits cache with"},{"line_number":1178,"context_line":"# all standard traits so that we only have to check CUSTOM_"},{"line_number":1179,"context_line":"# traits at runtime."},{"line_number":1180,"context_line":"_reset_trait_cache()"},{"line_number":1181,"context_line":""},{"line_number":1182,"context_line":""},{"line_number":1183,"context_line":"# NOTE(sean-k-mooney): this should not be called directly,"}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_288066bf","line":1180,"range":{"start_line":1177,"start_character":0,"end_line":1180,"end_character":20},"updated":"2019-08-28 09:10:53.000000000","message":"And this was at the bottom of the file where runtime stuff is usually placed. I wonder if we need to do this here, as opposed to on service startup or something?","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"50507259e13ee58dedf5635a5b91d1981e478afc","unresolved":false,"context_lines":[{"line_number":1174,"context_line":"    }"},{"line_number":1175,"context_line":""},{"line_number":1176,"context_line":""},{"line_number":1177,"context_line":"# NOTE(sean-k-mooney): we initialize the traits cache with"},{"line_number":1178,"context_line":"# all standard traits so that we only have to check CUSTOM_"},{"line_number":1179,"context_line":"# traits at runtime."},{"line_number":1180,"context_line":"_reset_trait_cache()"},{"line_number":1181,"context_line":""},{"line_number":1182,"context_line":""},{"line_number":1183,"context_line":"# NOTE(sean-k-mooney): this should not be called directly,"}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_92df4865","line":1180,"range":{"start_line":1177,"start_character":0,"end_line":1180,"end_character":20},"in_reply_to":"7faddb67_288066bf","updated":"2019-08-28 09:51:21.000000000","message":"it technically does not need to be called its just for efficiency i could condtionally call it in _validate_trait but then we would have to test teh if repeatedly.","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ab36060b6b9f3b316f2cc3c5aaa3b365985c6287","unresolved":false,"context_lines":[{"line_number":1190,"context_line":"    # input list and the second entry is the list of invalid traits."},{"line_number":1191,"context_line":"    # If the length of the second entry is 0 all traits were valid."},{"line_number":1192,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1193,"context_line":"    global _TRAITS_CACHE"},{"line_number":1194,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"},{"line_number":1195,"context_line":"    return valid"},{"line_number":1196,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_488362cc","line":1193,"range":{"start_line":1193,"start_character":0,"end_line":1193,"end_character":24},"updated":"2019-08-28 09:10:53.000000000","message":"nit: globals usually go at the top of the function","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"50507259e13ee58dedf5635a5b91d1981e478afc","unresolved":false,"context_lines":[{"line_number":1190,"context_line":"    # input list and the second entry is the list of invalid traits."},{"line_number":1191,"context_line":"    # If the length of the second entry is 0 all traits were valid."},{"line_number":1192,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1193,"context_line":"    global _TRAITS_CACHE"},{"line_number":1194,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"},{"line_number":1195,"context_line":"    return valid"},{"line_number":1196,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_924d083d","line":1193,"range":{"start_line":1193,"start_character":0,"end_line":1193,"end_character":24},"in_reply_to":"7faddb67_488362cc","updated":"2019-08-28 09:51:21.000000000","message":"ya i can move it if i resping. again it was a locaity thing\niw was intoducing the first use of the traits cache and then remembered since im writeing to it i need to \"import\" the global for writing by declaring it as a global.","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":1151,"context_line":"    return norm_name"},{"line_number":1152,"context_line":""},{"line_number":1153,"context_line":""},{"line_number":1154,"context_line":"def normalized_trait_name(prefix, suffix):"},{"line_number":1155,"context_line":"    \"\"\"Construct a normalised trait name from a prefix and suffix\"\"\""},{"line_number":1156,"context_line":"    # traits are not allowed to contain hyphens so we normalise"},{"line_number":1157,"context_line":"    # them to underscore. this is need for VIF_MODEL_SPAPR_VLAN"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_05ce85b6","line":1154,"range":{"start_line":1154,"start_character":13,"end_line":1154,"end_character":14},"updated":"2020-01-21 19:35:42.000000000","message":"nit: I would drop the \u0027d\u0027 and make the method name a verb like \"normal\".","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9c613d0f858d8f45ac8747df268e29fc561d3f0b","unresolved":false,"context_lines":[{"line_number":1151,"context_line":"    return norm_name"},{"line_number":1152,"context_line":""},{"line_number":1153,"context_line":""},{"line_number":1154,"context_line":"def normalized_trait_name(prefix, suffix):"},{"line_number":1155,"context_line":"    \"\"\"Construct a normalised trait name from a prefix and suffix\"\"\""},{"line_number":1156,"context_line":"    # traits are not allowed to contain hyphens so we normalise"},{"line_number":1157,"context_line":"    # them to underscore. this is need for VIF_MODEL_SPAPR_VLAN"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_fbe6b3db","line":1154,"range":{"start_line":1154,"start_character":13,"end_line":1154,"end_character":14},"in_reply_to":"3fa7e38b_05ce85b6","updated":"2020-02-20 14:43:09.000000000","message":"Killed this. It wasn\u0027t needed for what we\u0027re using and I could use utilities from os_traits to make sure our traits are valid.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":1157,"context_line":"    # them to underscore. this is need for VIF_MODEL_SPAPR_VLAN"},{"line_number":1158,"context_line":"    # but may be required for other traits in the future."},{"line_number":1159,"context_line":"    trait \u003d u\"{}_{}\".format(prefix, suffix)"},{"line_number":1160,"context_line":"    return re.sub(\u0027[^0-9A-Za-z]+\u0027, \u0027_\u0027, trait).upper()"},{"line_number":1161,"context_line":""},{"line_number":1162,"context_line":""},{"line_number":1163,"context_line":"# NOTE(sean-k-mooney): this should not be called directly,"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_c5514dd7","line":1160,"updated":"2020-01-21 19:35:42.000000000","message":"This method makes me sad.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9a574961a591dc984ac5ae603a55d72ca095c7e5","unresolved":false,"context_lines":[{"line_number":1157,"context_line":"    # them to underscore. this is need for VIF_MODEL_SPAPR_VLAN"},{"line_number":1158,"context_line":"    # but may be required for other traits in the future."},{"line_number":1159,"context_line":"    trait \u003d u\"{}_{}\".format(prefix, suffix)"},{"line_number":1160,"context_line":"    return re.sub(\u0027[^0-9A-Za-z]+\u0027, \u0027_\u0027, trait).upper()"},{"line_number":1161,"context_line":""},{"line_number":1162,"context_line":""},{"line_number":1163,"context_line":"# NOTE(sean-k-mooney): this should not be called directly,"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_e9f7838d","line":1160,"in_reply_to":"3fa7e38b_c5514dd7","updated":"2020-01-21 22:09:26.000000000","message":"this is basically normalize_name form os-traits\nbut i do not want it to prefix it with CUSTOM\nhttps://github.com/openstack/os-traits/blob/master/os_traits/__init__.py#L141-L157\n\ni could add this function to os-traits and then reimplement normalize name by calling this with CUSTOM as the prefix and name as the sufix.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":1161,"context_line":""},{"line_number":1162,"context_line":""},{"line_number":1163,"context_line":"# NOTE(sean-k-mooney): this should not be called directly,"},{"line_number":1164,"context_line":"# the os_traits.check_traits call is non trivial as it"},{"line_number":1165,"context_line":"# it needs to iterate over all the sub modules of os-traits"},{"line_number":1166,"context_line":"def _validate_trait(trait):"},{"line_number":1167,"context_line":"    # os_traits.check_traits takes a list of traits and"},{"line_number":1168,"context_line":"    # return a tuple of lists of traits. The first"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_6549792d","line":1165,"range":{"start_line":1164,"start_character":2,"end_line":1165,"end_character":59},"updated":"2020-01-21 19:35:42.000000000","message":"Big meh on this. If we need to do this level of caching (which I\u0027m not convinced is worthwhile in the first place), let\u0027s do it in os-traits.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9a574961a591dc984ac5ae603a55d72ca095c7e5","unresolved":false,"context_lines":[{"line_number":1161,"context_line":""},{"line_number":1162,"context_line":""},{"line_number":1163,"context_line":"# NOTE(sean-k-mooney): this should not be called directly,"},{"line_number":1164,"context_line":"# the os_traits.check_traits call is non trivial as it"},{"line_number":1165,"context_line":"# it needs to iterate over all the sub modules of os-traits"},{"line_number":1166,"context_line":"def _validate_trait(trait):"},{"line_number":1167,"context_line":"    # os_traits.check_traits takes a list of traits and"},{"line_number":1168,"context_line":"    # return a tuple of lists of traits. The first"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_2927db20","line":1165,"range":{"start_line":1164,"start_character":2,"end_line":1165,"end_character":59},"in_reply_to":"3fa7e38b_6549792d","updated":"2020-01-21 22:09:26.000000000","message":"i could put the cache in os-traits yes\n\nill do some simiple timeing tests and see if it makes sense.\n\nif i add the normalized_trait_name fucntion to os-triats the i could do this while im working on it.\n\nos-traits\u0027s api is intended for traits to be validate in sets not 1 by. given its main consumer was placement when that api was created itmakes sense since it was used to check if all the traits in a single request are valid.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"afd3f4a646184fe7ca829e16b7852127cdbf61e4","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"    # input list and the second entry is the list of invalid traits.i w"},{"line_number":1171,"context_line":"    # If the length of the second entry is 0 all traits were valid."},{"line_number":1172,"context_line":"    valid \u003d len(os_traits.check_traits([trait])[1]) \u003d\u003d 0"},{"line_number":1173,"context_line":"    global _TRAITS_CACHE"},{"line_number":1174,"context_line":"    _TRAITS_CACHE[trait] \u003d valid"},{"line_number":1175,"context_line":"    return valid"},{"line_number":1176,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_6ff71ad3","line":1173,"range":{"start_line":1173,"start_character":0,"end_line":1173,"end_character":24},"updated":"2020-01-21 17:34:08.000000000","message":"would be good to move this to the top of the function so it\u0027s obvious","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"afd3f4a646184fe7ca829e16b7852127cdbf61e4","unresolved":false,"context_lines":[{"line_number":1175,"context_line":"    return valid"},{"line_number":1176,"context_line":""},{"line_number":1177,"context_line":""},{"line_number":1178,"context_line":"def valid_trait(trait):"},{"line_number":1179,"context_line":"    \"\"\"\"Tests if  a trait is valid caching the result internally\"\"\""},{"line_number":1180,"context_line":"    valid \u003d _TRAITS_CACHE.get(trait)"},{"line_number":1181,"context_line":"    return valid or (valid is None and _validate_trait(trait))"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_2f2fe23e","line":1178,"range":{"start_line":1178,"start_character":4,"end_line":1178,"end_character":15},"updated":"2020-01-21 17:34:08.000000000","message":"\u0027is_valid_trait\u0027 would be preferable, IMO","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":1175,"context_line":"    return valid"},{"line_number":1176,"context_line":""},{"line_number":1177,"context_line":""},{"line_number":1178,"context_line":"def valid_trait(trait):"},{"line_number":1179,"context_line":"    \"\"\"\"Tests if  a trait is valid caching the result internally\"\"\""},{"line_number":1180,"context_line":"    valid \u003d _TRAITS_CACHE.get(trait)"},{"line_number":1181,"context_line":"    return valid or (valid is None and _validate_trait(trait))"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_25d38161","line":1178,"range":{"start_line":1178,"start_character":4,"end_line":1178,"end_character":15},"in_reply_to":"3fa7e38b_2f2fe23e","updated":"2020-01-21 19:35:42.000000000","message":"++","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"}],"nova/virt/libvirt/blockinfo.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"11e597c8fa108875bbaef95f168d2829d911198a","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    raise exception.TooManyDiskDevices(maximum\u003dmax_dev)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"VALID_STORAGE_BUS \u003d {"},{"line_number":204,"context_line":"        \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":205,"context_line":"        \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":206,"context_line":"        \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027],"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_81e4023e","line":203,"range":{"start_line":203,"start_character":0,"end_line":203,"end_character":17},"updated":"2019-08-09 11:25:39.000000000","message":"SUPPORTED_STORAGE_BUSES ?","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c71d71204541833fc8c41c2b333fd5a219741d3e","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    raise exception.TooManyDiskDevices(maximum\u003dmax_dev)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"VALID_STORAGE_BUS \u003d {"},{"line_number":204,"context_line":"        \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":205,"context_line":"        \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":206,"context_line":"        \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027],"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_d596313f","line":203,"range":{"start_line":203,"start_character":0,"end_line":203,"end_character":17},"in_reply_to":"7faddb67_81e4023e","updated":"2019-08-09 17:05:44.000000000","message":"there are other storage buses that are supported but not valid for the speficic virt type so i think valid is more correct\n\nit also matches the  nameing of the function and the previous usage of the variable","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"4d04bfd8eaa91b609fe972a37e8f84ac75360dce","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    raise exception.TooManyDiskDevices(maximum\u003dmax_dev)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"VALID_STORAGE_BUS \u003d {"},{"line_number":204,"context_line":"        \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":205,"context_line":"        \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":206,"context_line":"        \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027],"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_1f01e66a","line":203,"range":{"start_line":203,"start_character":0,"end_line":203,"end_character":17},"in_reply_to":"7faddb67_d596313f","updated":"2019-08-15 23:05:29.000000000","message":"Eh, depends on what you mean by supported. We\u0027re saying which buses are \"supported\" by each virt type","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9d3768079ea6e03fa319c38e0f2c2da39338ea6d","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    raise exception.TooManyDiskDevices(maximum\u003dmax_dev)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"VALID_STORAGE_BUS \u003d {"},{"line_number":204,"context_line":"        \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":205,"context_line":"        \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":206,"context_line":"        \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027],"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_e81d040f","line":203,"range":{"start_line":203,"start_character":0,"end_line":203,"end_character":17},"updated":"2019-08-19 23:34:29.000000000","message":"i might rename this to supported later but i want to rework the three patches first and then ill see what is more consistent.","commit_id":"2254b5fcd30421eb5c53258867b3825cd08732ce"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"694cc336c867ef33889b2066b5dd285b78dcf226","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    raise exception.TooManyDiskDevices(maximum\u003dmax_dev)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"VALID_STORAGE_BUS \u003d {"},{"line_number":204,"context_line":"        \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":205,"context_line":"        \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":206,"context_line":"        \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027],"}],"source_content_type":"text/x-python","patch_set":7,"id":"7faddb67_af6cebcf","line":203,"range":{"start_line":203,"start_character":0,"end_line":203,"end_character":17},"in_reply_to":"7faddb67_e81d040f","updated":"2019-08-26 17:24:41.000000000","message":"ok now that i have valid_trait functions ill rename this to supported since valid_trait checks if its a valid trait based on if its confroms to os-traits rules where as this is declaring what buses are supported by each virt driver.","commit_id":"2254b5fcd30421eb5c53258867b3825cd08732ce"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ab36060b6b9f3b316f2cc3c5aaa3b365985c6287","unresolved":false,"context_lines":[{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"SUPPORTED_STORAGE_BUSES \u003d {"},{"line_number":204,"context_line":"        \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":205,"context_line":"        \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":206,"context_line":"        \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027],"},{"line_number":207,"context_line":"        \u0027uml\u0027: [\u0027uml\u0027],"},{"line_number":208,"context_line":"        \u0027lxc\u0027: [\u0027lxc\u0027],"},{"line_number":209,"context_line":"        \u0027parallels\u0027: [\u0027ide\u0027, \u0027scsi\u0027]"},{"line_number":210,"context_line":"}"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_e869ee25","line":209,"range":{"start_line":204,"start_character":0,"end_line":209,"end_character":36},"updated":"2019-08-28 09:10:53.000000000","message":"nit: this should be dedented","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"50507259e13ee58dedf5635a5b91d1981e478afc","unresolved":false,"context_lines":[{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"SUPPORTED_STORAGE_BUSES \u003d {"},{"line_number":204,"context_line":"        \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":205,"context_line":"        \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":206,"context_line":"        \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027],"},{"line_number":207,"context_line":"        \u0027uml\u0027: [\u0027uml\u0027],"},{"line_number":208,"context_line":"        \u0027lxc\u0027: [\u0027lxc\u0027],"},{"line_number":209,"context_line":"        \u0027parallels\u0027: [\u0027ide\u0027, \u0027scsi\u0027]"},{"line_number":210,"context_line":"}"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_d26ce09e","line":209,"range":{"start_line":204,"start_character":0,"end_line":209,"end_character":36},"in_reply_to":"7faddb67_e869ee25","updated":"2019-08-28 09:51:21.000000000","message":"yes it can be.\nits still pep8 complent either way but i thinkits pretty\nclear form the diff why this is indented as it is :)\n\nill adress this if i respin this or the follow up patches.","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fc13af0fba444bded1a6b3e53186b1b5f2727be9","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    raise exception.TooManyDiskDevices(maximum\u003dmax_dev)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"# NOTE(aspiers): If you change this, don\u0027t forget to update the"},{"line_number":204,"context_line":"# docs and metadata for hw_*_bus in glance."},{"line_number":205,"context_line":"SUPPORTED_STORAGE_BUSES \u003d {"},{"line_number":206,"context_line":"    \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":207,"context_line":"    \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_f6b7a521","line":204,"range":{"start_line":203,"start_character":0,"end_line":204,"end_character":43},"updated":"2020-02-20 17:30:56.000000000","message":"Now that we\u0027re relying on it, can we beef up this comment along the lines of:\n\n # These bus names map directly to standard os-traits as:\n # \u0027foo\u0027 \u003d\u003e \u0027COMPUTE_STORAGE_BUS_FOO\u0027\n\nPossibly even adding:\n\n # If adding a new bus name, make sure the standard trait conforms\n # to this rule.","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"6c70e23877dd294e430297b072d5eeced2ee848c","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    raise exception.TooManyDiskDevices(maximum\u003dmax_dev)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"# NOTE(aspiers): If you change this, don\u0027t forget to update the"},{"line_number":204,"context_line":"# docs and metadata for hw_*_bus in glance."},{"line_number":205,"context_line":"SUPPORTED_STORAGE_BUSES \u003d {"},{"line_number":206,"context_line":"    \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":207,"context_line":"    \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_f9c8e64e","line":204,"range":{"start_line":203,"start_character":0,"end_line":204,"end_character":43},"in_reply_to":"3fa7e38b_f6b7a521","updated":"2020-02-21 17:49:27.000000000","message":"Done","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8ff46e6e9d19228c09e4658e753a8f07c5add1da","unresolved":false,"context_lines":[{"line_number":203,"context_line":"# NOTE(aspiers): If you change this, don\u0027t forget to update the docs and"},{"line_number":204,"context_line":"# metadata for hw_*_bus in glance. In addition, these bus names map directly to"},{"line_number":205,"context_line":"# standard os-traits as \u0027foo\u0027 \u003d\u003e \u0027COMPUTE_STORAGE_BUS_FOO\u0027. If adding a new bus"},{"line_number":206,"context_line":"# name, make sure the standard trait conforms to this rule."},{"line_number":207,"context_line":"SUPPORTED_STORAGE_BUSES \u003d {"},{"line_number":208,"context_line":"    \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":209,"context_line":"    \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"}],"source_content_type":"text/x-python","patch_set":21,"id":"3fa7e38b_4fe28cd5","line":206,"updated":"2020-02-21 20:03:59.000000000","message":"Following on from PS20:\n- If a new storage bus trait comes into existence, we must add it here and in os-traits at the same time. And...\n- if the new bus type isn\u0027t supported by the libvirt driver at all, we should add it here anyway (under a key like \u0027unsupported\u0027 or None) so the mapping we percolate up the stack is complete.\n\nIOW I\u0027m still asserting that os-traits and itertools.chain(*SUPPORTED_STORAGE_BUSES.values()) should match each other exactly, always, and adding test coverage for that is a good thing.","commit_id":"633616258523be9acbf445dada245cb1bd0eaa9a"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"29b69caef211191725c423e504d650dba0b418ea","unresolved":false,"context_lines":[{"line_number":203,"context_line":"# NOTE(aspiers): If you change this, don\u0027t forget to update the docs and"},{"line_number":204,"context_line":"# metadata for hw_*_bus in glance. In addition, these bus names map directly to"},{"line_number":205,"context_line":"# standard os-traits as \u0027foo\u0027 \u003d\u003e \u0027COMPUTE_STORAGE_BUS_FOO\u0027. If adding a new bus"},{"line_number":206,"context_line":"# name, make sure the standard trait conforms to this rule."},{"line_number":207,"context_line":"SUPPORTED_STORAGE_BUSES \u003d {"},{"line_number":208,"context_line":"    \u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"},{"line_number":209,"context_line":"    \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027],"}],"source_content_type":"text/x-python","patch_set":21,"id":"1fa4df85_bf164ba7","line":206,"in_reply_to":"3fa7e38b_4fe28cd5","updated":"2020-03-09 14:52:17.000000000","message":"that was not what i originally planned but i would be ok with an unsupported key.\n\nthis was intened to only be the subset of traits that is supported by libvirt and not a 1:1 mapping.\n\nthat is why this was change for valid to supported.\n\nthe unsupported values are valid but not supported which is why i would not expect .values to contain all traits know to os traits.\n\nin terms of adding new bus models the intent was to allways update os-triats first and have the nova change have a depends on against the os traits patch.","commit_id":"633616258523be9acbf445dada245cb1bd0eaa9a"}],"nova/virt/libvirt/driver.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"11e597c8fa108875bbaef95f168d2829d911198a","unresolved":false,"context_lines":[{"line_number":9639,"context_line":""},{"line_number":9640,"context_line":"        :return: A dict of trait names mapped to boolean values or None."},{"line_number":9641,"context_line":"        \"\"\""},{"line_number":9642,"context_line":"        valid_buses \u003d blockinfo.VALID_STORAGE_BUS.get("},{"line_number":9643,"context_line":"            CONF.libvirt.virt_type, [])"},{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_c1719a79","line":9642,"range":{"start_line":9642,"start_character":8,"end_line":9642,"end_character":19},"updated":"2019-08-09 11:25:39.000000000","message":"supported_buses?","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c71d71204541833fc8c41c2b333fd5a219741d3e","unresolved":false,"context_lines":[{"line_number":9639,"context_line":""},{"line_number":9640,"context_line":"        :return: A dict of trait names mapped to boolean values or None."},{"line_number":9641,"context_line":"        \"\"\""},{"line_number":9642,"context_line":"        valid_buses \u003d blockinfo.VALID_STORAGE_BUS.get("},{"line_number":9643,"context_line":"            CONF.libvirt.virt_type, [])"},{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_b59db558","line":9642,"range":{"start_line":9642,"start_character":8,"end_line":9642,"end_character":19},"in_reply_to":"7faddb67_c1719a79","updated":"2019-08-09 17:05:44.000000000","message":"no i think valid is better as i sed befer","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"11e597c8fa108875bbaef95f168d2829d911198a","unresolved":false,"context_lines":[{"line_number":9642,"context_line":"        valid_buses \u003d blockinfo.VALID_STORAGE_BUS.get("},{"line_number":9643,"context_line":"            CONF.libvirt.virt_type, [])"},{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_e145b616","line":9646,"range":{"start_line":9645,"start_character":0,"end_line":9646,"end_character":54},"updated":"2019-08-09 11:25:39.000000000","message":"You\u0027re being too clever by half :)\n\n  unsupported_buses \u003d [\n      x for x in sum(blockinfo.VALID_STORAGE_BUS.values(), [])\n      if x not in valid_buses]","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0d6fa86d010a9a4892d22010b4545e3675330960","unresolved":false,"context_lines":[{"line_number":9642,"context_line":"        valid_buses \u003d blockinfo.VALID_STORAGE_BUS.get("},{"line_number":9643,"context_line":"            CONF.libvirt.virt_type, [])"},{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_cd905d51","line":9646,"range":{"start_line":9645,"start_character":0,"end_line":9646,"end_character":54},"in_reply_to":"7faddb67_5fcc3e34","updated":"2019-08-19 19:29:33.000000000","message":"actully the list comprehention is slower\n\n\u003e\u003e\u003e timeit.timeit(\"{x for x in sum({\u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027], \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027], \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027], \u0027uml\u0027: [\u0027uml\u0027], \u0027lxc\u0027: [\u0027lxc\u0027], \u0027parallels\u0027: [\u0027ide\u0027, \u0027scsi\u0027]}.values(), [])}\", number\u003d1000000)\n1.5598978996276855\n\u003e\u003e\u003e timeit.timeit(\"import functools; import operator; set(functools.reduce(operator.iconcat, {\u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027], \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027], \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027], \u0027uml\u0027: [\u0027uml\u0027], \u0027lxc\u0027: [\u0027lxc\u0027], \u0027parallels\u0027: [\u0027ide\u0027, \u0027scsi\u0027]}.values(), []))\", number\u003d1000000)\n2.178863048553467\n\u003e\u003e\u003e timeit.timeit(\"import functools; import operator; {x for x in sum({\u0027qemu\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027], \u0027kvm\u0027: [\u0027virtio\u0027, \u0027scsi\u0027, \u0027ide\u0027, \u0027usb\u0027, \u0027fdc\u0027, \u0027sata\u0027], \u0027xen\u0027: [\u0027xen\u0027, \u0027ide\u0027], \u0027uml\u0027: [\u0027uml\u0027], \u0027lxc\u0027: [\u0027lxc\u0027], \u0027parallels\u0027: [\u0027ide\u0027, \u0027scsi\u0027]}.values(), [])}\", number\u003d1000000)\n2.4459500312805176\n\u003e\u003e\u003e \n\nits true that the comprehension is slow then importing the modules but that woudl normally only happen once when the agent starts.\n\nbut you were compareing allways importing the moduels in iconcat case to not importing then in the comprehension case.\n\nstarting the interpreter and importing the modules add enough overhead to mask the delta in this case\n\n\u003e\u003e\u003e timeit.timeit(\"import functools; import operator;\", number\u003d1000000)\n0.6234610080718994\n\nanyway ill start refactoring this and i might make it a list comprehention but what im really leaning towards is pulling this out in to a flatten_iterable function and calling that instead.","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c71d71204541833fc8c41c2b333fd5a219741d3e","unresolved":false,"context_lines":[{"line_number":9642,"context_line":"        valid_buses \u003d blockinfo.VALID_STORAGE_BUS.get("},{"line_number":9643,"context_line":"            CONF.libvirt.virt_type, [])"},{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_f5e9edb6","line":9646,"range":{"start_line":9645,"start_character":0,"end_line":9646,"end_character":54},"in_reply_to":"7faddb67_e145b616","updated":"2019-08-09 17:05:44.000000000","message":"i am doing it correctly that is much slower and personally i find it less readable and it does nto do what i want.\ni want to build a  set to remove duplicates and i am using set default later to ignore values that are already set.\n\ni look up the best way of doing it and found reduce with iconcat is the recommend way to do this and performace result that show it outperforms it so i dont think that is a better way to do it.\n\nalso ist missusing sum and relay on the fact that ere is an overload for appending list but it will not work with other data types wehere as functools.reduce(operator.iconcat...) will work for all iterables","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"4d04bfd8eaa91b609fe972a37e8f84ac75360dce","unresolved":false,"context_lines":[{"line_number":9642,"context_line":"        valid_buses \u003d blockinfo.VALID_STORAGE_BUS.get("},{"line_number":9643,"context_line":"            CONF.libvirt.virt_type, [])"},{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_5fcc3e34","line":9646,"range":{"start_line":9645,"start_character":0,"end_line":9646,"end_character":54},"in_reply_to":"7faddb67_f5e9edb6","updated":"2019-08-15 23:05:29.000000000","message":"Not to harp on about this, but...\n\n \u003e i am doing it correctly that is much slower and personally i find\n \u003e it less readable and it does nto do what i want.\n \u003e i want to build a  set to remove duplicates and i am using set\n \u003e default later to ignore values that are already set.\n\nAh, yeah, you should probably rename this to \"all_buses\" or something since the name threw me. Alternatively, do this list comprehension and avoid the need to use setdefault (I missed that, personally)\n\n \u003e i look up the best way of doing it and found reduce with iconcat is\n \u003e the recommend way to do this and performace result that show it\n \u003e outperforms it so i dont think that is a better way to do it.\n\nFunnily enough, it\u0027s actually not.\n\nhttp://paste.openstack.org/show/757500/\n\nI\u0027m sure it outperforms list comprehension and sets if you\u0027re talking about a much larger set of data, but not here. From my quick experiments, the list comprehension seems to be about 20% faster and it\u0027s more readable to boot.\n\n \u003e also ist missusing sum and relay on the fact that ere is an\n \u003e overload for appending list but it will not work with other data\n \u003e types wehere as functools.reduce(operator.iconcat...) will work for\n \u003e all iterables\n\nThat\u0027s not relevant, given that we only care about VALID_STORAGE_BUS here and that\u0027s a dict of lists.","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"fdfe07f2378b596d0124d1ad29f47c183fd1222e","unresolved":false,"context_lines":[{"line_number":9642,"context_line":"        valid_buses \u003d blockinfo.VALID_STORAGE_BUS.get("},{"line_number":9643,"context_line":"            CONF.libvirt.virt_type, [])"},{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_9895508b","line":9646,"range":{"start_line":9645,"start_character":0,"end_line":9646,"end_character":54},"in_reply_to":"7faddb67_f5e9edb6","updated":"2019-08-09 17:29:59.000000000","message":"by the way this is why you should not use sum like that\nhttps://stackoverflow.com/a/45323085","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"11e597c8fa108875bbaef95f168d2829d911198a","unresolved":false,"context_lines":[{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"},{"line_number":9650,"context_line":"        }"},{"line_number":9651,"context_line":"        for bus in unsupported_buses:"},{"line_number":9652,"context_line":"            traits.setdefault(\"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(),"},{"line_number":9653,"context_line":"                              False)"},{"line_number":9654,"context_line":""},{"line_number":9655,"context_line":"        return traits"},{"line_number":9656,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_a1681e87","line":9653,"range":{"start_line":9647,"start_character":0,"end_line":9653,"end_character":36},"updated":"2019-08-09 11:25:39.000000000","message":"Shouldn\u0027t we check to make sure these are valid traits (reported by os_traits) before reporting them? Heck, even a unit test to do this would be fine","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"4d04bfd8eaa91b609fe972a37e8f84ac75360dce","unresolved":false,"context_lines":[{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"},{"line_number":9650,"context_line":"        }"},{"line_number":9651,"context_line":"        for bus in unsupported_buses:"},{"line_number":9652,"context_line":"            traits.setdefault(\"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(),"},{"line_number":9653,"context_line":"                              False)"},{"line_number":9654,"context_line":""},{"line_number":9655,"context_line":"        return traits"},{"line_number":9656,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_9fddd6de","line":9653,"range":{"start_line":9647,"start_character":0,"end_line":9653,"end_character":36},"in_reply_to":"7faddb67_55f1e194","updated":"2019-08-15 23:05:29.000000000","message":"Expensive is a good reason not to do this. I think we should test it though. Could you add a simple UT to make sure someone doesn\u0027t modify VALID_STORAGE_BUS in the future such that we introduce a trait that doesn\u0027t exist in os-traits?","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"0d6fa86d010a9a4892d22010b4545e3675330960","unresolved":false,"context_lines":[{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"},{"line_number":9650,"context_line":"        }"},{"line_number":9651,"context_line":"        for bus in unsupported_buses:"},{"line_number":9652,"context_line":"            traits.setdefault(\"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(),"},{"line_number":9653,"context_line":"                              False)"},{"line_number":9654,"context_line":""},{"line_number":9655,"context_line":"        return traits"},{"line_number":9656,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_ed951933","line":9653,"range":{"start_line":9647,"start_character":0,"end_line":9653,"end_character":36},"in_reply_to":"7faddb67_9fddd6de","updated":"2019-08-19 19:29:33.000000000","message":"what im going to do is bring my validate function form the last patch to the first one and add simple dict caching. then i am happy to validate teh traits as i construct them.\n\nas for the unit test ya i can proably call this and iterate over the results and ensure they are valid.","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c71d71204541833fc8c41c2b333fd5a219741d3e","unresolved":false,"context_lines":[{"line_number":9644,"context_line":""},{"line_number":9645,"context_line":"        unsupported_buses \u003d set(functools.reduce(operator.iconcat,"},{"line_number":9646,"context_line":"            blockinfo.VALID_STORAGE_BUS.values(), []))"},{"line_number":9647,"context_line":"        traits \u003d {"},{"line_number":9648,"context_line":"            \"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(): True for bus"},{"line_number":9649,"context_line":"            in valid_buses"},{"line_number":9650,"context_line":"        }"},{"line_number":9651,"context_line":"        for bus in unsupported_buses:"},{"line_number":9652,"context_line":"            traits.setdefault(\"COMPUTE_STORAGE_BUS_{}\".format(bus).upper(),"},{"line_number":9653,"context_line":"                              False)"},{"line_number":9654,"context_line":""},{"line_number":9655,"context_line":"        return traits"},{"line_number":9656,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7faddb67_55f1e194","line":9653,"range":{"start_line":9647,"start_character":0,"end_line":9653,"end_character":36},"in_reply_to":"7faddb67_a1681e87","updated":"2019-08-09 17:05:44.000000000","message":"they are i added traits for all storage bus types we support.\n\ni could validate them but its rather expensive","commit_id":"f646bff679c8cb8961f1219ba6558b466e7f5f7f"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9ed6e9260c4d67e0846740c430acc7df6f68bcea","unresolved":false,"context_lines":[{"line_number":9664,"context_line":"    # NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":9665,"context_line":"    # in the future as such we may want to extract it in the future"},{"line_number":9666,"context_line":"    # to the base driver class or to a util module."},{"line_number":9667,"context_line":"    @staticmethod"},{"line_number":9668,"context_line":"    def _project_traits(model, key, prefix):"},{"line_number":9669,"context_line":"        \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":9670,"context_line":"        supported traits mapping each trait to a bool."}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_dfb2d206","line":9667,"updated":"2019-08-26 14:09:53.000000000","message":"it\u0027s cool to make it a static method, but then why are you putting it into libvirt code directly? either make it called externally or leave it to be instanciated directly as a private method","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"694cc336c867ef33889b2066b5dd285b78dcf226","unresolved":false,"context_lines":[{"line_number":9664,"context_line":"    # NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":9665,"context_line":"    # in the future as such we may want to extract it in the future"},{"line_number":9666,"context_line":"    # to the base driver class or to a util module."},{"line_number":9667,"context_line":"    @staticmethod"},{"line_number":9668,"context_line":"    def _project_traits(model, key, prefix):"},{"line_number":9669,"context_line":"        \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":9670,"context_line":"        supported traits mapping each trait to a bool."}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_f3b90579","line":9667,"in_reply_to":"7faddb67_dfb2d206","updated":"2019-08-26 17:24:41.000000000","message":"i put it in the libvirt code to be able to call it via self. no other reason and as noted above i think this would be useful for other driver too so i was debateing if it should be in the base dirver or a utility module.\n\ni just made it a static method to call out it does not depend on the driver instance or class but for now it logically makes sense to have this here. since this is where its used.\n\nif i had not used static method it would not have imendtaly been obviors this could be moved elsewhere.\n\ndo you have a preference of what path i take?","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"70b056ffcf8e6a9b4668752844328c0b67c59c3e","unresolved":false,"context_lines":[{"line_number":9664,"context_line":"    # NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":9665,"context_line":"    # in the future as such we may want to extract it in the future"},{"line_number":9666,"context_line":"    # to the base driver class or to a util module."},{"line_number":9667,"context_line":"    @staticmethod"},{"line_number":9668,"context_line":"    def _project_traits(model, key, prefix):"},{"line_number":9669,"context_line":"        \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":9670,"context_line":"        supported traits mapping each trait to a bool."}],"source_content_type":"text/x-python","patch_set":10,"id":"7faddb67_b50287b9","line":9667,"in_reply_to":"7faddb67_f3b90579","updated":"2019-08-27 10:08:00.000000000","message":"Not sure you saw my top comment, so putting again https://www.webucator.com/blog/2016/05/when-to-use-static-methods-in-python-never/\n\nBasically, if you really want to make clear that this method is absolutely untangled to the class, put it outside the class as a private module function and leave a TODO like \"move this out of this module when other drivers use it\".","commit_id":"4d6fa028f32d2c4aac126b715f1df9ca90418377"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"0e0b462e3ae54d89dd3c7ebfbaeda28068ae174f","unresolved":false,"context_lines":[{"line_number":422,"context_line":"        # intended to be updatable directly"},{"line_number":423,"context_line":"        self.provider_tree \u003d None"},{"line_number":424,"context_line":"        # driver traits will not change during the runtime of the agent"},{"line_number":425,"context_line":"        # so caluate them once and save them."},{"line_number":426,"context_line":"        self.storage_bus_traits \u003d self._get_storage_bus_traits()"},{"line_number":427,"context_line":""},{"line_number":428,"context_line":"    def _get_volume_drivers(self):"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_2e5de447","line":425,"range":{"start_line":425,"start_character":13,"end_line":425,"end_character":20},"updated":"2019-08-27 12:58:41.000000000","message":"calculate","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"4312275880f2cd578372f8792664873d31bbe37e","unresolved":false,"context_lines":[{"line_number":9662,"context_line":"    # NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":9663,"context_line":"    # in the future as such we may want to extract it in the future"},{"line_number":9664,"context_line":"    # to the base driver class or to a util module."},{"line_number":9665,"context_line":"    @staticmethod"},{"line_number":9666,"context_line":"    def _project_traits(model, key, prefix):"},{"line_number":9667,"context_line":"        \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":9668,"context_line":"        supported traits mapping each trait to a bool."}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_d58aa318","line":9665,"updated":"2019-08-27 10:16:14.000000000","message":"see my last comment on PS10","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"62155dfa8c6b3b7bd9db95b970d8b28fb1ed170b","unresolved":false,"context_lines":[{"line_number":9673,"context_line":"        :return: dict of string \u003d\u003e bool mapping trait \u003d\u003e supported."},{"line_number":9674,"context_line":"        \"\"\""},{"line_number":9675,"context_line":"        supported_values \u003d model.get(key, [])"},{"line_number":9676,"context_line":"        all_values \u003d set(utils.flatten_iterable(model.values()))"},{"line_number":9677,"context_line":"        traits \u003d {}"},{"line_number":9678,"context_line":"        for val in supported_values:"},{"line_number":9679,"context_line":"            trait \u003d \"{}_{}\".format(prefix, val).upper()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7faddb67_5aa7ba0a","line":9676,"range":{"start_line":9676,"start_character":25,"end_line":9676,"end_character":63},"updated":"2019-08-27 14:51:02.000000000","message":"I feel like I\u0027m going way overboard on this, so sorry for being annoying. It\u0027s just stuck with me. With that said:\n\n  itertools.chain(*model.values())\n\nwould achieve the same thing too. It\u0027s stdlib and is a well-known idiom, unlike the set thing.","commit_id":"82b5b87c71151b46e923f89aaef8f05f336c6be1"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ab36060b6b9f3b316f2cc3c5aaa3b365985c6287","unresolved":false,"context_lines":[{"line_number":9659,"context_line":"                           nova.privsep.fs.FS_FORMAT_EXT4,"},{"line_number":9660,"context_line":"                           nova.privsep.fs.FS_FORMAT_XFS]"},{"line_number":9661,"context_line":""},{"line_number":9662,"context_line":"    @staticmethod"},{"line_number":9663,"context_line":"    def _get_storage_bus_traits():"},{"line_number":9664,"context_line":"        \"\"\"Get Storage bus traits  based in the currently enabled"},{"line_number":9665,"context_line":"        virt_type."},{"line_number":9666,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_685f3e75","line":9663,"range":{"start_line":9662,"start_character":0,"end_line":9663,"end_character":34},"updated":"2019-08-28 09:10:53.000000000","message":"nit: Would this have made sense as a property?","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"50507259e13ee58dedf5635a5b91d1981e478afc","unresolved":false,"context_lines":[{"line_number":9659,"context_line":"                           nova.privsep.fs.FS_FORMAT_EXT4,"},{"line_number":9660,"context_line":"                           nova.privsep.fs.FS_FORMAT_XFS]"},{"line_number":9661,"context_line":""},{"line_number":9662,"context_line":"    @staticmethod"},{"line_number":9663,"context_line":"    def _get_storage_bus_traits():"},{"line_number":9664,"context_line":"        \"\"\"Get Storage bus traits  based in the currently enabled"},{"line_number":9665,"context_line":"        virt_type."},{"line_number":9666,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_d2f140e0","line":9663,"range":{"start_line":9662,"start_character":0,"end_line":9663,"end_character":34},"in_reply_to":"7faddb67_685f3e75","updated":"2019-08-28 09:51:21.000000000","message":"i played with that idea\ni made all the static traits a property in the next patch in the series instead. but it could be.\n\nand before sylvain point it out it could also be a free function at the end of the module.","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ab36060b6b9f3b316f2cc3c5aaa3b365985c6287","unresolved":false,"context_lines":[{"line_number":9752,"context_line":"# NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":9753,"context_line":"# as such we may want to extract it in the future"},{"line_number":9754,"context_line":"# to the base driver class or to a util module."},{"line_number":9755,"context_line":"def _project_traits(model, key, prefix):"},{"line_number":9756,"context_line":"    \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":9757,"context_line":"    supported traits mapping each trait to a bool."},{"line_number":9758,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_c86e722b","line":9755,"range":{"start_line":9755,"start_character":4,"end_line":9755,"end_character":19},"updated":"2019-08-28 09:10:53.000000000","message":"nit: I\u0027m still not grasping what the \u0027_project\u0027 prefix is based on. There\u0027s nothing project specific about this, is there?","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c3b12c11ee1f61661b990cbf7674859c891da1a2","unresolved":false,"context_lines":[{"line_number":9752,"context_line":"# NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":9753,"context_line":"# as such we may want to extract it in the future"},{"line_number":9754,"context_line":"# to the base driver class or to a util module."},{"line_number":9755,"context_line":"def _project_traits(model, key, prefix):"},{"line_number":9756,"context_line":"    \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":9757,"context_line":"    supported traits mapping each trait to a bool."},{"line_number":9758,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"7faddb67_4c992fce","line":9755,"range":{"start_line":9755,"start_character":4,"end_line":9755,"end_character":19},"in_reply_to":"7faddb67_c86e722b","updated":"2019-08-28 15:05:43.000000000","message":"project verb meaning to make a projection\ne.g. the compute science/set theroy meaning\nhttps://en.wikipedia.org/wiki/Projection_(set_theory)\n\nthis is a mapping function that projects the input set of model key and prefix on set of valid traits.\n\nso not related to tenants in any way.","commit_id":"febe3ffd17a49adb3e78306e3569c4376950f009"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":7279,"context_line":"        provider_tree.update_resources(nodename, resources)"},{"line_number":7280,"context_line":""},{"line_number":7281,"context_line":"        # _get_cpu_traits returns a dict of trait names mapped to boolean"},{"line_number":7282,"context_line":"        # values. Add traits equal to True to provider tree, remove"},{"line_number":7283,"context_line":"        traits \u003d self._get_cpu_traits() or {}"},{"line_number":7284,"context_line":"        traits.update(self.storage_bus_traits)"},{"line_number":7285,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_259ce1bd","line":7282,"range":{"start_line":7282,"start_character":18,"end_line":7282,"end_character":67},"updated":"2020-01-21 19:35:42.000000000","message":"x","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9a574961a591dc984ac5ae603a55d72ca095c7e5","unresolved":false,"context_lines":[{"line_number":7279,"context_line":"        provider_tree.update_resources(nodename, resources)"},{"line_number":7280,"context_line":""},{"line_number":7281,"context_line":"        # _get_cpu_traits returns a dict of trait names mapped to boolean"},{"line_number":7282,"context_line":"        # values. Add traits equal to True to provider tree, remove"},{"line_number":7283,"context_line":"        traits \u003d self._get_cpu_traits() or {}"},{"line_number":7284,"context_line":"        traits.update(self.storage_bus_traits)"},{"line_number":7285,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_29b83be6","line":7282,"range":{"start_line":7282,"start_character":18,"end_line":7282,"end_character":67},"in_reply_to":"3fa7e38b_259ce1bd","updated":"2020-01-21 22:09:26.000000000","message":"oh ya i duplicated that, will fix.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":10399,"context_line":""},{"line_number":10400,"context_line":"    @staticmethod"},{"line_number":10401,"context_line":"    def _get_storage_bus_traits():"},{"line_number":10402,"context_line":"        \"\"\"Get Storage bus traits  based in the currently enabled"},{"line_number":10403,"context_line":"        virt_type."},{"line_number":10404,"context_line":""},{"line_number":10405,"context_line":"        :return: A dict of trait names mapped to boolean values or None."}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_a59bf161","line":10402,"range":{"start_line":10402,"start_character":41,"end_line":10402,"end_character":43},"updated":"2020-01-21 19:35:42.000000000","message":"on","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":10399,"context_line":""},{"line_number":10400,"context_line":"    @staticmethod"},{"line_number":10401,"context_line":"    def _get_storage_bus_traits():"},{"line_number":10402,"context_line":"        \"\"\"Get Storage bus traits  based in the currently enabled"},{"line_number":10403,"context_line":"        virt_type."},{"line_number":10404,"context_line":""},{"line_number":10405,"context_line":"        :return: A dict of trait names mapped to boolean values or None."}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_85aa75d0","line":10402,"range":{"start_line":10402,"start_character":33,"end_line":10402,"end_character":34},"updated":"2020-01-21 19:35:42.000000000","message":"x","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9c613d0f858d8f45ac8747df268e29fc561d3f0b","unresolved":false,"context_lines":[{"line_number":10399,"context_line":""},{"line_number":10400,"context_line":"    @staticmethod"},{"line_number":10401,"context_line":"    def _get_storage_bus_traits():"},{"line_number":10402,"context_line":"        \"\"\"Get Storage bus traits  based in the currently enabled"},{"line_number":10403,"context_line":"        virt_type."},{"line_number":10404,"context_line":""},{"line_number":10405,"context_line":"        :return: A dict of trait names mapped to boolean values or None."}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_5bf8277d","line":10402,"range":{"start_line":10402,"start_character":33,"end_line":10402,"end_character":34},"in_reply_to":"3fa7e38b_85aa75d0","updated":"2020-02-20 14:43:09.000000000","message":"Done","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9c613d0f858d8f45ac8747df268e29fc561d3f0b","unresolved":false,"context_lines":[{"line_number":10399,"context_line":""},{"line_number":10400,"context_line":"    @staticmethod"},{"line_number":10401,"context_line":"    def _get_storage_bus_traits():"},{"line_number":10402,"context_line":"        \"\"\"Get Storage bus traits  based in the currently enabled"},{"line_number":10403,"context_line":"        virt_type."},{"line_number":10404,"context_line":""},{"line_number":10405,"context_line":"        :return: A dict of trait names mapped to boolean values or None."}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_bb011b6f","line":10402,"range":{"start_line":10402,"start_character":41,"end_line":10402,"end_character":43},"in_reply_to":"3fa7e38b_a59bf161","updated":"2020-02-20 14:43:09.000000000","message":"Done","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":10510,"context_line":"# NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":10511,"context_line":"# as such we may want to extract it in the future"},{"line_number":10512,"context_line":"# to the base driver class or to a util module."},{"line_number":10513,"context_line":"def _project_traits(model, key, prefix):"},{"line_number":10514,"context_line":"    \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":10515,"context_line":"    supported traits mapping each trait to a bool."},{"line_number":10516,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_25eaa10d","line":10513,"range":{"start_line":10513,"start_character":4,"end_line":10513,"end_character":19},"updated":"2020-01-21 19:35:42.000000000","message":"IMO this level of indirection is unnecessary, and confusing to look at. YAGNI. Split it later if it\u0027s needed later.\n\n[Later] Okay, I see you reused it in the next patch.\n\nCan we find better naming than \"project\"? On first look I (and I think most people) read it as the noun (as in project/tenant) rather than the verb (as in projecting) which is what I assume you meant.\n\n_bool_map_model_traits?","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9a574961a591dc984ac5ae603a55d72ca095c7e5","unresolved":false,"context_lines":[{"line_number":10510,"context_line":"# NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":10511,"context_line":"# as such we may want to extract it in the future"},{"line_number":10512,"context_line":"# to the base driver class or to a util module."},{"line_number":10513,"context_line":"def _project_traits(model, key, prefix):"},{"line_number":10514,"context_line":"    \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":10515,"context_line":"    supported traits mapping each trait to a bool."},{"line_number":10516,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_a9466b21","line":10513,"range":{"start_line":10513,"start_character":4,"end_line":10513,"end_character":19},"in_reply_to":"3fa7e38b_25eaa10d","updated":"2020-01-21 22:09:26.000000000","message":"maybe not _bool_map_model_traits but yes we can have a different name.\nthis is a projection function in the mathematical sense.\nthere is a less confusing name for this but ill need to think about it.  ill take a look at it again in the morning.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9c613d0f858d8f45ac8747df268e29fc561d3f0b","unresolved":false,"context_lines":[{"line_number":10510,"context_line":"# NOTE(sean-k-mooney): this may be useful to other drivers"},{"line_number":10511,"context_line":"# as such we may want to extract it in the future"},{"line_number":10512,"context_line":"# to the base driver class or to a util module."},{"line_number":10513,"context_line":"def _project_traits(model, key, prefix):"},{"line_number":10514,"context_line":"    \"\"\"Given a model, key and prefix returns a dict of"},{"line_number":10515,"context_line":"    supported traits mapping each trait to a bool."},{"line_number":10516,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_7bfba379","line":10513,"range":{"start_line":10513,"start_character":4,"end_line":10513,"end_character":19},"in_reply_to":"3fa7e38b_a9466b21","updated":"2020-02-20 14:43:09.000000000","message":"I got rid of this. The bit of duplication we end up with is worth it, IMO.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c05318ea3c790c2f979651014216f2f7567211ea","unresolved":false,"context_lines":[{"line_number":10534,"context_line":"        if utils.valid_trait(trait):"},{"line_number":10535,"context_line":"            traits.setdefault(trait, False)"},{"line_number":10536,"context_line":"        else:"},{"line_number":10537,"context_line":"            LOG.debug(\"Trait: %s is not valid. Skipping trait.\", trait)"},{"line_number":10538,"context_line":"    return traits"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_e57fa9db","line":10537,"updated":"2020-01-21 19:35:42.000000000","message":"This seems like it would be more concise and readable if done in a single loop.\n\n for val in all_values:\n     trait \u003d normalize...\n     if not is_trait_valid(trait):\n         LOG...\n         continue\n     traits[trait] \u003d val in supported_values","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9a574961a591dc984ac5ae603a55d72ca095c7e5","unresolved":false,"context_lines":[{"line_number":10534,"context_line":"        if utils.valid_trait(trait):"},{"line_number":10535,"context_line":"            traits.setdefault(trait, False)"},{"line_number":10536,"context_line":"        else:"},{"line_number":10537,"context_line":"            LOG.debug(\"Trait: %s is not valid. Skipping trait.\", trait)"},{"line_number":10538,"context_line":"    return traits"}],"source_content_type":"text/x-python","patch_set":19,"id":"3fa7e38b_89f7efd1","line":10537,"in_reply_to":"3fa7e38b_e57fa9db","updated":"2020-01-21 22:09:26.000000000","message":"yes i can do that.","commit_id":"4ddf45fdc0459536cffe2c2b2f0ff8870295f8e6"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fc13af0fba444bded1a6b3e53186b1b5f2727be9","unresolved":false,"context_lines":[{"line_number":7243,"context_line":"        provider_tree.update_inventory(nodename, result)"},{"line_number":7244,"context_line":"        provider_tree.update_resources(nodename, resources)"},{"line_number":7245,"context_line":""},{"line_number":7246,"context_line":"        # _get_cpu_traits and _get_storage_bus_traits returns a dict of trait"},{"line_number":7247,"context_line":"        # names mapped to boolean values..."},{"line_number":7248,"context_line":"        traits \u003d self._get_cpu_traits()"},{"line_number":7249,"context_line":"        traits.update(self._get_storage_bus_traits())"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_b3e85f7e","line":7246,"range":{"start_line":7246,"start_character":54,"end_line":7246,"end_character":61},"updated":"2020-02-20 17:30:56.000000000","message":"return","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"6c70e23877dd294e430297b072d5eeced2ee848c","unresolved":false,"context_lines":[{"line_number":7243,"context_line":"        provider_tree.update_inventory(nodename, result)"},{"line_number":7244,"context_line":"        provider_tree.update_resources(nodename, resources)"},{"line_number":7245,"context_line":""},{"line_number":7246,"context_line":"        # _get_cpu_traits and _get_storage_bus_traits returns a dict of trait"},{"line_number":7247,"context_line":"        # names mapped to boolean values..."},{"line_number":7248,"context_line":"        traits \u003d self._get_cpu_traits()"},{"line_number":7249,"context_line":"        traits.update(self._get_storage_bus_traits())"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_b9d26efd","line":7246,"range":{"start_line":7246,"start_character":54,"end_line":7246,"end_character":61},"in_reply_to":"3fa7e38b_b3e85f7e","updated":"2020-02-21 17:49:27.000000000","message":"Done","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fc13af0fba444bded1a6b3e53186b1b5f2727be9","unresolved":false,"context_lines":[{"line_number":10363,"context_line":""},{"line_number":10364,"context_line":"        :return: A dict of trait names mapped to boolean values."},{"line_number":10365,"context_line":"        \"\"\""},{"line_number":10366,"context_line":"        all_buses \u003d set(itertools.chain("},{"line_number":10367,"context_line":"            *blockinfo.SUPPORTED_STORAGE_BUSES.values()"},{"line_number":10368,"context_line":"        ))"},{"line_number":10369,"context_line":"        supported_buses \u003d blockinfo.SUPPORTED_STORAGE_BUSES.get("}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_56d0f956","line":10366,"range":{"start_line":10366,"start_character":20,"end_line":10366,"end_character":23},"updated":"2020-02-20 17:30:56.000000000","message":"nit: it\u0027s a teeny bit more efficient if you don\u0027t convert to a set() here...","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fc13af0fba444bded1a6b3e53186b1b5f2727be9","unresolved":false,"context_lines":[{"line_number":10366,"context_line":"        all_buses \u003d set(itertools.chain("},{"line_number":10367,"context_line":"            *blockinfo.SUPPORTED_STORAGE_BUSES.values()"},{"line_number":10368,"context_line":"        ))"},{"line_number":10369,"context_line":"        supported_buses \u003d blockinfo.SUPPORTED_STORAGE_BUSES.get("},{"line_number":10370,"context_line":"            CONF.libvirt.virt_type, []"},{"line_number":10371,"context_line":"        )"},{"line_number":10372,"context_line":"        return {"},{"line_number":10373,"context_line":"            f\u0027COMPUTE_STORAGE_BUS_{bus.upper()}\u0027: bus in supported_buses"}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_d6cdc9b9","line":10370,"range":{"start_line":10369,"start_character":26,"end_line":10370,"end_character":38},"updated":"2020-02-20 17:30:56.000000000","message":"...but do here","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fc13af0fba444bded1a6b3e53186b1b5f2727be9","unresolved":false,"context_lines":[{"line_number":10370,"context_line":"            CONF.libvirt.virt_type, []"},{"line_number":10371,"context_line":"        )"},{"line_number":10372,"context_line":"        return {"},{"line_number":10373,"context_line":"            f\u0027COMPUTE_STORAGE_BUS_{bus.upper()}\u0027: bus in supported_buses"},{"line_number":10374,"context_line":"            for bus in all_buses"},{"line_number":10375,"context_line":"        }"},{"line_number":10376,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_3306af24","line":10373,"range":{"start_line":10373,"start_character":12,"end_line":10373,"end_character":48},"updated":"2020-02-20 17:30:56.000000000","message":"I thought the normalize method was overkill, but this possibly goes too far the other way. Can we get a comment, e.g. \"Construct the corresponding standard trait from the storage bus name.\"?","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"6c70e23877dd294e430297b072d5eeced2ee848c","unresolved":false,"context_lines":[{"line_number":10370,"context_line":"            CONF.libvirt.virt_type, []"},{"line_number":10371,"context_line":"        )"},{"line_number":10372,"context_line":"        return {"},{"line_number":10373,"context_line":"            f\u0027COMPUTE_STORAGE_BUS_{bus.upper()}\u0027: bus in supported_buses"},{"line_number":10374,"context_line":"            for bus in all_buses"},{"line_number":10375,"context_line":"        }"},{"line_number":10376,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"3fa7e38b_39f8be7c","line":10373,"range":{"start_line":10373,"start_character":12,"end_line":10373,"end_character":48},"in_reply_to":"3fa7e38b_3306af24","updated":"2020-02-21 17:49:27.000000000","message":"Done","commit_id":"425b6d0bf0ffb0d5af1f3faa2065b08c51667c6d"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"29b69caef211191725c423e504d650dba0b418ea","unresolved":false,"context_lines":[{"line_number":10371,"context_line":"        )"},{"line_number":10372,"context_line":"        # construct the corresponding standard trait from the storage bus name"},{"line_number":10373,"context_line":"        return {"},{"line_number":10374,"context_line":"            f\u0027COMPUTE_STORAGE_BUS_{bus.upper()}\u0027: bus in supported_buses"},{"line_number":10375,"context_line":"            for bus in all_buses"},{"line_number":10376,"context_line":"        }"},{"line_number":10377,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"1fa4df85_3fdd7bdf","line":10374,"range":{"start_line":10374,"start_character":12,"end_line":10374,"end_character":72},"updated":"2020-03-09 14:52:17.000000000","message":"thats one way to force python 3.6+ :)","commit_id":"633616258523be9acbf445dada245cb1bd0eaa9a"}],"requirements.txt":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9551045ccfe57abc57443876d17b1d632504517e","unresolved":false,"context_lines":[{"line_number":56,"context_line":"oslo.versionedobjects\u003e\u003d1.35.0 # Apache-2.0"},{"line_number":57,"context_line":"os-brick\u003e\u003d2.6.1 # Apache-2.0"},{"line_number":58,"context_line":"os-resource-classes\u003e\u003d0.1.0 # Apache-2.0"},{"line_number":59,"context_line":"os-traits\u003e\u003d0.15.0 # Apache-2.0"},{"line_number":60,"context_line":"os-vif\u003e\u003d1.14.0 # Apache-2.0"},{"line_number":61,"context_line":"os-win\u003e\u003d3.0.0 # Apache-2.0"},{"line_number":62,"context_line":"castellan\u003e\u003d0.16.0 # Apache-2.0"}],"source_content_type":"text/plain","patch_set":2,"id":"9fb8cfa7_7acd5364","line":59,"range":{"start_line":59,"start_character":0,"end_line":59,"end_character":30},"updated":"2019-06-28 13:49:26.000000000","message":"i need to update lower-constartits too.","commit_id":"6779826712fcedd16db0fe3114e6811113cf81f7"}]}
