)]}'
{"nova/scheduler/client/report.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c65768678a9b31aeaacf5853302ee1b9ea95533a","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        if required_traits:"},{"line_number":353,"context_line":"            qs_params[\u0027required\u0027] \u003d \",\".join(required_traits)"},{"line_number":354,"context_line":"        if forbidden_traits:"},{"line_number":355,"context_line":"            # Sorted to make testing easier to manage and for"},{"line_number":356,"context_line":"            # predictability."},{"line_number":357,"context_line":"            forbiddens \u003d \u0027,!\u0027.join(sorted(forbidden_traits))"},{"line_number":358,"context_line":"            if qs_params[\u0027required\u0027]:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_485f1441","line":355,"range":{"start_line":355,"start_character":14,"end_line":355,"end_character":20},"updated":"2018-04-16 18:43:04.000000000","message":"Not sure how much good it does to sort these but not the ones above.","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"366e335d5cf1aea60bbf391f88ec3af4b8932c23","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        if required_traits:"},{"line_number":353,"context_line":"            qs_params[\u0027required\u0027] \u003d \",\".join(required_traits)"},{"line_number":354,"context_line":"        if forbidden_traits:"},{"line_number":355,"context_line":"            # Sorted to make testing easier to manage and for"},{"line_number":356,"context_line":"            # predictability."},{"line_number":357,"context_line":"            forbiddens \u003d \u0027,!\u0027.join(sorted(forbidden_traits))"},{"line_number":358,"context_line":"            if qs_params[\u0027required\u0027]:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_a68701d8","line":355,"range":{"start_line":355,"start_character":14,"end_line":355,"end_character":20},"in_reply_to":"9f6a8fd7_485f1441","updated":"2018-04-16 18:50:41.000000000","message":"The existing test didn\u0027t need it. The test change I made did. Is that enough reason? I\u0027m happy to do something else (either sort both or sort neither and change the test to granularize the expected results) but in this case was just making the shortest hop.","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"cc9911b4874651f8572faf000d2ca7e627f5e0ec","unresolved":false,"context_lines":[{"line_number":324,"context_line":"            A ResourceRequest object representing the requested resources,"},{"line_number":325,"context_line":"            traits, and aggregates from the request spec."},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"        Example member_of (aggregates) value in resources:"},{"line_number":328,"context_line":""},{"line_number":329,"context_line":"            [(\u0027foo\u0027, \u0027bar\u0027), (\u0027baz\u0027,)]"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"        translates to:"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"            \"Candidates are in either \u0027foo\u0027 or \u0027bar\u0027, but definitely in \u0027baz\u0027\""},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"        \"\"\""},{"line_number":336,"context_line":"        # TODO(efried): For now, just use the unnumbered group to retain"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f6a8fd7_64ac658c","line":333,"range":{"start_line":327,"start_character":8,"end_line":333,"end_character":78},"updated":"2018-04-17 17:34:27.000000000","message":"note to self... the above is (currently) incorrect. We don\u0027t currently support AND\u0027d member_of. It\u0027s a work in progress...","commit_id":"2c51688558504f2e8ce80bac06642772be67b2a9"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5b007363db765da1a6da93f4f52b318a1ee59b1c","unresolved":false,"context_lines":[{"line_number":324,"context_line":"            A ResourceRequest object representing the requested resources,"},{"line_number":325,"context_line":"            traits, and aggregates from the request spec."},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"        Example member_of (aggregates) value in resources:"},{"line_number":328,"context_line":""},{"line_number":329,"context_line":"            [(\u0027foo\u0027, \u0027bar\u0027), (\u0027baz\u0027,)]"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"        translates to:"},{"line_number":332,"context_line":""},{"line_number":333,"context_line":"            \"Candidates are in either \u0027foo\u0027 or \u0027bar\u0027, but definitely in \u0027baz\u0027\""},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"        \"\"\""},{"line_number":336,"context_line":"        # TODO(efried): For now, just use the unnumbered group to retain"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f6a8fd7_a4b11d92","line":333,"range":{"start_line":327,"start_character":8,"end_line":333,"end_character":78},"in_reply_to":"9f6a8fd7_64ac658c","updated":"2018-04-17 17:51:38.000000000","message":"Yuh, see also comment on L363","commit_id":"2c51688558504f2e8ce80bac06642772be67b2a9"}],"nova/scheduler/utils.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"da56ccab45d032965726f5b8947fc1420603b7a4","unresolved":false,"context_lines":[{"line_number":87,"context_line":"    def _add_trait(self, groupid, trait_name, trait_type):"},{"line_number":88,"context_line":"        # Currently the only valid values for a trait entry are \u0027required\u0027"},{"line_number":89,"context_line":"        # and \u0027forbidden\u0027"},{"line_number":90,"context_line":"        trait_vals \u003d (\u0027required\u0027, \u0027forbidden\u0027)"},{"line_number":91,"context_line":"        if trait_type \u003d\u003d \u0027required\u0027:"},{"line_number":92,"context_line":"            self.get_request_group(groupid).required_traits.add(trait_name)"},{"line_number":93,"context_line":"        elif trait_type \u003d\u003d \u0027forbidden\u0027:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_cbc6be17","line":90,"range":{"start_line":90,"start_character":8,"end_line":90,"end_character":46},"updated":"2018-04-16 18:14:28.000000000","message":"unused.","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"ed14ef7e996a30bb461bb671c5bb9d09bd6d58a7","unresolved":false,"context_lines":[{"line_number":87,"context_line":"    def _add_trait(self, groupid, trait_name, trait_type):"},{"line_number":88,"context_line":"        # Currently the only valid values for a trait entry are \u0027required\u0027"},{"line_number":89,"context_line":"        # and \u0027forbidden\u0027"},{"line_number":90,"context_line":"        trait_vals \u003d (\u0027required\u0027, \u0027forbidden\u0027)"},{"line_number":91,"context_line":"        if trait_type \u003d\u003d \u0027required\u0027:"},{"line_number":92,"context_line":"            self.get_request_group(groupid).required_traits.add(trait_name)"},{"line_number":93,"context_line":"        elif trait_type \u003d\u003d \u0027forbidden\u0027:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_46c5c58d","line":90,"range":{"start_line":90,"start_character":8,"end_line":90,"end_character":46},"in_reply_to":"9f6a8fd7_6694898c","updated":"2018-04-16 18:31:04.000000000","message":"ah, doh, yeah. sorry bout that...","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"44994a6ba502e1f894823bd5cce91b187aa07413","unresolved":false,"context_lines":[{"line_number":87,"context_line":"    def _add_trait(self, groupid, trait_name, trait_type):"},{"line_number":88,"context_line":"        # Currently the only valid values for a trait entry are \u0027required\u0027"},{"line_number":89,"context_line":"        # and \u0027forbidden\u0027"},{"line_number":90,"context_line":"        trait_vals \u003d (\u0027required\u0027, \u0027forbidden\u0027)"},{"line_number":91,"context_line":"        if trait_type \u003d\u003d \u0027required\u0027:"},{"line_number":92,"context_line":"            self.get_request_group(groupid).required_traits.add(trait_name)"},{"line_number":93,"context_line":"        elif trait_type \u003d\u003d \u0027forbidden\u0027:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_6694898c","line":90,"range":{"start_line":90,"start_character":8,"end_line":90,"end_character":46},"in_reply_to":"9f6a8fd7_cbc6be17","updated":"2018-04-16 18:29:40.000000000","message":"it\u0027s used in the error message at line 95\n\nI consider not using, it because it feels pretty redundant, but it is used, and I decided it was a useful signal for reading the stack of conditionals. I struggled to find a way that satisfied me here and just decided to let it slide for now.","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c65768678a9b31aeaacf5853302ee1b9ea95533a","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                \"for key trait%(groupid)s.\","},{"line_number":99,"context_line":"                {\"tvals\": \u0027, \u0027.join(trait_vals), \"groupid\": groupid,"},{"line_number":100,"context_line":"                 \"val\": trait_type})"},{"line_number":101,"context_line":"        return"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    @classmethod"},{"line_number":104,"context_line":"    def from_extra_specs(cls, extra_specs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_ebedc225","line":101,"range":{"start_line":101,"start_character":8,"end_line":101,"end_character":14},"updated":"2018-04-16 18:43:04.000000000","message":"no longer needed","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"f1b8ce855699327393fe4b2f289b064d7f263f87","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                \"for key trait%(groupid)s.\","},{"line_number":99,"context_line":"                {\"tvals\": \u0027, \u0027.join(trait_vals), \"groupid\": groupid,"},{"line_number":100,"context_line":"                 \"val\": trait_type})"},{"line_number":101,"context_line":"        return"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    @classmethod"},{"line_number":104,"context_line":"    def from_extra_specs(cls, extra_specs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_9a18f31d","line":101,"range":{"start_line":101,"start_character":8,"end_line":101,"end_character":14},"in_reply_to":"9f6a8fd7_41da8fe9","updated":"2018-04-17 15:43:30.000000000","message":"Even if I got the tail for free, I\u0027d still want to account for it in my larder.","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"e1e3b5937c188278aa5c074c6f85b114d8aa3233","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                \"for key trait%(groupid)s.\","},{"line_number":99,"context_line":"                {\"tvals\": \u0027, \u0027.join(trait_vals), \"groupid\": groupid,"},{"line_number":100,"context_line":"                 \"val\": trait_type})"},{"line_number":101,"context_line":"        return"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    @classmethod"},{"line_number":104,"context_line":"    def from_extra_specs(cls, extra_specs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_41da8fe9","line":101,"range":{"start_line":101,"start_character":8,"end_line":101,"end_character":14},"in_reply_to":"9f6a8fd7_e60ad988","updated":"2018-04-16 20:04:31.000000000","message":"/me mumbles something about python getting tail for free...","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"366e335d5cf1aea60bbf391f88ec3af4b8932c23","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                \"for key trait%(groupid)s.\","},{"line_number":99,"context_line":"                {\"tvals\": \u0027, \u0027.join(trait_vals), \"groupid\": groupid,"},{"line_number":100,"context_line":"                 \"val\": trait_type})"},{"line_number":101,"context_line":"        return"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    @classmethod"},{"line_number":104,"context_line":"    def from_extra_specs(cls, extra_specs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_e60ad988","line":101,"range":{"start_line":101,"start_character":8,"end_line":101,"end_character":14},"in_reply_to":"9f6a8fd7_ebedc225","updated":"2018-04-16 18:50:41.000000000","message":"In python, a method without a return is like a fish without a tail. Here, we make the fact that we are solely side-effecty explicit.","commit_id":"2a5a4f88e5b9669b0cba18ce5bf155db8c99358f"}],"releasenotes/notes/forbidden-traits-in-nova-478f1884a06e50e7.yaml":[{"author":{"_account_id":16929,"name":"Giridhar Jayavelu","email":"gjayavelu@vmware.com","username":"gjayavelu"},"change_message_id":"a5f058301238d23bce0c311ad5596a311d459c14","unresolved":false,"context_lines":[{"line_number":8,"context_line":"    - trait:HW_CPU_X86_AVX2\u003dforbidden"},{"line_number":9,"context_line":"    - trait:STORAGE_DISK_SSD\u003dforbidden"},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"    The scheduler will pass the foribdden traits to the"},{"line_number":12,"context_line":"    ``GET /allocation_candidates`` endpoint in the Placement API to include"},{"line_number":13,"context_line":"    only resource providers that do not include the forbidden traits. Currently"},{"line_number":14,"context_line":"    the only valid values are ``required`` and ``forbidden``. Any other values"}],"source_content_type":"text/x-yaml","patch_set":2,"id":"9f6a8fd7_91ff79a9","line":11,"updated":"2018-04-17 16:54:41.000000000","message":"s/foribdden/forbidden","commit_id":"01f8384d8445b1b6d04f0ed10dc04ec58eae09d6"}]}
