)]}'
{"ironic_lib/tests/test_utils.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        expected[\u0027model\u0027] \u003d \u0027s\u003d\u003dfoo%20model\u0027"},{"line_number":313,"context_line":"        expected[\u0027vendor\u0027] \u003d \u0027s\u003d\u003dfoo%20vendor%20with%20space\u0027"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        result \u003d utils.parse_root_device_hints(root_device)"},{"line_number":316,"context_line":"        # The hints already contain the operators, make sure we keep it"},{"line_number":317,"context_line":"        self.assertEqual(expected, result)"},{"line_number":318,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_7d1fb7b7","line":315,"updated":"2016-08-24 13:41:37.000000000","message":"I was thinking that if someone specified \"foo%20model\" instead of \"foo model\", things would get interesting :)","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        expected[\u0027model\u0027] \u003d \u0027s\u003d\u003dfoo%20model\u0027"},{"line_number":313,"context_line":"        expected[\u0027vendor\u0027] \u003d \u0027s\u003d\u003dfoo%20vendor%20with%20space\u0027"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"        result \u003d utils.parse_root_device_hints(root_device)"},{"line_number":316,"context_line":"        # The hints already contain the operators, make sure we keep it"},{"line_number":317,"context_line":"        self.assertEqual(expected, result)"},{"line_number":318,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_af029407","line":315,"in_reply_to":"1ac06dbe_7d1fb7b7","updated":"2016-08-24 14:03:33.000000000","message":"hah then Ironic will look for a \"foo%20model\" because the \"%20\" will be normalized as well :D","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        self.assertIsNone(result)"},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"    def test_parse_root_device_hints_convert_size(self):"},{"line_number":324,"context_line":"        result \u003d utils.parse_root_device_hints({\u0027size\u0027: 12345})"},{"line_number":325,"context_line":"        self.assertEqual({\u0027size\u0027: \u0027\u003d\u003d12345\u0027}, result)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    def test_parse_root_device_hints_invalid_size(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_9d639341","line":324,"updated":"2016-08-24 13:41:37.000000000","message":"it should also work for \u0027size\u0027: \u002712345\u0027, right?","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        self.assertIsNone(result)"},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"    def test_parse_root_device_hints_convert_size(self):"},{"line_number":324,"context_line":"        result \u003d utils.parse_root_device_hints({\u0027size\u0027: 12345})"},{"line_number":325,"context_line":"        self.assertEqual({\u0027size\u0027: \u0027\u003d\u003d12345\u0027}, result)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    def test_parse_root_device_hints_invalid_size(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_6f19bc79","line":324,"in_reply_to":"1ac06dbe_9d639341","updated":"2016-08-24 14:03:33.000000000","message":"Yes","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":332,"context_line":"    def test_parse_root_device_hints_size_or(self):"},{"line_number":333,"context_line":"        hint \u003d \u0027\u003cor\u003e 123 \u003cor\u003e 456 \u003cor\u003e 789\u0027"},{"line_number":334,"context_line":"        result \u003d utils.parse_root_device_hints({\u0027size\u0027: hint})"},{"line_number":335,"context_line":"        self.assertEqual({\u0027size\u0027: hint}, result)"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"    def test_parse_root_device_hints_size_or_invalid(self):"},{"line_number":338,"context_line":"        hint \u003d \u0027\u003cor\u003e 123 \u003cor\u003e non-int \u003cor\u003e 789\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_9dbf1360","line":335,"updated":"2016-08-24 13:41:37.000000000","message":"what about hint \u003d \u0027\u003cor\u003e foo \u003cor\u003e foo bar \u003cor\u003e bar\u0027? Should that work?","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":332,"context_line":"    def test_parse_root_device_hints_size_or(self):"},{"line_number":333,"context_line":"        hint \u003d \u0027\u003cor\u003e 123 \u003cor\u003e 456 \u003cor\u003e 789\u0027"},{"line_number":334,"context_line":"        result \u003d utils.parse_root_device_hints({\u0027size\u0027: hint})"},{"line_number":335,"context_line":"        self.assertEqual({\u0027size\u0027: hint}, result)"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"    def test_parse_root_device_hints_size_or_invalid(self):"},{"line_number":338,"context_line":"        hint \u003d \u0027\u003cor\u003e 123 \u003cor\u003e non-int \u003cor\u003e 789\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_0f6da8cc","line":335,"in_reply_to":"1ac06dbe_9dbf1360","updated":"2016-08-24 14:03:33.000000000","message":"It should yeah, perhaps I need to add another \"..._or\" test case for strings","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":391,"context_line":"    def test_extract_hint_operator_and_values_single_value(self):"},{"line_number":392,"context_line":"        expected \u003d {\u0027op\u0027: \u0027\u003e\u003d\u0027, \u0027values\u0027: [\u0027123\u0027]}"},{"line_number":393,"context_line":"        self.assertEqual("},{"line_number":394,"context_line":"            expected, utils._extract_hint_operator_and_values(\u0027\u003e\u003d 123\u0027))"},{"line_number":395,"context_line":""},{"line_number":396,"context_line":"    def test_extract_hint_operator_and_values_multiple_values(self):"},{"line_number":397,"context_line":"        expected \u003d {\u0027op\u0027: \u0027\u003cor\u003e\u0027, \u0027values\u0027: [\u0027123\u0027, \u0027456\u0027, \u0027789\u0027]}"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_18acd134","line":394,"updated":"2016-08-24 13:41:37.000000000","message":"What happens if it is \"\u0027\u0027\", or \"\u003e\u003d \"? Maybe they won\u0027t be parsed because they don\u0027t fit in the grammar?","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":391,"context_line":"    def test_extract_hint_operator_and_values_single_value(self):"},{"line_number":392,"context_line":"        expected \u003d {\u0027op\u0027: \u0027\u003e\u003d\u0027, \u0027values\u0027: [\u0027123\u0027]}"},{"line_number":393,"context_line":"        self.assertEqual("},{"line_number":394,"context_line":"            expected, utils._extract_hint_operator_and_values(\u0027\u003e\u003d 123\u0027))"},{"line_number":395,"context_line":""},{"line_number":396,"context_line":"    def test_extract_hint_operator_and_values_multiple_values(self):"},{"line_number":397,"context_line":"        expected \u003d {\u0027op\u0027: \u0027\u003cor\u003e\u0027, \u0027values\u0027: [\u0027123\u0027, \u0027456\u0027, \u0027789\u0027]}"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_8fc35838","line":394,"in_reply_to":"1ac06dbe_18acd134","updated":"2016-08-24 14:03:33.000000000","message":"You mean the operator being quoted ?\n\nThat does not work, apparently oslo_utils doesn\u0027t handle that correctly:\n\n In [4]: grammar.parseString(\u0027\"\u003e\u003d\" 123\u0027)\n Out[4]: ([\u0027\"\u003e\u003d\"\u0027], {})\n\n In [5]: grammar.parseString(\u0027\"\u003e\u003d 123\"\u0027)\n Out[5]: ([\u0027\"\u003e\u003d\u0027], {})","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":395,"context_line":""},{"line_number":396,"context_line":"    def test_extract_hint_operator_and_values_multiple_values(self):"},{"line_number":397,"context_line":"        expected \u003d {\u0027op\u0027: \u0027\u003cor\u003e\u0027, \u0027values\u0027: [\u0027123\u0027, \u0027456\u0027, \u0027789\u0027]}"},{"line_number":398,"context_line":"        hint \u003d \u0027\u003cor\u003e 123 \u003cor\u003e 456 \u003cor\u003e 789\u0027"},{"line_number":399,"context_line":"        self.assertEqual("},{"line_number":400,"context_line":"            expected, utils._extract_hint_operator_and_values(hint))"},{"line_number":401,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_2c3d12bc","line":398,"updated":"2016-08-24 13:41:37.000000000","message":"I\u0027d like to see a test that has a hint with spaces, unless that doesn\u0027t work. Eg\n\nhint \u003d \u0027\u003cor\u003e foo model \u003cor\u003e bar model \u003cor\u003e modelx\u0027","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":395,"context_line":""},{"line_number":396,"context_line":"    def test_extract_hint_operator_and_values_multiple_values(self):"},{"line_number":397,"context_line":"        expected \u003d {\u0027op\u0027: \u0027\u003cor\u003e\u0027, \u0027values\u0027: [\u0027123\u0027, \u0027456\u0027, \u0027789\u0027]}"},{"line_number":398,"context_line":"        hint \u003d \u0027\u003cor\u003e 123 \u003cor\u003e 456 \u003cor\u003e 789\u0027"},{"line_number":399,"context_line":"        self.assertEqual("},{"line_number":400,"context_line":"            expected, utils._extract_hint_operator_and_values(hint))"},{"line_number":401,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_cfdb9020","line":398,"in_reply_to":"1ac06dbe_2c3d12bc","updated":"2016-08-24 14:03:33.000000000","message":"Done","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":403,"context_line":"        expected \u003d {\u0027op\u0027: \u0027\u0027, \u0027values\u0027: [\u0027123\u0027]}"},{"line_number":404,"context_line":"        self.assertEqual("},{"line_number":405,"context_line":"            expected, utils._extract_hint_operator_and_values(\u0027123\u0027))"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    def test__append_operator_to_hints(self):"},{"line_number":408,"context_line":"        root_device \u003d {\u0027model\u0027: \u0027foo\u0027, \u0027size\u0027: 12345, \u0027rotational\u0027: True}"},{"line_number":409,"context_line":"        expected \u003d {\u0027model\u0027: \u0027s\u003d\u003dfoo\u0027, \u0027size\u0027: \u0027\u003d\u003d12345\u0027, \u0027rotational\u0027: True}"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_b8777d07","line":406,"updated":"2016-08-24 13:41:37.000000000","message":"should we add a test where ROOT_DEVICE_HINTS_GRAMMER.parseString() raises an exception? (pyparsing.ParseException)","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":403,"context_line":"        expected \u003d {\u0027op\u0027: \u0027\u0027, \u0027values\u0027: [\u0027123\u0027]}"},{"line_number":404,"context_line":"        self.assertEqual("},{"line_number":405,"context_line":"            expected, utils._extract_hint_operator_and_values(\u0027123\u0027))"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    def test__append_operator_to_hints(self):"},{"line_number":408,"context_line":"        root_device \u003d {\u0027model\u0027: \u0027foo\u0027, \u0027size\u0027: 12345, \u0027rotational\u0027: True}"},{"line_number":409,"context_line":"        expected \u003d {\u0027model\u0027: \u0027s\u003d\u003dfoo\u0027, \u0027size\u0027: \u0027\u003d\u003d12345\u0027, \u0027rotational\u0027: True}"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_0f82c8c8","line":406,"in_reply_to":"1ac06dbe_b8777d07","updated":"2016-08-24 14:03:33.000000000","message":"ops, we should actually handle that in code. I will take a look","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":405,"context_line":"            expected, utils._extract_hint_operator_and_values(\u0027123\u0027))"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    def test__append_operator_to_hints(self):"},{"line_number":408,"context_line":"        root_device \u003d {\u0027model\u0027: \u0027foo\u0027, \u0027size\u0027: 12345, \u0027rotational\u0027: True}"},{"line_number":409,"context_line":"        expected \u003d {\u0027model\u0027: \u0027s\u003d\u003dfoo\u0027, \u0027size\u0027: \u0027\u003d\u003d12345\u0027, \u0027rotational\u0027: True}"},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"        result \u003d utils._append_operator_to_hints(root_device)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_6ce38a34","line":408,"updated":"2016-08-24 13:41:37.000000000","message":"what about \u0027model\u0027: \u0027foo model\u0027 ?","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":405,"context_line":"            expected, utils._extract_hint_operator_and_values(\u0027123\u0027))"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    def test__append_operator_to_hints(self):"},{"line_number":408,"context_line":"        root_device \u003d {\u0027model\u0027: \u0027foo\u0027, \u0027size\u0027: 12345, \u0027rotational\u0027: True}"},{"line_number":409,"context_line":"        expected \u003d {\u0027model\u0027: \u0027s\u003d\u003dfoo\u0027, \u0027size\u0027: \u0027\u003d\u003d12345\u0027, \u0027rotational\u0027: True}"},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"        result \u003d utils._append_operator_to_hints(root_device)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_4fda00eb","line":408,"in_reply_to":"1ac06dbe_6ce38a34","updated":"2016-08-24 14:03:33.000000000","message":"_append_operator_to_hints() is called at the end of parse_root_device_hints(). So if we add a space here it will just return \"s\u003d\u003dfoo model\"","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":409,"context_line":"        expected \u003d {\u0027model\u0027: \u0027s\u003d\u003dfoo\u0027, \u0027size\u0027: \u0027\u003d\u003d12345\u0027, \u0027rotational\u0027: True}"},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"        result \u003d utils._append_operator_to_hints(root_device)"},{"line_number":412,"context_line":"        self.assertEqual(expected, result)"},{"line_number":413,"context_line":""},{"line_number":414,"context_line":"    def test_normalize_string_hint_or(self):"},{"line_number":415,"context_line":"        hint \u003d \u0027\u003cor\u003e foo \u003cor\u003e foo bar \u003cor\u003e bar\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_0c401607","line":412,"updated":"2016-08-24 13:41:37.000000000","message":"what if (or would it) ROOT_DEVICE_HINTS_GRAMMAR.parseString() raises an exception?","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":409,"context_line":"        expected \u003d {\u0027model\u0027: \u0027s\u003d\u003dfoo\u0027, \u0027size\u0027: \u0027\u003d\u003d12345\u0027, \u0027rotational\u0027: True}"},{"line_number":410,"context_line":""},{"line_number":411,"context_line":"        result \u003d utils._append_operator_to_hints(root_device)"},{"line_number":412,"context_line":"        self.assertEqual(expected, result)"},{"line_number":413,"context_line":""},{"line_number":414,"context_line":"    def test_normalize_string_hint_or(self):"},{"line_number":415,"context_line":"        hint \u003d \u0027\u003cor\u003e foo \u003cor\u003e foo bar \u003cor\u003e bar\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_8f80788d","line":412,"in_reply_to":"1ac06dbe_0c401607","updated":"2016-08-24 14:03:33.000000000","message":"++ will handle that in code as per comment L406","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":418,"context_line":"        self.assertEqual(expected, result)"},{"line_number":419,"context_line":""},{"line_number":420,"context_line":"    def test_normalize_string_hint_in(self):"},{"line_number":421,"context_line":"        hint \u003d \u0027\u003cor\u003e foo \u003cor\u003e foo bar \u003cor\u003e bar\u0027"},{"line_number":422,"context_line":"        expected \u003d \u0027\u003cor\u003efoo\u003cor\u003efoo%20bar\u003cor\u003ebar\u0027"},{"line_number":423,"context_line":"        result \u003d utils._normalize_string_hint(hint)"},{"line_number":424,"context_line":"        self.assertEqual(expected, result)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_ec293a39","line":421,"updated":"2016-08-24 13:41:37.000000000","message":"i think you might have wanted s/\u003cor\u003e/\u003cin\u003e/","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":418,"context_line":"        self.assertEqual(expected, result)"},{"line_number":419,"context_line":""},{"line_number":420,"context_line":"    def test_normalize_string_hint_in(self):"},{"line_number":421,"context_line":"        hint \u003d \u0027\u003cor\u003e foo \u003cor\u003e foo bar \u003cor\u003e bar\u0027"},{"line_number":422,"context_line":"        expected \u003d \u0027\u003cor\u003efoo\u003cor\u003efoo%20bar\u003cor\u003ebar\u0027"},{"line_number":423,"context_line":"        result \u003d utils._normalize_string_hint(hint)"},{"line_number":424,"context_line":"        self.assertEqual(expected, result)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_ef476c75","line":421,"in_reply_to":"1ac06dbe_ec293a39","updated":"2016-08-24 14:03:33.000000000","message":"urgh... yeah","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":421,"context_line":"    def test_extract_hint_operator_and_values_empty_value(self):"},{"line_number":422,"context_line":"        self.assertRaises("},{"line_number":423,"context_line":"            ValueError, utils._extract_hint_operator_and_values, \u0027\u0027, \u0027size\u0027)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"    def test__append_operator_to_hints(self):"},{"line_number":426,"context_line":"        root_device \u003d {\u0027serial\u0027: \u0027foo\u0027, \u0027size\u0027: 12345,"},{"line_number":427,"context_line":"                       \u0027model\u0027: \u0027foo model\u0027, \u0027rotational\u0027: True}"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_7872a212","line":424,"updated":"2016-08-29 20:19:39.000000000","message":"Can you add something like this? Wanted to make have a test with an \u0027int\u0027 value.\n\n     def test_extract_hint_operator_and_values_integer(self):\n        expected \u003d {\u0027op\u0027: \u0027\u0027, \u0027values\u0027: [\u0027123\u0027]}\n        self.assertEqual(\n            expected, utils._extract_hint_operator_and_values(123, \u0027size\u0027))","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":421,"context_line":"    def test_extract_hint_operator_and_values_empty_value(self):"},{"line_number":422,"context_line":"        self.assertRaises("},{"line_number":423,"context_line":"            ValueError, utils._extract_hint_operator_and_values, \u0027\u0027, \u0027size\u0027)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"    def test__append_operator_to_hints(self):"},{"line_number":426,"context_line":"        root_device \u003d {\u0027serial\u0027: \u0027foo\u0027, \u0027size\u0027: 12345,"},{"line_number":427,"context_line":"                       \u0027model\u0027: \u0027foo model\u0027, \u0027rotational\u0027: True}"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_a4af867b","line":424,"in_reply_to":"fa7ab95a_7872a212","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"}],"ironic_lib/utils.py":[{"author":{"_account_id":14525,"name":"Vasyl Saienko","email":"vsaienko@mirantis.com","username":"vsaienko"},"change_message_id":"40725252d00888a717f8bd7ada02c94a7eec997e","unresolved":false,"context_lines":[{"line_number":192,"context_line":"    return ast[1:]"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"def _append_operator_to_hints(root_device):"},{"line_number":196,"context_line":"    \"\"\"Add an equal (s\u003d\u003d or \u003d\u003d) operator to the hints."},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    In order to keep the backwards compatibility with the root device"}],"source_content_type":"text/x-python","patch_set":3,"id":"1ac06dbe_77ed7cb6","line":195,"updated":"2016-08-23 07:53:12.000000000","message":"Are we going to deprecate to old syntax? My personal feeling that we should do it.","commit_id":"09da0e5b6a17592a373214c807b8af08e1b3402e"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f88030405d431531543c125c807ad08a2fd357db","unresolved":false,"context_lines":[{"line_number":192,"context_line":"    return ast[1:]"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"def _append_operator_to_hints(root_device):"},{"line_number":196,"context_line":"    \"\"\"Add an equal (s\u003d\u003d or \u003d\u003d) operator to the hints."},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    In order to keep the backwards compatibility with the root device"}],"source_content_type":"text/x-python","patch_set":3,"id":"1ac06dbe_2429eb9e","line":195,"in_reply_to":"1ac06dbe_77ed7cb6","updated":"2016-08-23 16:24:43.000000000","message":"Hi Vasyl,\n\nYes I think we should as well, we should raise a warning message in Ironic when the user update the root device hints.\n\nFor now, we should keep it backward compatible for at least a release cycle.","commit_id":"09da0e5b6a17592a373214c807b8af08e1b3402e"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    A root device hint could contain one or more values depending on the"},{"line_number":184,"context_line":"    operator. This method extracts the value(s) and return it in a list."},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    :returns: A list with the value(s)."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_5a4b1c59","line":185,"updated":"2016-08-23 17:53:18.000000000","message":":param hint: this is a string? what is its format?","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    A root device hint could contain one or more values depending on the"},{"line_number":184,"context_line":"    operator. This method extracts the value(s) and return it in a list."},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"    :returns: A list with the value(s)."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_7a0fcf36","line":185,"in_reply_to":"1ac06dbe_5a4b1c59","updated":"2016-08-24 11:05:55.000000000","message":"ops, yes it\u0027s a string","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":193,"context_line":"    return ast[1:]"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"def _normalize_string_hints(hint_value):"},{"line_number":197,"context_line":"    \"\"\"Normalize a string type hint."},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    Normalize a string type hint by replacing whitespaces and special"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_1a8d24d6","line":196,"updated":"2016-08-23 17:53:18.000000000","message":"It is one hint, right? I\u0027d probably call it _normalize_string or _normalize_hint or _normalize_string_hint.\n\nWhat\u0027s the difference between a \u0027hint\u0027 and a \u0027hint_value\u0027?","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":193,"context_line":"    return ast[1:]"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"def _normalize_string_hints(hint_value):"},{"line_number":197,"context_line":"    \"\"\"Normalize a string type hint."},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    Normalize a string type hint by replacing whitespaces and special"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_453838d3","line":196,"in_reply_to":"1ac06dbe_1a8d24d6","updated":"2016-08-24 11:05:55.000000000","message":"+1 for the name _normalize_string_hint (I would like to be explicitly about the type).\n\nOh they are the same, probably just not consistent because I added this function later after founding out about the space problem :-(\n\nI will make it consistent in the next patch-set.","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":197,"context_line":"    \"\"\"Normalize a string type hint."},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    Normalize a string type hint by replacing whitespaces and special"},{"line_number":200,"context_line":"    characters using the %xx escape."},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    :param hint_value: The hint value string."},{"line_number":203,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_7a0b78d6","line":200,"updated":"2016-08-23 17:53:18.000000000","message":"Unless it has one of the \u003cin\u003e, \u003cor\u003e operators...\n\nHow about \u0027Normalize a string by url-encoding white spaces and special characters.\u0027 Strings with the \u0027\u003cin\u003e\u0027 or \u0027\u003cor\u003e\u0027 operators are not touched.","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":197,"context_line":"    \"\"\"Normalize a string type hint."},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    Normalize a string type hint by replacing whitespaces and special"},{"line_number":200,"context_line":"    characters using the %xx escape."},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    :param hint_value: The hint value string."},{"line_number":203,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_65445449","line":200,"in_reply_to":"1ac06dbe_7a0b78d6","updated":"2016-08-24 11:05:55.000000000","message":"Sounds great, thanks","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":199,"context_line":"    Normalize a string type hint by replacing whitespaces and special"},{"line_number":200,"context_line":"    characters using the %xx escape."},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    :param hint_value: The hint value string."},{"line_number":203,"context_line":"    \"\"\""},{"line_number":204,"context_line":"    hint_value \u003d six.text_type(hint_value).strip().lower()"},{"line_number":205,"context_line":"    if any([op in hint_value for op in (\u0027\u003cin\u003e\u0027, \u0027\u003cor\u003e\u0027)]):"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_ee3a0ae6","line":202,"updated":"2016-08-23 17:53:18.000000000","message":"i suppose it is described in the oslo library, so i should look there. But what is the format of this string. It looks like (from the code below) it could be:\nstring with \u0027\u003cin\u003e\u0027 or \u0027\u003cor\u003e\u0027\n\u003coperator\u003e \u003cstring perhaps separated by spaces\u003e\nstring perhaps separated by spaces\n\nIs that true? Would it be useful to add doc about that?","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":199,"context_line":"    Normalize a string type hint by replacing whitespaces and special"},{"line_number":200,"context_line":"    characters using the %xx escape."},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    :param hint_value: The hint value string."},{"line_number":203,"context_line":"    \"\"\""},{"line_number":204,"context_line":"    hint_value \u003d six.text_type(hint_value).strip().lower()"},{"line_number":205,"context_line":"    if any([op in hint_value for op in (\u0027\u003cin\u003e\u0027, \u0027\u003cor\u003e\u0027)]):"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_607a82be","line":202,"in_reply_to":"1ac06dbe_ee3a0ae6","updated":"2016-08-24 11:05:55.000000000","message":"That\u0027s true, I think I can parse those as well. I will work on a enhanced version for it","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":205,"context_line":"    if any([op in hint_value for op in (\u0027\u003cin\u003e\u0027, \u0027\u003cor\u003e\u0027)]):"},{"line_number":206,"context_line":"        return hint_value"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    splitted \u003d hint_value.split()"},{"line_number":209,"context_line":"    if len(splitted) \u003e 1 and splitted[0] in specs_matcher.op_methods:"},{"line_number":210,"context_line":"        splitted \u003d splitted[1:]"},{"line_number":211,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_da98ac6c","line":208,"updated":"2016-08-23 17:53:18.000000000","message":"\u0027splitted\u0027 exists as a word I think, but I\u0027m not sure how it is used. When you split something yesterday, it was split, not splitted. How about \u0027terms\u0027 or \u0027tokens\u0027 or something like that instead.","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":205,"context_line":"    if any([op in hint_value for op in (\u0027\u003cin\u003e\u0027, \u0027\u003cor\u003e\u0027)]):"},{"line_number":206,"context_line":"        return hint_value"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    splitted \u003d hint_value.split()"},{"line_number":209,"context_line":"    if len(splitted) \u003e 1 and splitted[0] in specs_matcher.op_methods:"},{"line_number":210,"context_line":"        splitted \u003d splitted[1:]"},{"line_number":211,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_c5a0a8f6","line":208,"in_reply_to":"1ac06dbe_da98ac6c","updated":"2016-08-24 11:05:55.000000000","message":"Done","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"efbe32287722d18361bf77c710d91d7002be53c2","unresolved":false,"context_lines":[{"line_number":206,"context_line":"        return hint_value"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    splitted \u003d hint_value.split()"},{"line_number":209,"context_line":"    if len(splitted) \u003e 1 and splitted[0] in specs_matcher.op_methods:"},{"line_number":210,"context_line":"        splitted \u003d splitted[1:]"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    return parse.quote(\u0027 \u0027.join(splitted))"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_ce374e4b","line":209,"range":{"start_line":209,"start_character":44,"end_line":209,"end_character":68},"updated":"2016-08-23 17:42:01.000000000","message":"It means we\u0027re dropping things like s!\u003d here? And they become s\u003d\u003d in _append_operator_to_hints","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":206,"context_line":"        return hint_value"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    splitted \u003d hint_value.split()"},{"line_number":209,"context_line":"    if len(splitted) \u003e 1 and splitted[0] in specs_matcher.op_methods:"},{"line_number":210,"context_line":"        splitted \u003d splitted[1:]"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    return parse.quote(\u0027 \u0027.join(splitted))"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_6523b456","line":209,"range":{"start_line":209,"start_character":44,"end_line":209,"end_character":68},"in_reply_to":"1ac06dbe_ce374e4b","updated":"2016-08-24 11:05:55.000000000","message":"Great catch! I was suppose to save the operator (index 0)","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":218,"context_line":"    In order to keep the backwards compatibility with the root device"},{"line_number":219,"context_line":"    hints where no operator means equal, this method is explicitly adding"},{"line_number":220,"context_line":"    the equal operators to the hints with no operators when parsing it in"},{"line_number":221,"context_line":"    order to facilitate the use of the match() method from oslo.utils."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    for hint, value in root_device.items():"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_582fa487","line":221,"updated":"2016-08-23 17:53:18.000000000","message":"How about\n\nFor backwards compatibility, for root device hints where no operator means equal, this method adds the equal operator to the hint. This is needed when using oslo.utils.specs_matcher methods.","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":218,"context_line":"    In order to keep the backwards compatibility with the root device"},{"line_number":219,"context_line":"    hints where no operator means equal, this method is explicitly adding"},{"line_number":220,"context_line":"    the equal operators to the hints with no operators when parsing it in"},{"line_number":221,"context_line":"    order to facilitate the use of the match() method from oslo.utils."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    for hint, value in root_device.items():"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_20436a6d","line":221,"in_reply_to":"1ac06dbe_582fa487","updated":"2016-08-24 11:05:55.000000000","message":"sounds much better! Thank you","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":219,"context_line":"    hints where no operator means equal, this method is explicitly adding"},{"line_number":220,"context_line":"    the equal operators to the hints with no operators when parsing it in"},{"line_number":221,"context_line":"    order to facilitate the use of the match() method from oslo.utils."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    for hint, value in root_device.items():"},{"line_number":225,"context_line":"        # NOTE(lucasagomes): The specs_matcher from oslo.utils do not"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_786260d9","line":222,"updated":"2016-08-23 17:53:18.000000000","message":":param root_device: ...","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":219,"context_line":"    hints where no operator means equal, this method is explicitly adding"},{"line_number":220,"context_line":"    the equal operators to the hints with no operators when parsing it in"},{"line_number":221,"context_line":"    order to facilitate the use of the match() method from oslo.utils."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    for hint, value in root_device.items():"},{"line_number":225,"context_line":"        # NOTE(lucasagomes): The specs_matcher from oslo.utils do not"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_6061e204","line":222,"in_reply_to":"1ac06dbe_786260d9","updated":"2016-08-24 11:05:55.000000000","message":"Done","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    for hint, value in root_device.items():"},{"line_number":225,"context_line":"        # NOTE(lucasagomes): The specs_matcher from oslo.utils do not"},{"line_number":226,"context_line":"        # support boolean, so we don\u0027t need to append any operator"},{"line_number":227,"context_line":"        # for it."},{"line_number":228,"context_line":"        if VALID_ROOT_DEVICE_HINTS[hint] is bool:"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_f8565004","line":225,"updated":"2016-08-23 17:53:18.000000000","message":"s/do not/does not/","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    for hint, value in root_device.items():"},{"line_number":225,"context_line":"        # NOTE(lucasagomes): The specs_matcher from oslo.utils do not"},{"line_number":226,"context_line":"        # support boolean, so we don\u0027t need to append any operator"},{"line_number":227,"context_line":"        # for it."},{"line_number":228,"context_line":"        if VALID_ROOT_DEVICE_HINTS[hint] is bool:"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_a0575a24","line":225,"in_reply_to":"1ac06dbe_f8565004","updated":"2016-08-24 11:05:55.000000000","message":"Done","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"efbe32287722d18361bf77c710d91d7002be53c2","unresolved":false,"context_lines":[{"line_number":264,"context_line":"            _(\u0027The hints \"%(invalid_hints)s\" are invalid. \u0027"},{"line_number":265,"context_line":"              \u0027Valid hints are: \"%(valid_hints)s\"\u0027) %"},{"line_number":266,"context_line":"            {\u0027invalid_hints\u0027: \u0027, \u0027.join(invalid_hints),"},{"line_number":267,"context_line":"             \u0027valid_hints\u0027: \u0027, \u0027.join(VALID_ROOT_DEVICE_HINTS)})"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    for hint, value in root_device.items():"},{"line_number":270,"context_line":"        hint_type \u003d VALID_ROOT_DEVICE_HINTS[hint]"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_ddb38608","line":267,"range":{"start_line":267,"start_character":28,"end_line":267,"end_character":32},"updated":"2016-08-23 17:42:01.000000000","message":"Might want to include both name and type here.","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":264,"context_line":"            _(\u0027The hints \"%(invalid_hints)s\" are invalid. \u0027"},{"line_number":265,"context_line":"              \u0027Valid hints are: \"%(valid_hints)s\"\u0027) %"},{"line_number":266,"context_line":"            {\u0027invalid_hints\u0027: \u0027, \u0027.join(invalid_hints),"},{"line_number":267,"context_line":"             \u0027valid_hints\u0027: \u0027, \u0027.join(VALID_ROOT_DEVICE_HINTS)})"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    for hint, value in root_device.items():"},{"line_number":270,"context_line":"        hint_type \u003d VALID_ROOT_DEVICE_HINTS[hint]"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_80005e03","line":267,"range":{"start_line":267,"start_character":28,"end_line":267,"end_character":32},"in_reply_to":"1ac06dbe_ddb38608","updated":"2016-08-24 11:05:55.000000000","message":"Done","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"4c1681e7280144f1313cec161d236161abac84b7","unresolved":false,"context_lines":[{"line_number":271,"context_line":"        if hint_type is str:"},{"line_number":272,"context_line":"            if not isinstance(value, six.string_types):"},{"line_number":273,"context_line":"                raise ValueError("},{"line_number":274,"context_line":"                    _(\u0027Root device hint %(hint)s is not a string value. \u0027"},{"line_number":275,"context_line":"                      \u0027Current value: %(value)s\u0027) % {\u0027hint\u0027: hint,"},{"line_number":276,"context_line":"                                                     \u0027value\u0027: value})"},{"line_number":277,"context_line":"            root_device[hint] \u003d _normalize_string_hints(value)"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_89e390d8","line":274,"updated":"2016-08-23 17:53:18.000000000","message":"maybe s/%(hint)s/\"%(hint)s\"/","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"486a6d0510cca97efdafcf3286d3a4268b6f442f","unresolved":false,"context_lines":[{"line_number":271,"context_line":"        if hint_type is str:"},{"line_number":272,"context_line":"            if not isinstance(value, six.string_types):"},{"line_number":273,"context_line":"                raise ValueError("},{"line_number":274,"context_line":"                    _(\u0027Root device hint %(hint)s is not a string value. \u0027"},{"line_number":275,"context_line":"                      \u0027Current value: %(value)s\u0027) % {\u0027hint\u0027: hint,"},{"line_number":276,"context_line":"                                                     \u0027value\u0027: value})"},{"line_number":277,"context_line":"            root_device[hint] \u003d _normalize_string_hints(value)"}],"source_content_type":"text/x-python","patch_set":5,"id":"1ac06dbe_4b116751","line":274,"in_reply_to":"1ac06dbe_89e390d8","updated":"2016-08-24 11:05:55.000000000","message":"Done","commit_id":"dfc5e900c9ec68d9441eed4e17d90161183c6259"},{"author":{"_account_id":6637,"name":"Sam Betts","email":"sam@code-smash.net","username":"sambetts"},"change_message_id":"dfdf6fd340721215a4a7286874649757b7b4e417","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        return {\u0027op\u0027: \u0027\u0027, \u0027values\u0027: [hint_value]}"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    op \u003d ast[0]"},{"line_number":200,"context_line":"    return {\u0027values\u0027: [v.strip() for v in re.split(op, hint_value)[0::1] if v],"},{"line_number":201,"context_line":"            \u0027op\u0027: op}"},{"line_number":202,"context_line":""},{"line_number":203,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1ac06dbe_3f0ffc37","line":200,"range":{"start_line":200,"start_character":66,"end_line":200,"end_character":72},"updated":"2016-08-24 11:50:50.000000000","message":"This just returns the original list.","commit_id":"916a80e9eec505a7356ddc76a4bc93f904b187ed"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":182,"context_line":"    \"\"\"Extract the operator and value(s) of a root device hint."},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    A root device hint could contain one or more values depending on the"},{"line_number":185,"context_line":"    operator. This method extracts the operator and value(s) and return"},{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    :param hint_value: The hint value string."}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_d25dfa7a","line":185,"updated":"2016-08-24 13:41:37.000000000","message":"s/return/returns/","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":182,"context_line":"    \"\"\"Extract the operator and value(s) of a root device hint."},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    A root device hint could contain one or more values depending on the"},{"line_number":185,"context_line":"    operator. This method extracts the operator and value(s) and return"},{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    :param hint_value: The hint value string."}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_af3454fb","line":185,"in_reply_to":"1ac06dbe_d25dfa7a","updated":"2016-08-24 14:03:33.000000000","message":"Done","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    :param hint_value: The hint value string."},{"line_number":189,"context_line":"    :returns: A dictionary in containg:"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"        :op: The operator. An empty string in case of None."},{"line_number":192,"context_line":"        :values: A list of values."}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_72c36639","line":189,"updated":"2016-08-24 13:41:37.000000000","message":"s/in containg/containing/","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    :param hint_value: The hint value string."},{"line_number":189,"context_line":"    :returns: A dictionary in containg:"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"        :op: The operator. An empty string in case of None."},{"line_number":192,"context_line":"        :values: A list of values."}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_0f3ac8e7","line":189,"in_reply_to":"1ac06dbe_72c36639","updated":"2016-08-24 14:03:33.000000000","message":"Done","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b21fa5d77846cf9b3f6b97c9c6601b21352b255e","unresolved":false,"context_lines":[{"line_number":280,"context_line":"            root_device[hint] \u003d _normalize_string_hint(value)"},{"line_number":281,"context_line":""},{"line_number":282,"context_line":"        elif hint_type is int:"},{"line_number":283,"context_line":"            for v in _extract_hint_operator_and_values(value)[\u0027values\u0027]:"},{"line_number":284,"context_line":"                try:"},{"line_number":285,"context_line":"                    integer \u003d int(v)"},{"line_number":286,"context_line":"                except ValueError:"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_78bd0502","line":283,"updated":"2016-08-24 13:41:37.000000000","message":"value might not be a string, right? In one of your tests, it is an integer. How does _extract_hint_operator..() handle non-strings?","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"a33072943583df53fd46751150e6a2966d3c4c8f","unresolved":false,"context_lines":[{"line_number":280,"context_line":"            root_device[hint] \u003d _normalize_string_hint(value)"},{"line_number":281,"context_line":""},{"line_number":282,"context_line":"        elif hint_type is int:"},{"line_number":283,"context_line":"            for v in _extract_hint_operator_and_values(value)[\u0027values\u0027]:"},{"line_number":284,"context_line":"                try:"},{"line_number":285,"context_line":"                    integer \u003d int(v)"},{"line_number":286,"context_line":"                except ValueError:"}],"source_content_type":"text/x-python","patch_set":7,"id":"1ac06dbe_82616fd6","line":283,"in_reply_to":"1ac06dbe_78bd0502","updated":"2016-08-24 14:03:33.000000000","message":"The method converts int to strings (specs_matcher.match() handles strings) and always return a list (even if there\u0027s only 1 item on it).","commit_id":"89afb14c4a268ff776b17b0be294a7574ddab85c"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"7bc64b0ee240d2f13a074cef16ae44a53becbc99","unresolved":false,"context_lines":[{"line_number":189,"context_line":"    :returns: A dictionary containing:"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"        :op: The operator. An empty string in case of None."},{"line_number":192,"context_line":"        :values: A list of values."},{"line_number":193,"context_line":"    \"\"\""},{"line_number":194,"context_line":"    hint_value \u003d six.text_type(hint_value).strip().lower()"},{"line_number":195,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(hint_value)"}],"source_content_type":"text/x-python","patch_set":8,"id":"1ac06dbe_5bb907ec","line":192,"updated":"2016-08-24 21:08:48.000000000","message":"Should be documented that everything is forced to lowercase.","commit_id":"4e938b4cc73e634b32b799ab6bbd02ac45679a1f"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"720155ab6be8a9298e77612d22734be67587f06b","unresolved":false,"context_lines":[{"line_number":189,"context_line":"    :returns: A dictionary containing:"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"        :op: The operator. An empty string in case of None."},{"line_number":192,"context_line":"        :values: A list of values."},{"line_number":193,"context_line":"    \"\"\""},{"line_number":194,"context_line":"    hint_value \u003d six.text_type(hint_value).strip().lower()"},{"line_number":195,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(hint_value)"}],"source_content_type":"text/x-python","patch_set":8,"id":"1ac06dbe_1f23dba8","line":192,"in_reply_to":"1ac06dbe_5bb907ec","updated":"2016-08-25 08:27:34.000000000","message":"This is part of normalizing a string, to facilitate string comparison. It can be documented tho","commit_id":"4e938b4cc73e634b32b799ab6bbd02ac45679a1f"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"7bc64b0ee240d2f13a074cef16ae44a53becbc99","unresolved":false,"context_lines":[{"line_number":205,"context_line":"    \"\"\"Normalize a string type hint."},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    Normalize a string by url-encoding white spaces and special"},{"line_number":208,"context_line":"    characters."},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    :param hint_value: The hint value string."},{"line_number":211,"context_line":"    :returns: A normalized string"}],"source_content_type":"text/x-python","patch_set":8,"id":"1ac06dbe_5b2aa7e8","line":208,"updated":"2016-08-24 21:08:48.000000000","message":"It seems that it only normalizes the values in the string. Reading this makes me think that.\n\n \"\u003cor\u003e 123 \u003cor\u003e 125\"\n\nwould become\n\n \"\u003cor\u003e%20123%20\u003cor\u003e%125\"\n\nor\n\n \"%3Cor%3E%20123%20%3Cor%3E%20125\"\n\nWould be good to update the docs.","commit_id":"4e938b4cc73e634b32b799ab6bbd02ac45679a1f"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"720155ab6be8a9298e77612d22734be67587f06b","unresolved":false,"context_lines":[{"line_number":205,"context_line":"    \"\"\"Normalize a string type hint."},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    Normalize a string by url-encoding white spaces and special"},{"line_number":208,"context_line":"    characters."},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    :param hint_value: The hint value string."},{"line_number":211,"context_line":"    :returns: A normalized string"}],"source_content_type":"text/x-python","patch_set":8,"id":"1ac06dbe_94d692ef","line":208,"in_reply_to":"1ac06dbe_5b2aa7e8","updated":"2016-08-25 08:27:34.000000000","message":"Yes, it does not normalize the operators and it strips the whitespaces around the elements as well, so:\n\n\"\u003cor\u003e 123 \u003cor\u003e 125\" will be parsed the same.\n\nWhen you have spaces/special characters within the elements then it uses the %xxx mask on it (url-encode), e.g:\n\n\"\u003cor\u003e foo bar \u003cor\u003e bar\" then it will become \"\u003cor\u003e foo%20bar \u003cor\u003e bar\"\n\n(see unittests)","commit_id":"4e938b4cc73e634b32b799ab6bbd02ac45679a1f"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"7bc64b0ee240d2f13a074cef16ae44a53becbc99","unresolved":false,"context_lines":[{"line_number":242,"context_line":"    return root_device"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"def parse_root_device_hints(root_device):"},{"line_number":246,"context_line":"    \"\"\"Parse the root_device property of a node."},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    Parses and validates the root_device property of a node. These are"}],"source_content_type":"text/x-python","patch_set":8,"id":"1ac06dbe_1655a6c5","line":245,"updated":"2016-08-24 21:08:48.000000000","message":"I see this function in both ironic-lib and ironic.\n\nIs that intentional?\n\nThis seems like breaking changes. So not sure how Ironic will start using this.","commit_id":"4e938b4cc73e634b32b799ab6bbd02ac45679a1f"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"720155ab6be8a9298e77612d22734be67587f06b","unresolved":false,"context_lines":[{"line_number":242,"context_line":"    return root_device"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"def parse_root_device_hints(root_device):"},{"line_number":246,"context_line":"    \"\"\"Parse the root_device property of a node."},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"    Parses and validates the root_device property of a node. These are"}],"source_content_type":"text/x-python","patch_set":8,"id":"1ac06dbe_94017209","line":245,"in_reply_to":"1ac06dbe_1655a6c5","updated":"2016-08-25 08:27:34.000000000","message":"It was recently moved to here. IPA and inspector also have a similar function to parse the root device hints. The idea is to centralize it and have all projects to use this one.\n\nAbout backward compat, Ironic will use this function only to validate the root device hints. In the past we also used to parse it and create a string that would be passed to the ramdisk via the kernel cmdline but that should be removed soon (see https://review.openstack.org/#/c/318538/) because we no longer support the bash ramdisk (the only way to pass information from ironic to the bash ramdisk was via kernel cmdline).","commit_id":"4e938b4cc73e634b32b799ab6bbd02ac45679a1f"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"6de2dfbd99200738d063caf5e606395aee5e8786","unresolved":false,"context_lines":[{"line_number":191,"context_line":"    :returns: A dictionary containing:"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        :op: The operator. An empty string in case of None."},{"line_number":194,"context_line":"        :values: A list of values stripped and converted to lowercase."},{"line_number":195,"context_line":"    \"\"\""},{"line_number":196,"context_line":"    hint_value \u003d six.text_type(hint_value).strip().lower()"},{"line_number":197,"context_line":"    if not hint_value:"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_0d0570c1","line":194,"updated":"2016-08-25 10:40:46.000000000","message":"that will be stripped and converted ...","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"26f09b826542bdf96c4f577733d29e2f5db87147","unresolved":false,"context_lines":[{"line_number":191,"context_line":"    :returns: A dictionary containing:"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        :op: The operator. An empty string in case of None."},{"line_number":194,"context_line":"        :values: A list of values stripped and converted to lowercase."},{"line_number":195,"context_line":"    \"\"\""},{"line_number":196,"context_line":"    hint_value \u003d six.text_type(hint_value).strip().lower()"},{"line_number":197,"context_line":"    if not hint_value:"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_065b85f7","line":194,"in_reply_to":"1ac06dbe_0d0570c1","updated":"2016-08-25 13:27:03.000000000","message":"That\u0027s the :returns: so they are already stripped","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b60ab68e28b969bb5dd4e40e2aa2030f659cf7ed","unresolved":false,"context_lines":[{"line_number":209,"context_line":"def _normalize_string_hint(hint_name, hint_value):"},{"line_number":210,"context_line":"    \"\"\"Normalize a string type hint value."},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    Normalize a string type hint value by url-encoding white spaces and"},{"line_number":213,"context_line":"    special characters. This method does not normalize the operators,"},{"line_number":214,"context_line":"    for example: A hint value of \"\u003cor\u003e foo bar \u003cor\u003e bar\" will become"},{"line_number":215,"context_line":"    \"\u003cor\u003e foo%20bar \u003cor\u003e bar\"."}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_e0e9f6b8","line":212,"updated":"2016-08-25 11:51:25.000000000","message":"Hmm, this is a bit awkward. You are normalizing the values (not operators) in a string type hint value.\n\nMaybe change \u0027hint_value\u0027 to \u0027hint\u0027 (and hint_name to name?) so it isn\u0027t so confusing when \u0027value\u0027 is mentioned. (Or use another term for the values in the hint.) eg:\n\nA string-type hint contains one or more operators and one or more values: [\u003cop\u003e] \u003cvalue\u003e [\u003cop\u003e \u003cvalue\u003e]*. This normalizes the values by url-encoding white spaces and special characters. The operators are not normalized. For example: the hint \"...\"\n\nOr if you want to keep \u0027hint_value\u0027, change the \u003cvalue\u003e to eg \u003ctoken\u003e and say you\u0027re normalizing the tokens.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"26f09b826542bdf96c4f577733d29e2f5db87147","unresolved":false,"context_lines":[{"line_number":209,"context_line":"def _normalize_string_hint(hint_name, hint_value):"},{"line_number":210,"context_line":"    \"\"\"Normalize a string type hint value."},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    Normalize a string type hint value by url-encoding white spaces and"},{"line_number":213,"context_line":"    special characters. This method does not normalize the operators,"},{"line_number":214,"context_line":"    for example: A hint value of \"\u003cor\u003e foo bar \u003cor\u003e bar\" will become"},{"line_number":215,"context_line":"    \"\u003cor\u003e foo%20bar \u003cor\u003e bar\"."}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_f28264c7","line":212,"in_reply_to":"1ac06dbe_e0e9f6b8","updated":"2016-08-25 13:27:03.000000000","message":"Done","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b60ab68e28b969bb5dd4e40e2aa2030f659cf7ed","unresolved":false,"context_lines":[{"line_number":217,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":218,"context_line":"    :param hint_value: The hint value string."},{"line_number":219,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":220,"context_line":"    :returns: A normalized string."},{"line_number":221,"context_line":"    \"\"\""},{"line_number":222,"context_line":"    hint \u003d _extract_hint_operator_and_values(hint_name, hint_value)"},{"line_number":223,"context_line":"    result \u003d hint[\u0027op\u0027].join([\u0027 %s \u0027 % parse.quote(t) for t in hint[\u0027values\u0027]])"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_fde7dda9","line":220,"updated":"2016-08-25 11:51:25.000000000","message":"oh, I missed this. the hint value, in the form of a dictionary with \u0027op\u0027 : operator and \u0027values\u0027: [values].","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"26f09b826542bdf96c4f577733d29e2f5db87147","unresolved":false,"context_lines":[{"line_number":217,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":218,"context_line":"    :param hint_value: The hint value string."},{"line_number":219,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":220,"context_line":"    :returns: A normalized string."},{"line_number":221,"context_line":"    \"\"\""},{"line_number":222,"context_line":"    hint \u003d _extract_hint_operator_and_values(hint_name, hint_value)"},{"line_number":223,"context_line":"    result \u003d hint[\u0027op\u0027].join([\u0027 %s \u0027 % parse.quote(t) for t in hint[\u0027values\u0027]])"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_b25f4c74","line":220,"in_reply_to":"1ac06dbe_fde7dda9","updated":"2016-08-25 13:27:03.000000000","message":"This one will actually return the string. The _extract... function will return a dictionary.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"307216044cfb574da798fe7b18667f00533d02b0","unresolved":false,"context_lines":[{"line_number":289,"context_line":"            root_device[hint] \u003d _normalize_string_hint(hint, value)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        elif hint_type is int:"},{"line_number":292,"context_line":"            for v in _extract_hint_operator_and_values(hint, value)[\u0027values\u0027]:"},{"line_number":293,"context_line":"                try:"},{"line_number":294,"context_line":"                    integer \u003d int(v)"},{"line_number":295,"context_line":"                except ValueError:"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_c3ede48f","line":292,"updated":"2016-08-25 12:09:36.000000000","message":"_extract_hint_operator_and_values() expects value to be a string but there is nothing here that checks for that.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4e0e6468ab47470cf2eef3307a78cbd3a33aa009","unresolved":false,"context_lines":[{"line_number":289,"context_line":"            root_device[hint] \u003d _normalize_string_hint(hint, value)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        elif hint_type is int:"},{"line_number":292,"context_line":"            for v in _extract_hint_operator_and_values(hint, value)[\u0027values\u0027]:"},{"line_number":293,"context_line":"                try:"},{"line_number":294,"context_line":"                    integer \u003d int(v)"},{"line_number":295,"context_line":"                except ValueError:"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_c61172b1","line":292,"in_reply_to":"1ac06dbe_c3ede48f","updated":"2016-08-25 12:25:10.000000000","message":"Hm it expects an object that is possible to convert to a string, which is, I guess, all objects? Tho might be worth checking that it does not become something like u\u0027\u003c__main__.A object at 0x7f5112779a90\u003e\u0027 after conversion to string if a random object is passed here.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"26f09b826542bdf96c4f577733d29e2f5db87147","unresolved":false,"context_lines":[{"line_number":289,"context_line":"            root_device[hint] \u003d _normalize_string_hint(hint, value)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        elif hint_type is int:"},{"line_number":292,"context_line":"            for v in _extract_hint_operator_and_values(hint, value)[\u0027values\u0027]:"},{"line_number":293,"context_line":"                try:"},{"line_number":294,"context_line":"                    integer \u003d int(v)"},{"line_number":295,"context_line":"                except ValueError:"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_f23a64e6","line":292,"in_reply_to":"1ac06dbe_c61172b1","updated":"2016-08-25 13:27:03.000000000","message":"Yeah it expects a object that will be converted by hint. In this case it\u0027s expecting an int-like object, if something like @vdrok\u0027s pointed out is passed it will fail on the next lines where it tries to convert to integer.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"6de2dfbd99200738d063caf5e606395aee5e8786","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        elif hint_type is bool:"},{"line_number":308,"context_line":"            try:"},{"line_number":309,"context_line":"                root_device[hint] \u003d strutils.bool_from_string("},{"line_number":310,"context_line":"                    value, strict\u003dTrue)"},{"line_number":311,"context_line":"            except ValueError:"},{"line_number":312,"context_line":"                raise ValueError("},{"line_number":313,"context_line":"                    _(\u0027Root device hint \"%(hint)s\" is not a Boolean value. \u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_08ca7e1a","line":310,"range":{"start_line":310,"start_character":20,"end_line":310,"end_character":25},"updated":"2016-08-25 10:40:46.000000000","message":"It means that it is not possible to add an operator to boolean hint, worth mentioning somewhere.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"6e3d21a1b18cad348045bebfdee6a032f4684baa","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        elif hint_type is bool:"},{"line_number":308,"context_line":"            try:"},{"line_number":309,"context_line":"                root_device[hint] \u003d strutils.bool_from_string("},{"line_number":310,"context_line":"                    value, strict\u003dTrue)"},{"line_number":311,"context_line":"            except ValueError:"},{"line_number":312,"context_line":"                raise ValueError("},{"line_number":313,"context_line":"                    _(\u0027Root device hint \"%(hint)s\" is not a Boolean value. \u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_7804847d","line":310,"range":{"start_line":310,"start_character":20,"end_line":310,"end_character":25},"in_reply_to":"1ac06dbe_062385a8","updated":"2016-08-25 17:05:12.000000000","message":"Yup, I get that, L237 says ironic-lib won\u0027t append it, but you can not append it youself too (ie \u0027\u003d\u003d True\u0027), it will lead to an error. I am perfectly fine with following up separately.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"26f09b826542bdf96c4f577733d29e2f5db87147","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        elif hint_type is bool:"},{"line_number":308,"context_line":"            try:"},{"line_number":309,"context_line":"                root_device[hint] \u003d strutils.bool_from_string("},{"line_number":310,"context_line":"                    value, strict\u003dTrue)"},{"line_number":311,"context_line":"            except ValueError:"},{"line_number":312,"context_line":"                raise ValueError("},{"line_number":313,"context_line":"                    _(\u0027Root device hint \"%(hint)s\" is not a Boolean value. \u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_062385a8","line":310,"range":{"start_line":310,"start_character":20,"end_line":310,"end_character":25},"in_reply_to":"1ac06dbe_08ca7e1a","updated":"2016-08-25 13:27:03.000000000","message":"Correct yeah, currently oslo.utils spec_matcher does not support boolean see L237.\n\nYeah, I plan to document it in the Ironic documentation.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"267153b7a5b298fe363f44f38c9426ff8aa381a1","unresolved":false,"context_lines":[{"line_number":314,"context_line":"                      \u0027Current value: %(value)s\u0027) % {\u0027hint\u0027: hint,"},{"line_number":315,"context_line":"                                                     \u0027value\u0027: value})"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    return _append_operator_to_hints(root_device)"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_43d1f4fa","line":317,"updated":"2016-08-25 12:05:30.000000000","message":"You\u0027re going to hate me. Why not do the appending of the operator in this method as well. We already know here, to skip if it is bool. And for ints, it has already been parsed so you can see if there is an operator or not. Maybe not worth changing now; we can revisit it later. I\u0027m a bit concerned about how many times we\u0027re parsing the hints.","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"26f09b826542bdf96c4f577733d29e2f5db87147","unresolved":false,"context_lines":[{"line_number":314,"context_line":"                      \u0027Current value: %(value)s\u0027) % {\u0027hint\u0027: hint,"},{"line_number":315,"context_line":"                                                     \u0027value\u0027: value})"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    return _append_operator_to_hints(root_device)"}],"source_content_type":"text/x-python","patch_set":9,"id":"1ac06dbe_e6d2a933","line":317,"in_reply_to":"1ac06dbe_43d1f4fa","updated":"2016-08-25 13:27:03.000000000","message":"Right, I just separated and added it to another function to make this one shorter.\n\nMaybe keep it for now and change it later ? It\u0027s not a big deal afaict","commit_id":"a2359e51401d3b10d078e74821f6f37a5e9774e1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b8bdd558f2da4d41ed9daa3bf4169beee66a57c9","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    :param hint: The name of the hint. Used for logging."},{"line_number":189,"context_line":"    :param value: The hint value string."},{"line_number":190,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":191,"context_line":"    :returns: A dictionary containing:"},{"line_number":192,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"fa7ab95a_a9747efd","line":189,"updated":"2016-08-25 22:41:20.000000000","message":"so this isn\u0027t true, it may not be a string.","commit_id":"5d7da3737ef58cbc8c14e0c9b91239ecec2a291c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"4116863cd770ec5e5d8fb009a6f2c9cd04367439","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    :param hint: The name of the hint. Used for logging."},{"line_number":189,"context_line":"    :param value: The hint value string."},{"line_number":190,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":191,"context_line":"    :returns: A dictionary containing:"},{"line_number":192,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"fa7ab95a_30527f14","line":189,"in_reply_to":"fa7ab95a_a9747efd","updated":"2016-08-26 08:55:26.000000000","message":"Indeed, I will change it","commit_id":"5d7da3737ef58cbc8c14e0c9b91239ecec2a291c"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"7c684d26d0920660188ff6f3540d0e9f42d74201","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            \u0027op\u0027: op}"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"def _normalize_string_hint(hint, value):"},{"line_number":210,"context_line":"    \"\"\"Normalize a string type hint value."},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    A string-type hint contains one or more operators and one or more"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa7ab95a_099f2a04","line":209,"updated":"2016-08-25 23:09:08.000000000","message":"From Ruby\u0027s comment in patch set 9.  Maybe this should be:\n\n _normalize_string_value(hint, value)\n\nAs is looking at this function declaration I would think that \u0027hint\u0027 is what is being processed. Naming is hard. Since I don\u0027t really like my suggested name.\n\nAnother idea:\n _normalize_hint_expression(expression, name)","commit_id":"5d7da3737ef58cbc8c14e0c9b91239ecec2a291c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"4116863cd770ec5e5d8fb009a6f2c9cd04367439","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            \u0027op\u0027: op}"},{"line_number":207,"context_line":""},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"def _normalize_string_hint(hint, value):"},{"line_number":210,"context_line":"    \"\"\"Normalize a string type hint value."},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"    A string-type hint contains one or more operators and one or more"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa7ab95a_5020e39b","line":209,"in_reply_to":"fa7ab95a_099f2a04","updated":"2016-08-26 08:55:26.000000000","message":"Ops! True, yeah naming is quite difficult :-/\n\n+1 I will rename it","commit_id":"5d7da3737ef58cbc8c14e0c9b91239ecec2a291c"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"b8bdd558f2da4d41ed9daa3bf4169beee66a57c9","unresolved":false,"context_lines":[{"line_number":291,"context_line":"            root_device[hint] \u003d _normalize_string_hint(hint, value)"},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"        elif hint_type is int:"},{"line_number":294,"context_line":"            for v in _extract_hint_operator_and_values(hint, value)[\u0027values\u0027]:"},{"line_number":295,"context_line":"                try:"},{"line_number":296,"context_line":"                    integer \u003d int(v)"},{"line_number":297,"context_line":"                except ValueError:"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa7ab95a_4954d253","line":294,"updated":"2016-08-25 22:41:20.000000000","message":"I was actually wondering what would happen if value was None. Is that possible?","commit_id":"5d7da3737ef58cbc8c14e0c9b91239ecec2a291c"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"4116863cd770ec5e5d8fb009a6f2c9cd04367439","unresolved":false,"context_lines":[{"line_number":291,"context_line":"            root_device[hint] \u003d _normalize_string_hint(hint, value)"},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"        elif hint_type is int:"},{"line_number":294,"context_line":"            for v in _extract_hint_operator_and_values(hint, value)[\u0027values\u0027]:"},{"line_number":295,"context_line":"                try:"},{"line_number":296,"context_line":"                    integer \u003d int(v)"},{"line_number":297,"context_line":"                except ValueError:"}],"source_content_type":"text/x-python","patch_set":10,"id":"fa7ab95a_3030bf56","line":294,"in_reply_to":"fa7ab95a_4954d253","updated":"2016-08-26 08:55:26.000000000","message":"If it\u0027s None it will fail on the L296 when we try to convert it to int().\n\nBut looking at the IPA code, it would fail there before:\n\nhttps://github.com/openstack/ironic-python-agent/blob/master/ironic_python_agent/hardware.py#L158","commit_id":"5d7da3737ef58cbc8c14e0c9b91239ecec2a291c"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":179,"context_line":""},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"def _extract_hint_operator_and_values(hint_expression, hint_name):"},{"line_number":182,"context_line":"    \"\"\"Extract the operator and value(s) of a root device hint."},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    A root device hint could contain one or more values depending on the"},{"line_number":185,"context_line":"    operator. This method extracts the operator and value(s) and returns"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_d5b37798","line":182,"range":{"start_line":182,"start_character":58,"end_line":182,"end_character":62},"updated":"2016-08-29 20:19:39.000000000","message":"hint expression","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":179,"context_line":""},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"def _extract_hint_operator_and_values(hint_expression, hint_name):"},{"line_number":182,"context_line":"    \"\"\"Extract the operator and value(s) of a root device hint."},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    A root device hint could contain one or more values depending on the"},{"line_number":185,"context_line":"    operator. This method extracts the operator and value(s) and returns"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_9f43af6b","line":182,"range":{"start_line":182,"start_character":58,"end_line":182,"end_character":62},"in_reply_to":"fa7ab95a_d5b37798","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":181,"context_line":"def _extract_hint_operator_and_values(hint_expression, hint_name):"},{"line_number":182,"context_line":"    \"\"\"Extract the operator and value(s) of a root device hint."},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    A root device hint could contain one or more values depending on the"},{"line_number":185,"context_line":"    operator. This method extracts the operator and value(s) and returns"},{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_15b23f94","line":184,"range":{"start_line":184,"start_character":18,"end_line":184,"end_character":22},"updated":"2016-08-29 20:19:39.000000000","message":"hint expression","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":181,"context_line":"def _extract_hint_operator_and_values(hint_expression, hint_name):"},{"line_number":182,"context_line":"    \"\"\"Extract the operator and value(s) of a root device hint."},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"    A root device hint could contain one or more values depending on the"},{"line_number":185,"context_line":"    operator. This method extracts the operator and value(s) and returns"},{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_df0ff734","line":184,"range":{"start_line":184,"start_character":18,"end_line":184,"end_character":22},"in_reply_to":"fa7ab95a_15b23f94","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    :param hint_expression: The hint value string containing operators"},{"line_number":189,"context_line":"                            and values(s)."},{"line_number":190,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":191,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":192,"context_line":"    :returns: A dictionary containing:"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_d89c8e10","line":189,"updated":"2016-08-29 20:19:39.000000000","message":"Should there be a note that it can contain only values.\n\nLike:  size: 123","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":186,"context_line":"    a dictionary containing both."},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    :param hint_expression: The hint value string containing operators"},{"line_number":189,"context_line":"                            and values(s)."},{"line_number":190,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":191,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":192,"context_line":"    :returns: A dictionary containing:"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_512afb90","line":189,"in_reply_to":"fa7ab95a_d89c8e10","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":188,"context_line":"    :param hint_expression: The hint value string containing operators"},{"line_number":189,"context_line":"                            and values(s)."},{"line_number":190,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":191,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":192,"context_line":"    :returns: A dictionary containing:"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"        :op: The operator. An empty string in case of None."}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_75a54b45","line":191,"range":{"start_line":191,"start_character":36,"end_line":191,"end_character":41},"updated":"2016-08-29 20:19:39.000000000","message":"s/the hint value/hint_expression/","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":188,"context_line":"    :param hint_expression: The hint value string containing operators"},{"line_number":189,"context_line":"                            and values(s)."},{"line_number":190,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":191,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":192,"context_line":"    :returns: A dictionary containing:"},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"        :op: The operator. An empty string in case of None."}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_711b7f81","line":191,"range":{"start_line":191,"start_character":36,"end_line":191,"end_character":41},"in_reply_to":"fa7ab95a_75a54b45","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":196,"context_line":"    \"\"\""},{"line_number":197,"context_line":"    expression \u003d six.text_type(hint_expression).strip().lower()"},{"line_number":198,"context_line":"    if not expression:"},{"line_number":199,"context_line":"        raise ValueError(_(\u0027Root device hint \"%s\" value is empty\u0027) % hint_name)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(expression)"},{"line_number":202,"context_line":"    if len(ast) \u003c\u003d 1:"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_5556872a","line":199,"range":{"start_line":199,"start_character":50,"end_line":199,"end_character":55},"updated":"2016-08-29 20:19:39.000000000","message":"expression","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":196,"context_line":"    \"\"\""},{"line_number":197,"context_line":"    expression \u003d six.text_type(hint_expression).strip().lower()"},{"line_number":198,"context_line":"    if not expression:"},{"line_number":199,"context_line":"        raise ValueError(_(\u0027Root device hint \"%s\" value is empty\u0027) % hint_name)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(expression)"},{"line_number":202,"context_line":"    if len(ast) \u003c\u003d 1:"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_111f9308","line":199,"range":{"start_line":199,"start_character":50,"end_line":199,"end_character":55},"in_reply_to":"fa7ab95a_5556872a","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    if not expression:"},{"line_number":199,"context_line":"        raise ValueError(_(\u0027Root device hint \"%s\" value is empty\u0027) % hint_name)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(expression)"},{"line_number":202,"context_line":"    if len(ast) \u003c\u003d 1:"},{"line_number":203,"context_line":"        return {\u0027op\u0027: \u0027\u0027, \u0027values\u0027: [expression]}"},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_350bc32b","line":201,"updated":"2016-08-29 20:19:39.000000000","message":"Some comments here would be nice. As there doesn\u0027t seem to be any docs in oslo.utils about this.\n\nSo I don\u0027t know what parseString() returns.","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    if not expression:"},{"line_number":199,"context_line":"        raise ValueError(_(\u0027Root device hint \"%s\" value is empty\u0027) % hint_name)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(expression)"},{"line_number":202,"context_line":"    if len(ast) \u003c\u003d 1:"},{"line_number":203,"context_line":"        return {\u0027op\u0027: \u0027\u0027, \u0027values\u0027: [expression]}"},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_d100cb68","line":201,"in_reply_to":"fa7ab95a_350bc32b","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":199,"context_line":"        raise ValueError(_(\u0027Root device hint \"%s\" value is empty\u0027) % hint_name)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(expression)"},{"line_number":202,"context_line":"    if len(ast) \u003c\u003d 1:"},{"line_number":203,"context_line":"        return {\u0027op\u0027: \u0027\u0027, \u0027values\u0027: [expression]}"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"    op \u003d ast[0]"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_5804fe16","line":202,"updated":"2016-08-29 20:19:39.000000000","message":"# hint_expression had no operators","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":199,"context_line":"        raise ValueError(_(\u0027Root device hint \"%s\" value is empty\u0027) % hint_name)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(expression)"},{"line_number":202,"context_line":"    if len(ast) \u003c\u003d 1:"},{"line_number":203,"context_line":"        return {\u0027op\u0027: \u0027\u0027, \u0027values\u0027: [expression]}"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"    op \u003d ast[0]"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_d42279a2","line":202,"in_reply_to":"fa7ab95a_5804fe16","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":207,"context_line":"            \u0027op\u0027: op}"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"def _normalize_string_expression(hint_expression, hint_name):"},{"line_number":211,"context_line":"    \"\"\"Normalize a string type hint expression."},{"line_number":212,"context_line":""},{"line_number":213,"context_line":"    A string-type hint expression contains one or more operators and"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_94140df6","line":210,"updated":"2016-08-29 20:19:39.000000000","message":"Maybe:\n\n def _normalize_hint_expression(.....","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":207,"context_line":"            \u0027op\u0027: op}"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"def _normalize_string_expression(hint_expression, hint_name):"},{"line_number":211,"context_line":"    \"\"\"Normalize a string type hint expression."},{"line_number":212,"context_line":""},{"line_number":213,"context_line":"    A string-type hint expression contains one or more operators and"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_7477ed9f","line":210,"in_reply_to":"fa7ab95a_94140df6","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":216,"context_line":"    operators are not normalized. For example: the hint value of \"\u003cor\u003e"},{"line_number":217,"context_line":"    foo bar \u003cor\u003e bar\" will become \"\u003cor\u003e foo%20bar \u003cor\u003e bar\"."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"    :param hint_expression: The hint value string containing operators"},{"line_number":220,"context_line":"                            and values(s)."},{"line_number":221,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":222,"context_line":"    :raises: ValueError if the hint value is empty."}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_78462250","line":219,"range":{"start_line":219,"start_character":37,"end_line":219,"end_character":42},"updated":"2016-08-29 20:19:39.000000000","message":"expression\n\nor\n\nA string containing operators and value(s)","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":216,"context_line":"    operators are not normalized. For example: the hint value of \"\u003cor\u003e"},{"line_number":217,"context_line":"    foo bar \u003cor\u003e bar\" will become \"\u003cor\u003e foo%20bar \u003cor\u003e bar\"."},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"    :param hint_expression: The hint value string containing operators"},{"line_number":220,"context_line":"                            and values(s)."},{"line_number":221,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":222,"context_line":"    :raises: ValueError if the hint value is empty."}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_947ab186","line":219,"range":{"start_line":219,"start_character":37,"end_line":219,"end_character":42},"in_reply_to":"fa7ab95a_78462250","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":219,"context_line":"    :param hint_expression: The hint value string containing operators"},{"line_number":220,"context_line":"                            and values(s)."},{"line_number":221,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":222,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":223,"context_line":"    :returns: A normalized string."},{"line_number":224,"context_line":"    \"\"\""},{"line_number":225,"context_line":"    hdict \u003d _extract_hint_operator_and_values(hint_expression, hint_name)"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_18b19647","line":222,"range":{"start_line":222,"start_character":27,"end_line":222,"end_character":41},"updated":"2016-08-29 20:19:39.000000000","message":"s/the hint value/hint_expression/","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":219,"context_line":"    :param hint_expression: The hint value string containing operators"},{"line_number":220,"context_line":"                            and values(s)."},{"line_number":221,"context_line":"    :param hint_name: The name of the hint. Used for logging."},{"line_number":222,"context_line":"    :raises: ValueError if the hint value is empty."},{"line_number":223,"context_line":"    :returns: A normalized string."},{"line_number":224,"context_line":"    \"\"\""},{"line_number":225,"context_line":"    hdict \u003d _extract_hint_operator_and_values(hint_expression, hint_name)"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_5446694f","line":222,"range":{"start_line":222,"start_character":27,"end_line":222,"end_character":41},"in_reply_to":"fa7ab95a_18b19647","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":14760,"name":"John L. Villalovos","email":"openstack.org@sodarock.com","username":"jlvillal"},"change_message_id":"3b6d88b4caaae6b95d5e70365107ccb7b9b16c5c","unresolved":false,"context_lines":[{"line_number":288,"context_line":"            if not isinstance(expression, six.string_types):"},{"line_number":289,"context_line":"                raise ValueError("},{"line_number":290,"context_line":"                    _(\u0027Root device hint \"%(name)s\" is not a string value. \u0027"},{"line_number":291,"context_line":"                      \u0027Current value: %(expression)s\u0027) %"},{"line_number":292,"context_line":"                    {\u0027name\u0027: name, \u0027expression\u0027: expression})"},{"line_number":293,"context_line":"            root_device[name] \u003d _normalize_string_expression(expression, name)"},{"line_number":294,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_f8115205","line":291,"range":{"start_line":291,"start_character":31,"end_line":291,"end_character":36},"updated":"2016-08-29 20:19:39.000000000","message":"Maybe??\n\nhint expression","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f39b8b7bde4935f8d6e83be5148cd7e37a0809b7","unresolved":false,"context_lines":[{"line_number":288,"context_line":"            if not isinstance(expression, six.string_types):"},{"line_number":289,"context_line":"                raise ValueError("},{"line_number":290,"context_line":"                    _(\u0027Root device hint \"%(name)s\" is not a string value. \u0027"},{"line_number":291,"context_line":"                      \u0027Current value: %(expression)s\u0027) %"},{"line_number":292,"context_line":"                    {\u0027name\u0027: name, \u0027expression\u0027: expression})"},{"line_number":293,"context_line":"            root_device[name] \u003d _normalize_string_expression(expression, name)"},{"line_number":294,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa7ab95a_f46bfdb4","line":291,"range":{"start_line":291,"start_character":31,"end_line":291,"end_character":36},"in_reply_to":"fa7ab95a_f8115205","updated":"2016-08-30 09:21:48.000000000","message":"Done","commit_id":"9dbf836e1b56b7de0621c4837ac0831a03c477f8"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dec25bd8ce5d5612ad255b2acc5633121c3596e","unresolved":false,"context_lines":[{"line_number":199,"context_line":"        raise ValueError("},{"line_number":200,"context_line":"            _(\u0027Root device hint \"%s\" expression is empty\u0027) % hint_name)"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    # parseString() returns a list of tokens which the operator (if"},{"line_number":203,"context_line":"    # present) is always the first element."},{"line_number":204,"context_line":"    ast \u003d ROOT_DEVICE_HINTS_GRAMMAR.parseString(expression)"},{"line_number":205,"context_line":"    if len(ast) \u003c\u003d 1:"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa7ab95a_72527968","line":202,"range":{"start_line":202,"start_character":45,"end_line":202,"end_character":50},"updated":"2016-08-30 17:41:58.000000000","message":"s/which/where","commit_id":"dccd7b17895046d8b34ee9f450900b81a4a266d1"}]}
