)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a53b035eb495a9a71612bd744a1305a4f0a7b98","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Instead of a custom build parser and evaluator for"},{"line_number":10,"context_line":"specs use an actual formal parser and evaluation of"},{"line_number":11,"context_line":"that parse result instead, making that custom parser"},{"line_number":12,"context_line":"now be one that follows a more normal way of creating"},{"line_number":13,"context_line":"and evaluating a DSL."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Co-authored-by: Alexis Lee \u003clxsli@hpe.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"3aaa91ec_86cb69a3","line":12,"updated":"2016-07-01 01:37:26.000000000","message":"I question whether it is \u0027normal\u0027. I suspect most folks would not think of doing this formally! :)","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"f8105687c3d460d86f2b2d2b035b03cea65ab235","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Instead of a custom build parser and evaluator for"},{"line_number":10,"context_line":"specs use an actual formal parser and evaluation of"},{"line_number":11,"context_line":"that parse result instead, making that custom parser"},{"line_number":12,"context_line":"now be one that follows a more normal way of creating"},{"line_number":13,"context_line":"and evaluating a DSL."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Co-authored-by: Alexis Lee \u003clxsli@hpe.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"3aaa91ec_a79111f4","line":12,"in_reply_to":"3aaa91ec_2c2068b0","updated":"2016-07-01 17:01:50.000000000","message":"Sorry - I just read my last comment back, and it was much more aggressive than I\u0027d intended. I too am very tired today :-( You\u0027re probably right about the use of parser generators not being \"normal\", in the sense of \"ubiquitous\", but it\u0027s definitely best practice.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"940d49c56e0e0eac4ac77cc92f8d2eb87cdb1d1f","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Instead of a custom build parser and evaluator for"},{"line_number":10,"context_line":"specs use an actual formal parser and evaluation of"},{"line_number":11,"context_line":"that parse result instead, making that custom parser"},{"line_number":12,"context_line":"now be one that follows a more normal way of creating"},{"line_number":13,"context_line":"and evaluating a DSL."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Co-authored-by: Alexis Lee \u003clxsli@hpe.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"3aaa91ec_2c2068b0","line":12,"in_reply_to":"3aaa91ec_86cb69a3","updated":"2016-07-01 16:46:46.000000000","message":"I\u0027d expect anyone who\u0027s taken an undergraduate compilers course, or who has read \"The Art of Unix Programming\", to reach for a parser generator before hand-rolling a parser. But you\u0027re right, as an industry we don\u0027t make enough use of parser generators - and it\u0027s a major contributor to our epidemic of security flaws: http://langsec.org/papers/the-bugs-we-have-to-kill.pdf","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"213985f1bbcff656e49ab02ba303ccd26193f51c","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Instead of a custom build parser and evaluator for"},{"line_number":10,"context_line":"specs use an actual formal parser and evaluation of"},{"line_number":11,"context_line":"that parse result instead, making that custom parser"},{"line_number":12,"context_line":"now be one that follows a more normal way of creating"},{"line_number":13,"context_line":"and evaluating a DSL."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Co-authored-by: Alexis Lee \u003clxsli@hpe.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"1aa78d24_c1f792f3","line":12,"in_reply_to":"3aaa91ec_a79111f4","updated":"2016-07-05 14:08:03.000000000","message":"@Miles. No worries. I think \u0027best practice\u0027 would have been better than \u0027normal\u0027, and/or with your reasoning of why it is better to do it this way.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"bc279b5d82df0fcae857f769a0c800cbd242c511","unresolved":false,"context_lines":[{"line_number":11,"context_line":"that parse result instead, making that custom parser"},{"line_number":12,"context_line":"now be one that follows a more normal way of creating"},{"line_number":13,"context_line":"and evaluating a DSL."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Co-authored-by: Alexis Lee \u003clxsli@hpe.com\u003e"},{"line_number":16,"context_line":"Change-Id: I10f7dff8c83e5b6983515677e80cefa55881a92c"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":19,"id":"1aa78d24_336043cf","line":14,"updated":"2016-07-11 22:21:29.000000000","message":"I think this should mention something like \"Also removes \u003call-in\u003e operator, since it seems to be buggy. It will be added later when the issue has been resolved.\"","commit_id":"fb889b507ead686f22cde704999d62e31796a5e7"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"93d2be20132a4ac34039fa419c44cab81aec5c64","unresolved":false,"context_lines":[{"line_number":11,"context_line":"that parse result instead, making that custom parser"},{"line_number":12,"context_line":"now be one that follows a more normal way of creating"},{"line_number":13,"context_line":"and evaluating a DSL."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Co-authored-by: Alexis Lee \u003clxsli@hpe.com\u003e"},{"line_number":16,"context_line":"Change-Id: I10f7dff8c83e5b6983515677e80cefa55881a92c"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":19,"id":"1aa78d24_13fee7ad","line":14,"in_reply_to":"1aa78d24_336043cf","updated":"2016-07-11 22:25:55.000000000","message":"Hope you don\u0027t mind; I went ahead and updated it.","commit_id":"fb889b507ead686f22cde704999d62e31796a5e7"}],"oslo_utils/specs_matcher.py":[{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":17,"context_line":"import operator"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import pyparsing"},{"line_number":20,"context_line":"from pyparsing import Literal, Regex, Word  # noqa"},{"line_number":21,"context_line":"from pyparsing import OneOrMore, ZeroOrMore  # noqa"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_18e71612","line":20,"range":{"start_line":20,"start_character":46,"end_line":20,"end_character":50},"updated":"2016-05-10 12:59:24.000000000","message":"is the noqa just so you can import multiple things on one line? if so - just don\u0027t?","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":17,"context_line":"import operator"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import pyparsing"},{"line_number":20,"context_line":"from pyparsing import Literal, Regex, Word  # noqa"},{"line_number":21,"context_line":"from pyparsing import OneOrMore, ZeroOrMore  # noqa"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_0c5addf1","line":20,"range":{"start_line":20,"start_character":46,"end_line":20,"end_character":50},"in_reply_to":"dab17558_18e71612","updated":"2016-05-11 21:51:35.000000000","message":"Fair enough :-P","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"984f959cb38947ffd062a10dd43450ba3549c426","unresolved":false,"context_lines":[{"line_number":28,"context_line":"class Parser(object):"},{"line_number":29,"context_line":"    \"\"\"Specs matcher DSL parser (and evaluator).\"\"\""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    unary_op_methods \u003d {"},{"line_number":32,"context_line":"        # This one is special/odd,"},{"line_number":33,"context_line":"        # TODO(harlowja): fix it so that its not greater than or"},{"line_number":34,"context_line":"        # equal, see https://review.openstack.org/#/c/8089/"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_43c37438","line":31,"updated":"2016-05-10 11:19:56.000000000","message":"Don\u0027t you mean \"binary\"?","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":28,"context_line":"class Parser(object):"},{"line_number":29,"context_line":"    \"\"\"Specs matcher DSL parser (and evaluator).\"\"\""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    unary_op_methods \u003d {"},{"line_number":32,"context_line":"        # This one is special/odd,"},{"line_number":33,"context_line":"        # TODO(harlowja): fix it so that its not greater than or"},{"line_number":34,"context_line":"        # equal, see https://review.openstack.org/#/c/8089/"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_b891aa49","line":31,"in_reply_to":"dab17558_43c37438","updated":"2016-05-10 12:59:24.000000000","message":"from the perspective of pyparsing, which gets a string like \"\u003d 123\", \u0027\u003d\u0027 is a unary operator. I agree it\u0027s weird but blame the language designer.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":28,"context_line":"class Parser(object):"},{"line_number":29,"context_line":"    \"\"\"Specs matcher DSL parser (and evaluator).\"\"\""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    unary_op_methods \u003d {"},{"line_number":32,"context_line":"        # This one is special/odd,"},{"line_number":33,"context_line":"        # TODO(harlowja): fix it so that its not greater than or"},{"line_number":34,"context_line":"        # equal, see https://review.openstack.org/#/c/8089/"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ccd8d555","line":31,"in_reply_to":"dab17558_b891aa49","updated":"2016-05-11 21:51:35.000000000","message":"Ya, the spec has this weird syntax where its not \u0027X \u003d Y\u0027  but instead its \u0027\u003d Y\u0027 which is then later compared to some input value, so at parsing time its unary.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":66,"context_line":"            stack.append((\"unary-op\", toks[0]))"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        def push_nary_op(str, loc, toks):"},{"line_number":69,"context_line":"            stack.append((\"nary-op\", toks[0]))"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        eq \u003d Literal(\"\u003d\")"},{"line_number":72,"context_line":"        neq \u003d Literal(\"!\u003d\")"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_6e8f7875","line":69,"updated":"2016-05-10 12:59:24.000000000","message":"why only toks[0] please?","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"a836177f1defd8517f7a394ed69fede9e23a18b9","unresolved":false,"context_lines":[{"line_number":66,"context_line":"            stack.append((\"unary-op\", toks[0]))"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        def push_nary_op(str, loc, toks):"},{"line_number":69,"context_line":"            stack.append((\"nary-op\", toks[0]))"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        eq \u003d Literal(\"\u003d\")"},{"line_number":72,"context_line":"        neq \u003d Literal(\"!\u003d\")"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ca16194b","line":69,"in_reply_to":"dab17558_6e8f7875","updated":"2016-05-11 12:04:36.000000000","message":"toks is a list of the tokens matched. Since all these productions only match one token, toks will always be a singleton list. But I agree that this should be explained in a comment.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":66,"context_line":"            stack.append((\"unary-op\", toks[0]))"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        def push_nary_op(str, loc, toks):"},{"line_number":69,"context_line":"            stack.append((\"nary-op\", toks[0]))"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        eq \u003d Literal(\"\u003d\")"},{"line_number":72,"context_line":"        neq \u003d Literal(\"!\u003d\")"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ecbcb9dd","line":69,"in_reply_to":"dab17558_9b8745b4","updated":"2016-05-11 21:51:35.000000000","message":"The \u0027aes\u0027 and \u0027mmx\u0027 are atoms, so will be parsed and call the push_atom method instead.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"c83f81e288e7380982869968b91a3efdce5fec1b","unresolved":false,"context_lines":[{"line_number":66,"context_line":"            stack.append((\"unary-op\", toks[0]))"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"        def push_nary_op(str, loc, toks):"},{"line_number":69,"context_line":"            stack.append((\"nary-op\", toks[0]))"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        eq \u003d Literal(\"\u003d\")"},{"line_number":72,"context_line":"        neq \u003d Literal(\"!\u003d\")"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_9b8745b4","line":69,"in_reply_to":"dab17558_ca16194b","updated":"2016-05-11 12:37:18.000000000","message":"Oh I see, toks \u003d [\"\u003call-in\u003e\"]. That is confusing, I expected [\"\u003call-in\u003e\", \"aes\", \"mmx\"]. Thanks.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"984f959cb38947ffd062a10dd43450ba3549c426","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        nary_ops \u003d all_in_"},{"line_number":91,"context_line":"        nary_ops.setParseAction(push_nary_op)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        unary_ops \u003d ("},{"line_number":94,"context_line":"            # Order matters here (so that \u0027\u003d\u0027 doesn\u0027t match before \u0027\u003d\u003d\u0027)"},{"line_number":95,"context_line":"            eeq | eq |"},{"line_number":96,"context_line":"            neq | in_ |"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_23ee30b4","line":93,"updated":"2016-05-10 11:19:56.000000000","message":"Again, I think this should be \"binary\".","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"984f959cb38947ffd062a10dd43450ba3549c426","unresolved":false,"context_lines":[{"line_number":96,"context_line":"            neq | in_ |"},{"line_number":97,"context_line":"            gt_eq | lt_eq |"},{"line_number":98,"context_line":"            op_eq | op_neq |"},{"line_number":99,"context_line":"            # Order matters here (so that \u0027\u003e\u0027 doesn\u0027t match before \u0027\u003e\u003d\u0027)"},{"line_number":100,"context_line":"            op_lt_eq | op_lt |"},{"line_number":101,"context_line":"            op_gt_eq | op_gt)"},{"line_number":102,"context_line":"        unary_ops.setParseAction(push_unary_op)"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_434894cc","line":99,"updated":"2016-05-10 11:19:56.000000000","message":"Doesn\u0027t pyparsing prefer longer matches? How annoying.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":96,"context_line":"            neq | in_ |"},{"line_number":97,"context_line":"            gt_eq | lt_eq |"},{"line_number":98,"context_line":"            op_eq | op_neq |"},{"line_number":99,"context_line":"            # Order matters here (so that \u0027\u003e\u0027 doesn\u0027t match before \u0027\u003e\u003d\u0027)"},{"line_number":100,"context_line":"            op_lt_eq | op_lt |"},{"line_number":101,"context_line":"            op_gt_eq | op_gt)"},{"line_number":102,"context_line":"        unary_ops.setParseAction(push_unary_op)"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_6cd1e922","line":99,"in_reply_to":"dab17558_434894cc","updated":"2016-05-11 21:51:35.000000000","message":"I tried, it doesn\u0027t seem like it does :-/","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":101,"context_line":"            op_gt_eq | op_gt)"},{"line_number":102,"context_line":"        unary_ops.setParseAction(push_unary_op)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        # A atom is anything not an operator/keyword followed by anything"},{"line_number":105,"context_line":"        # but whitespace..."},{"line_number":106,"context_line":"        atom \u003d ~(unary_ops | nary_ops | or_) + Regex(r\"\\S+\")"},{"line_number":107,"context_line":"        atom.setParseAction(push_atom)"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_8e7bbc8b","line":104,"range":{"start_line":104,"start_character":10,"end_line":104,"end_character":16},"updated":"2016-05-10 12:59:24.000000000","message":"femtonit: an atom","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"4923ac1142cd0e16af302a7a13ed2e2f034fb9b1","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        bnf \u003d ("},{"line_number":110,"context_line":"            # Order matters here"},{"line_number":111,"context_line":"            (or_ + ((unary_ops + atom) | (nary_ops + OneOrMore(atom) | atom))"},{"line_number":112,"context_line":"                 + ZeroOrMore(or_ + ((unary_ops + atom)"},{"line_number":113,"context_line":"                                     | (nary_ops + OneOrMore(atom))"},{"line_number":114,"context_line":"                                     | atom))) |"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_db438dad","line":111,"updated":"2016-05-11 12:34:32.000000000","message":"You can reduce duplication and make the grammar easier to read by using several productions here:\n\n    unary \u003d unary_ops + atom\n    nary \u003d nary_ops + OneOrMore(atom)\n    alternative \u003d or_ + (unary | nary | atom)\n    disjunction \u003d OneOrMore(alternative)\n    bnf \u003d disjunction | nary | unary | atom","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        bnf \u003d ("},{"line_number":110,"context_line":"            # Order matters here"},{"line_number":111,"context_line":"            (or_ + ((unary_ops + atom) | (nary_ops + OneOrMore(atom) | atom))"},{"line_number":112,"context_line":"                 + ZeroOrMore(or_ + ((unary_ops + atom)"},{"line_number":113,"context_line":"                                     | (nary_ops + OneOrMore(atom))"},{"line_number":114,"context_line":"                                     | atom))) |"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_eca319b0","line":111,"in_reply_to":"dab17558_db438dad","updated":"2016-05-11 21:51:35.000000000","message":"Seems fine with me. I was going back on trying to find a good balance of readability vs not. I\u0027ll try yours.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        )"},{"line_number":119,"context_line":"        return bnf, stack"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def parse(self, spec):"},{"line_number":122,"context_line":"        bnf, stack \u003d self.make_grammar()"},{"line_number":123,"context_line":"        return (bnf, stack, bnf.parseString(spec))"},{"line_number":124,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ceb784f3","line":121,"updated":"2016-05-10 12:59:24.000000000","message":"method comment please, something like \"this validates the spec and returns a tuple of (bnf, queue, ast) where ast looks something like [\"or\", \"not\", \"AES\", \"or\", \"MMX\"]\"","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        bnf, stack \u003d self.make_grammar()"},{"line_number":123,"context_line":"        return (bnf, stack, bnf.parseString(spec))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _evaluate(self, value, stack):"},{"line_number":126,"context_line":"        kind, kind_value \u003d stack.popleft()"},{"line_number":127,"context_line":"        if kind \u003d\u003d \"nary-op\":"},{"line_number":128,"context_line":"            op \u003d self.nary_op_methods[kind_value]"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ce01446c","line":125,"updated":"2016-05-10 12:59:24.000000000","message":"method comment please, explaining the evaluation strategy - which seems to be pop items off the front of the /queue/, reducing to simpler items and with special support for \"\u003cor\u003e\". Or shift-reduce in parsing parlance, which not everyone will be familiar with.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":123,"context_line":"        return (bnf, stack, bnf.parseString(spec))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _evaluate(self, value, stack):"},{"line_number":126,"context_line":"        kind, kind_value \u003d stack.popleft()"},{"line_number":127,"context_line":"        if kind \u003d\u003d \"nary-op\":"},{"line_number":128,"context_line":"            op \u003d self.nary_op_methods[kind_value]"},{"line_number":129,"context_line":"            values \u003d set()"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ae4fa069","line":126,"updated":"2016-05-10 12:59:24.000000000","message":"um, if we\u0027re using popleft, we\u0027re using this as a queue not a stack! varname is confusing","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":123,"context_line":"        return (bnf, stack, bnf.parseString(spec))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _evaluate(self, value, stack):"},{"line_number":126,"context_line":"        kind, kind_value \u003d stack.popleft()"},{"line_number":127,"context_line":"        if kind \u003d\u003d \"nary-op\":"},{"line_number":128,"context_line":"            op \u003d self.nary_op_methods[kind_value]"},{"line_number":129,"context_line":"            values \u003d set()"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ac9e3160","line":126,"in_reply_to":"dab17558_ac7b28f4","updated":"2016-05-11 21:51:35.000000000","message":"Hmmm, expr seems nice.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"60206a9d8822bdcd05f879ecef3989a5d24342ea","unresolved":false,"context_lines":[{"line_number":123,"context_line":"        return (bnf, stack, bnf.parseString(spec))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _evaluate(self, value, stack):"},{"line_number":126,"context_line":"        kind, kind_value \u003d stack.popleft()"},{"line_number":127,"context_line":"        if kind \u003d\u003d \"nary-op\":"},{"line_number":128,"context_line":"            op \u003d self.nary_op_methods[kind_value]"},{"line_number":129,"context_line":"            values \u003d set()"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_d18609da","line":126,"in_reply_to":"dab17558_ae4fa069","updated":"2016-05-10 13:27:54.000000000","message":"We also appendleft(), so I think it is a stack.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"2185cf7c060d6f485f42b8c32dc5bd02639b879a","unresolved":false,"context_lines":[{"line_number":123,"context_line":"        return (bnf, stack, bnf.parseString(spec))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _evaluate(self, value, stack):"},{"line_number":126,"context_line":"        kind, kind_value \u003d stack.popleft()"},{"line_number":127,"context_line":"        if kind \u003d\u003d \"nary-op\":"},{"line_number":128,"context_line":"            op \u003d self.nary_op_methods[kind_value]"},{"line_number":129,"context_line":"            values \u003d set()"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ac7b28f4","line":126,"in_reply_to":"dab17558_d18609da","updated":"2016-05-10 13:35:40.000000000","message":"well... items are appended to the right initially, then we stack-reduce to the right. So it\u0027s probably clearest to call it a deque, which is what it actually is, or something semantically meaningful like \"expr\".","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _evaluate(self, value, stack):"},{"line_number":126,"context_line":"        kind, kind_value \u003d stack.popleft()"},{"line_number":127,"context_line":"        if kind \u003d\u003d \"nary-op\":"},{"line_number":128,"context_line":"            op \u003d self.nary_op_methods[kind_value]"},{"line_number":129,"context_line":"            values \u003d set()"},{"line_number":130,"context_line":"            while stack:"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_9b1940da","line":127,"updated":"2016-05-10 12:59:24.000000000","message":"can we break this into _eval_\u003ckind\u003e methods please? except _eval_atom because that\u0027d be trivial","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def _evaluate(self, value, stack):"},{"line_number":126,"context_line":"        kind, kind_value \u003d stack.popleft()"},{"line_number":127,"context_line":"        if kind \u003d\u003d \"nary-op\":"},{"line_number":128,"context_line":"            op \u003d self.nary_op_methods[kind_value]"},{"line_number":129,"context_line":"            values \u003d set()"},{"line_number":130,"context_line":"            while stack:"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_ec8af919","line":127,"in_reply_to":"dab17558_9b1940da","updated":"2016-05-11 21:51:35.000000000","message":"Sure.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"984f959cb38947ffd062a10dd43450ba3549c426","unresolved":false,"context_lines":[{"line_number":135,"context_line":"                    stack.appendleft((next_kind, next_kind_value))"},{"line_number":136,"context_line":"                    break"},{"line_number":137,"context_line":"                elif next_kind !\u003d \u0027atom\u0027:"},{"line_number":138,"context_line":"                    raise EvaluationError(\"Nary op encountered with\""},{"line_number":139,"context_line":"                                          \" subsequent non-atom value\")"},{"line_number":140,"context_line":"                else:"},{"line_number":141,"context_line":"                    values.add(next_kind_value)"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_23f8f048","line":138,"updated":"2016-05-10 11:19:56.000000000","message":"\"n-ary\" is clearer, I think.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":141,"context_line":"                    values.add(next_kind_value)"},{"line_number":142,"context_line":"            if not values:"},{"line_number":143,"context_line":"                raise EvaluationError(\"Nary op encountered with no\""},{"line_number":144,"context_line":"                                      \" subsequent atom value(s)\")"},{"line_number":145,"context_line":"            if not stack:"},{"line_number":146,"context_line":"                return op(value, values)"},{"line_number":147,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_bb7b64f4","line":144,"updated":"2016-05-10 12:59:24.000000000","message":"this should be impossible if the BNF is correct, no? Same for most of the others; no point validating twice","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":141,"context_line":"                    values.add(next_kind_value)"},{"line_number":142,"context_line":"            if not values:"},{"line_number":143,"context_line":"                raise EvaluationError(\"Nary op encountered with no\""},{"line_number":144,"context_line":"                                      \" subsequent atom value(s)\")"},{"line_number":145,"context_line":"            if not stack:"},{"line_number":146,"context_line":"                return op(value, values)"},{"line_number":147,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_cc8d7532","line":144,"in_reply_to":"dab17558_bb7b64f4","updated":"2016-05-11 21:51:35.000000000","message":"Yes it should be impossible, but I\u0027m being all defensive :-P\n\nI\u0027ll remove since its probably less confusing with it gone.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":142,"context_line":"            if not values:"},{"line_number":143,"context_line":"                raise EvaluationError(\"Nary op encountered with no\""},{"line_number":144,"context_line":"                                      \" subsequent atom value(s)\")"},{"line_number":145,"context_line":"            if not stack:"},{"line_number":146,"context_line":"                return op(value, values)"},{"line_number":147,"context_line":"            else:"},{"line_number":148,"context_line":"                return any([op(value, values),"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_9b67804c","line":145,"updated":"2016-05-10 12:59:24.000000000","message":"positive condition first please, here and in other cases","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"984f959cb38947ffd062a10dd43450ba3549c426","unresolved":false,"context_lines":[{"line_number":166,"context_line":"            # evaluation)."},{"line_number":167,"context_line":"            stacks \u003d []"},{"line_number":168,"context_line":"            cur_stack \u003d collections.deque()"},{"line_number":169,"context_line":"            for kind, val in stack:"},{"line_number":170,"context_line":"                if kind \u003d\u003d \"or\":"},{"line_number":171,"context_line":"                    stacks.append(cur_stack)"},{"line_number":172,"context_line":"                    cur_stack \u003d collections.deque()"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_c310045c","line":169,"updated":"2016-05-10 11:19:56.000000000","message":"You\u0027re shadowing the outer \"kind\" variable here, which I think makes the logic less clear.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":166,"context_line":"            # evaluation)."},{"line_number":167,"context_line":"            stacks \u003d []"},{"line_number":168,"context_line":"            cur_stack \u003d collections.deque()"},{"line_number":169,"context_line":"            for kind, val in stack:"},{"line_number":170,"context_line":"                if kind \u003d\u003d \"or\":"},{"line_number":171,"context_line":"                    stacks.append(cur_stack)"},{"line_number":172,"context_line":"                    cur_stack \u003d collections.deque()"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_2c81a1fb","line":169,"in_reply_to":"dab17558_c310045c","updated":"2016-05-11 21:51:35.000000000","message":"Crap, thought I fixed that.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"b9d05ab4170fdfb61ae312a3b5bb4159df391c38","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                else:"},{"line_number":174,"context_line":"                    cur_stack.append((kind, val))"},{"line_number":175,"context_line":"            if cur_stack:"},{"line_number":176,"context_line":"                stacks.append(cur_stack)"},{"line_number":177,"context_line":"            return any(self._evaluate(value, stack) for stack in stacks)"},{"line_number":178,"context_line":"        else:"},{"line_number":179,"context_line":"            raise EvaluationError(\"Unknown op \u0027%s\u0027 encountered\""}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_dbb9087b","line":176,"updated":"2016-05-10 12:59:24.000000000","message":"may as well pre-add rather than post-add, we can assume there\u0027s at least one case","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c9841fb951fbe32aa7e2788a8c65dd78ab4aa330","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                else:"},{"line_number":174,"context_line":"                    cur_stack.append((kind, val))"},{"line_number":175,"context_line":"            if cur_stack:"},{"line_number":176,"context_line":"                stacks.append(cur_stack)"},{"line_number":177,"context_line":"            return any(self._evaluate(value, stack) for stack in stacks)"},{"line_number":178,"context_line":"        else:"},{"line_number":179,"context_line":"            raise EvaluationError(\"Unknown op \u0027%s\u0027 encountered\""}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_0c849d08","line":176,"in_reply_to":"dab17558_dbb9087b","updated":"2016-05-11 21:51:35.000000000","message":"Good point.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"984f959cb38947ffd062a10dd43450ba3549c426","unresolved":false,"context_lines":[{"line_number":184,"context_line":"            _bnf, stack, _results \u003d self.parse(spec)"},{"line_number":185,"context_line":"        except pyparsing.ParseException:"},{"line_number":186,"context_line":"            # Some unknown spec provided, by default just do a direct"},{"line_number":187,"context_line":"            # comparsion to the value to determine spec -\u003e value equality..."},{"line_number":188,"context_line":"            if on_unknown is not None:"},{"line_number":189,"context_line":"                return on_unknown(value, spec)"},{"line_number":190,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"dab17558_1ee38334","line":187,"updated":"2016-05-10 11:19:56.000000000","message":"Typo: \"comparison\"","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":2813,"name":"Mehdi Abaakouk","email":"sileht@sileht.net","username":"sileht"},"change_message_id":"e191d5a862f3d6d1be13b7f4c01a2a79c1e834de","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        # This one is special/odd,"},{"line_number":34,"context_line":"        # TODO(harlowja): fix it so that its not greater than or"},{"line_number":35,"context_line":"        # equal, see https://review.openstack.org/#/c/8089/"},{"line_number":36,"context_line":"        \u0027\u003d\u0027: lambda x, y: float(x) \u003e\u003d float(y),"},{"line_number":37,"context_line":"        \u0027\u003cin\u003e\u0027: lambda x, y: y in x,"},{"line_number":38,"context_line":"        \u0027\u003d\u003d\u0027: lambda x, y: float(x) \u003d\u003d float(y),"},{"line_number":39,"context_line":"        \u0027!\u003d\u0027: lambda x, y: float(x) !\u003d float(y),"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_f155a9f9","line":36,"updated":"2016-05-12 06:08:54.000000000","message":"rofl","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a3a482e83dc4c3a618644818369a19faa70bb0d9","unresolved":false,"context_lines":[{"line_number":33,"context_line":"        # This one is special/odd,"},{"line_number":34,"context_line":"        # TODO(harlowja): fix it so that its not greater than or"},{"line_number":35,"context_line":"        # equal, see https://review.openstack.org/#/c/8089/"},{"line_number":36,"context_line":"        \u0027\u003d\u0027: lambda x, y: float(x) \u003e\u003d float(y),"},{"line_number":37,"context_line":"        \u0027\u003cin\u003e\u0027: lambda x, y: y in x,"},{"line_number":38,"context_line":"        \u0027\u003d\u003d\u0027: lambda x, y: float(x) \u003d\u003d float(y),"},{"line_number":39,"context_line":"        \u0027!\u003d\u0027: lambda x, y: float(x) !\u003d float(y),"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_52d0d7c9","line":36,"in_reply_to":"dab17558_f155a9f9","updated":"2016-05-12 20:18:46.000000000","message":"ya....","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"6bcb50acfd040f0fcdd060c1b3b592e2f2114872","unresolved":false,"context_lines":[{"line_number":111,"context_line":"        nary \u003d nary_ops + OneOrMore(atom)"},{"line_number":112,"context_line":"        alternative \u003d or_ + (unary | nary | atom)"},{"line_number":113,"context_line":"        disjunction \u003d OneOrMore(alternative)"},{"line_number":114,"context_line":"        bnf \u003d disjunction | nary | unary | atom"},{"line_number":115,"context_line":"        return bnf, expr_deque"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def parse(self, spec):"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_65ee0eb6","line":114,"range":{"start_line":114,"start_character":28,"end_line":114,"end_character":47},"updated":"2016-05-12 08:54:40.000000000","message":"this seems simpler to me:\n\n  term \u003d nary | unary | atom\n  bnf \u003d OneOrMore(or_ + term) | term","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"149d6791adcd21ddf051aec016d2abff16d8d004","unresolved":false,"context_lines":[{"line_number":111,"context_line":"        nary \u003d nary_ops + OneOrMore(atom)"},{"line_number":112,"context_line":"        alternative \u003d or_ + (unary | nary | atom)"},{"line_number":113,"context_line":"        disjunction \u003d OneOrMore(alternative)"},{"line_number":114,"context_line":"        bnf \u003d disjunction | nary | unary | atom"},{"line_number":115,"context_line":"        return bnf, expr_deque"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def parse(self, spec):"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_e277869d","line":114,"in_reply_to":"dab17558_65ee0eb6","updated":"2016-05-12 12:52:05.000000000","message":"Yep, agreed!","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"6bcb50acfd040f0fcdd060c1b3b592e2f2114872","unresolved":false,"context_lines":[{"line_number":114,"context_line":"        bnf \u003d disjunction | nary | unary | atom"},{"line_number":115,"context_line":"        return bnf, expr_deque"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def parse(self, spec):"},{"line_number":118,"context_line":"        bnf, expr_deque \u003d self.make_grammar()"},{"line_number":119,"context_line":"        return (bnf, expr_deque, bnf.parseString(spec))"},{"line_number":120,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_25224602","line":117,"updated":"2016-05-12 08:54:40.000000000","message":"no comment?","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a3a482e83dc4c3a618644818369a19faa70bb0d9","unresolved":false,"context_lines":[{"line_number":114,"context_line":"        bnf \u003d disjunction | nary | unary | atom"},{"line_number":115,"context_line":"        return bnf, expr_deque"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def parse(self, spec):"},{"line_number":118,"context_line":"        bnf, expr_deque \u003d self.make_grammar()"},{"line_number":119,"context_line":"        return (bnf, expr_deque, bnf.parseString(spec))"},{"line_number":120,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_8f6e8894","line":117,"in_reply_to":"dab17558_25224602","updated":"2016-05-12 20:18:46.000000000","message":"parses things, ha, will add :-P","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"8a32057a6fc76c0d01df03d4a2e9ddab5b8daf7d","unresolved":false,"context_lines":[{"line_number":114,"context_line":"        bnf \u003d disjunction | nary | unary | atom"},{"line_number":115,"context_line":"        return bnf, expr_deque"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def parse(self, spec):"},{"line_number":118,"context_line":"        bnf, expr_deque \u003d self.make_grammar()"},{"line_number":119,"context_line":"        return (bnf, expr_deque, bnf.parseString(spec))"},{"line_number":120,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_f8bb8573","line":117,"in_reply_to":"dab17558_8f6e8894","updated":"2016-05-13 09:54:04.000000000","message":"Possibly give some examples of valid strings in the language, or a reference to where the language is documented?","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"6bcb50acfd040f0fcdd060c1b3b592e2f2114872","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        return (bnf, expr_deque, bnf.parseString(spec))"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def _evaluate_nary_op(self, op_value, cmp_value, expr_deque):"},{"line_number":122,"context_line":"        values \u003d set()"},{"line_number":123,"context_line":"        while expr_deque:"},{"line_number":124,"context_line":"            next_kind, next_kind_value \u003d expr_deque.popleft()"},{"line_number":125,"context_line":"            if next_kind \u003d\u003d \"unary_op\" or next_kind \u003d\u003d \"or\":"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_e012ec08","line":122,"range":{"start_line":122,"start_character":17,"end_line":122,"end_character":22},"updated":"2016-05-12 08:54:40.000000000","message":"this is fine for all-in but not necessarily for all n-ary ops, it\u0027d be better to let all-in set() its args","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a3a482e83dc4c3a618644818369a19faa70bb0d9","unresolved":false,"context_lines":[{"line_number":119,"context_line":"        return (bnf, expr_deque, bnf.parseString(spec))"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def _evaluate_nary_op(self, op_value, cmp_value, expr_deque):"},{"line_number":122,"context_line":"        values \u003d set()"},{"line_number":123,"context_line":"        while expr_deque:"},{"line_number":124,"context_line":"            next_kind, next_kind_value \u003d expr_deque.popleft()"},{"line_number":125,"context_line":"            if next_kind \u003d\u003d \"unary_op\" or next_kind \u003d\u003d \"or\":"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_0f6298ad","line":122,"range":{"start_line":122,"start_character":17,"end_line":122,"end_character":22},"in_reply_to":"dab17558_e012ec08","updated":"2016-05-12 20:18:46.000000000","message":"okie.","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"149d6791adcd21ddf051aec016d2abff16d8d004","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        values \u003d set()"},{"line_number":123,"context_line":"        while expr_deque:"},{"line_number":124,"context_line":"            next_kind, next_kind_value \u003d expr_deque.popleft()"},{"line_number":125,"context_line":"            if next_kind \u003d\u003d \"unary_op\" or next_kind \u003d\u003d \"or\":"},{"line_number":126,"context_line":"                # Put it back on, and stop as we have reached"},{"line_number":127,"context_line":"                # a consumption boundary."},{"line_number":128,"context_line":"                expr_deque.appendleft((next_kind, next_kind_value))"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_22806e46","line":125,"updated":"2016-05-12 12:52:05.000000000","message":"This definitely feels like something the parser should be doing :-( Is next_kind \u003d\u003d \"unary_op\" even possible?","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"4dfc063e1347dd94542e3bd0d35b3165af440a19","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        values \u003d set()"},{"line_number":123,"context_line":"        while expr_deque:"},{"line_number":124,"context_line":"            next_kind, next_kind_value \u003d expr_deque.popleft()"},{"line_number":125,"context_line":"            if next_kind \u003d\u003d \"unary_op\" or next_kind \u003d\u003d \"or\":"},{"line_number":126,"context_line":"                # Put it back on, and stop as we have reached"},{"line_number":127,"context_line":"                # a consumption boundary."},{"line_number":128,"context_line":"                expr_deque.appendleft((next_kind, next_kind_value))"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_4f02e070","line":125,"in_reply_to":"dab17558_22806e46","updated":"2016-05-12 20:23:12.000000000","message":"Ya, I think some of this isn\u0027t needed, fixing that.","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"6bcb50acfd040f0fcdd060c1b3b592e2f2114872","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        op \u003d self.nary_op_methods[op_value]"},{"line_number":133,"context_line":"        if expr_deque:"},{"line_number":134,"context_line":"            return any([op(cmp_value, values),"},{"line_number":135,"context_line":"                        self._evaluate(cmp_value, expr_deque)])"},{"line_number":136,"context_line":"        else:"},{"line_number":137,"context_line":"            return op(cmp_value, values)"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_40a2d89b","line":135,"updated":"2016-05-12 08:54:40.000000000","message":"what\u0027s going on here please? It looks like you\u0027re accepting \"\u003call-in\u003e 1 2 \u003cin\u003e 1\" which I don\u0027t think the adhoc processor did. The any on L162 should take care of \u003cor\u003es.","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"4dfc063e1347dd94542e3bd0d35b3165af440a19","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        op \u003d self.nary_op_methods[op_value]"},{"line_number":133,"context_line":"        if expr_deque:"},{"line_number":134,"context_line":"            return any([op(cmp_value, values),"},{"line_number":135,"context_line":"                        self._evaluate(cmp_value, expr_deque)])"},{"line_number":136,"context_line":"        else:"},{"line_number":137,"context_line":"            return op(cmp_value, values)"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_2f031c78","line":135,"in_reply_to":"dab17558_40a2d89b","updated":"2016-05-12 20:23:12.000000000","message":"Ah, ya good point.","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"6bcb50acfd040f0fcdd060c1b3b592e2f2114872","unresolved":false,"context_lines":[{"line_number":166,"context_line":"        kind, kind_value \u003d expr_deque.popleft()"},{"line_number":167,"context_line":"        if kind \u003d\u003d \"atom\":"},{"line_number":168,"context_line":"            return cmp_value \u003d\u003d kind_value"},{"line_number":169,"context_line":"        else:"},{"line_number":170,"context_line":"            try:"},{"line_number":171,"context_line":"                handler \u003d getattr(self, \"_evaluate_%s\" % kind)"},{"line_number":172,"context_line":"            except AttributeError:"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_45766ad9","line":169,"updated":"2016-05-12 08:54:40.000000000","message":"don\u0027t need else as the first case returns","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"6bcb50acfd040f0fcdd060c1b3b592e2f2114872","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                raise EvaluationError(\"Unknown op \u0027%s\u0027 encountered\""},{"line_number":174,"context_line":"                                      \" with value %s\" % (kind, kind_value))"},{"line_number":175,"context_line":"            else:"},{"line_number":176,"context_line":"                return handler(kind_value, cmp_value, expr_deque)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def evaluate(self, cmp_value, spec, on_unknown\u003doperator.eq):"},{"line_number":179,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_200fd42f","line":176,"updated":"2016-05-12 08:54:40.000000000","message":"could this be line 172? why the else?","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a3a482e83dc4c3a618644818369a19faa70bb0d9","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                raise EvaluationError(\"Unknown op \u0027%s\u0027 encountered\""},{"line_number":174,"context_line":"                                      \" with value %s\" % (kind, kind_value))"},{"line_number":175,"context_line":"            else:"},{"line_number":176,"context_line":"                return handler(kind_value, cmp_value, expr_deque)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def evaluate(self, cmp_value, spec, on_unknown\u003doperator.eq):"},{"line_number":179,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_cfc41061","line":176,"in_reply_to":"dab17558_200fd42f","updated":"2016-05-12 20:18:46.000000000","message":"Soooo reduction of except clause is IMHO a virtue.\n\nI could put at 172 but then that except caluse would be handling attribute errors that the handler code itself could throw; which is not the intention here, the intention of the try, except was only to handle attribute errors missing on the self object, not those that get raised by the handler method itself.","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"05ca753aacce9da6df7eb5f4618f4638aa3713b2","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                raise EvaluationError(\"Unknown op \u0027%s\u0027 encountered\""},{"line_number":174,"context_line":"                                      \" with value %s\" % (kind, kind_value))"},{"line_number":175,"context_line":"            else:"},{"line_number":176,"context_line":"                return handler(kind_value, cmp_value, expr_deque)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"    def evaluate(self, cmp_value, spec, on_unknown\u003doperator.eq):"},{"line_number":179,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":11,"id":"dab17558_cf1c10c4","line":176,"in_reply_to":"dab17558_cfc41061","updated":"2016-05-12 20:23:46.000000000","message":"Probably meant reduction of try/except clause is IMHO a virtue.","commit_id":"28630fea6ddef9df7b55bfdd037e40e1fb4b80f9"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"5ee8815629cbdd20c6aab1a10ef16587d841de42","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    \"\"\"Raised when unknown/unexpected evaluation error happens.\"\"\""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"#: Exception raised when parsing fails."},{"line_number":29,"context_line":"ParseException \u003d pyparsing.ParseException"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class ParserEvaluator(object):"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_23b31eeb","line":29,"updated":"2016-05-13 10:04:46.000000000","message":"why not just import this?","commit_id":"3ec2717a27edf30b525752937e829aafb206399a"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"88a7463be26d7ac889e7d379b4df99524024803c","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        gt_eq \u003d Literal(\"\u003e\u003d\")"},{"line_number":80,"context_line":"        lt_eq \u003d Literal(\"\u003c\u003d\")"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        op_eq \u003d Literal(\"s\u003d\u003d\")"},{"line_number":83,"context_line":"        op_neq \u003d Literal(\"s!\u003d\")"},{"line_number":84,"context_line":"        op_lt \u003d Literal(\"s\u003c\")"},{"line_number":85,"context_line":"        op_lt_eq \u003d Literal(\"s\u003c\u003d\")"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_35cd13b8","line":82,"updated":"2016-05-13 11:03:54.000000000","message":"Is \"s\u003d\u003d\" string equality? If so, I think str_eq would be a clearer name. Though since you don\u0027t use these variables after you\u0027ve declared unary_ops, you could just inline the usages and eliminate them.","commit_id":"3ec2717a27edf30b525752937e829aafb206399a"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"88a7463be26d7ac889e7d379b4df99524024803c","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        nary \u003d nary_ops + OneOrMore(atom)"},{"line_number":116,"context_line":"        term \u003d nary | unary | atom"},{"line_number":117,"context_line":"        bnf \u003d OneOrMore(or_ + term) | term"},{"line_number":118,"context_line":"        return bnf, expr_deque"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def parse(self, spec):"},{"line_number":121,"context_line":"        \"\"\"Parses a spec into a (grammar applied, expression deque) tuple."}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_95f95fcb","line":118,"updated":"2016-05-13 11:03:54.000000000","message":"I don\u0027t like the variable name \"bnf\" - it\u0027s standard practice to name your grammar productions after which part of the language they match.","commit_id":"3ec2717a27edf30b525752937e829aafb206399a"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"5ee8815629cbdd20c6aab1a10ef16587d841de42","unresolved":false,"context_lines":[{"line_number":137,"context_line":"        next_kind, next_kind_value \u003d expr_deque.popleft()"},{"line_number":138,"context_line":"        if expr_deque:"},{"line_number":139,"context_line":"            return any([op(cmp_value, next_kind_value),"},{"line_number":140,"context_line":"                        self._evaluate(cmp_value, expr_deque)])"},{"line_number":141,"context_line":"        return op(cmp_value, next_kind_value)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    def _evaluate_or(self, op_value, cmp_value, expr_deque):"}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_03dd3a14","line":140,"updated":"2016-05-13 10:04:46.000000000","message":"I think this also oversteps the original grammar; you\u0027re allowing implicit disjunction","commit_id":"3ec2717a27edf30b525752937e829aafb206399a"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"88a7463be26d7ac889e7d379b4df99524024803c","unresolved":false,"context_lines":[{"line_number":140,"context_line":"                        self._evaluate(cmp_value, expr_deque)])"},{"line_number":141,"context_line":"        return op(cmp_value, next_kind_value)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    def _evaluate_or(self, op_value, cmp_value, expr_deque):"},{"line_number":144,"context_line":"        # Break apart the expr into many smaller expr(s)"},{"line_number":145,"context_line":"        # and evaluate each one on its own (as if it was its one"},{"line_number":146,"context_line":"        # evaluation)."}],"source_content_type":"text/x-python","patch_set":13,"id":"dab17558_b5010309","line":143,"updated":"2016-05-13 11:03:54.000000000","message":"It turns out we\u0027d misunderstood the original grammar - \"\u003cor\u003e\" only allows for strict equality (eg \"\u003cor\u003e 5 \u003cor\u003e 6 \u003cor\u003e 7\"), not for more complex matchers (so \"\u003cor\u003e \u003e\u003d 5 \u003cor\u003e \u003c\u003d 1\" is invalid).","commit_id":"3ec2717a27edf30b525752937e829aafb206399a"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"49455e7fd4c47054a9723bc336b790240c799776","unresolved":false,"context_lines":[{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def parse_disjunction(s, l, t):"},{"line_number":51,"context_line":"        # Even-numbered tokens will be \"\u003cor\u003e\" - discard them"},{"line_number":52,"context_line":"        return [\"\u003cor\u003e\"] + t[1::2]"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    eq \u003d Literal(\"\u003d\")"},{"line_number":55,"context_line":"    neq \u003d Literal(\"!\u003d\")"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_35f78a5a","line":52,"updated":"2016-05-16 10:10:17.000000000","message":"nit could we define this closer to (right above) disjunction.setParseAction? Maybe even as a lambda?","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"0796111c5203a9f6f9445e32b396ffc12f317ded","unresolved":false,"context_lines":[{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def parse_disjunction(s, l, t):"},{"line_number":51,"context_line":"        # Even-numbered tokens will be \"\u003cor\u003e\" - discard them"},{"line_number":52,"context_line":"        return [\"\u003cor\u003e\"] + t[1::2]"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    eq \u003d Literal(\"\u003d\")"},{"line_number":55,"context_line":"    neq \u003d Literal(\"!\u003d\")"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_c3791695","line":52,"in_reply_to":"dab17558_35f78a5a","updated":"2016-05-16 14:21:55.000000000","message":"+1 - it\u0027s trivial now.","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"0796111c5203a9f6f9445e32b396ffc12f317ded","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        # Even-numbered tokens will be \"\u003cor\u003e\" - discard them"},{"line_number":52,"context_line":"        return [\"\u003cor\u003e\"] + t[1::2]"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    eq \u003d Literal(\"\u003d\")"},{"line_number":55,"context_line":"    neq \u003d Literal(\"!\u003d\")"},{"line_number":56,"context_line":"    eeq \u003d Literal(\"\u003d\u003d\")"},{"line_number":57,"context_line":"    gt_eq \u003d Literal(\"\u003e\u003d\")"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_a3ee92ea","line":54,"updated":"2016-05-16 14:21:55.000000000","message":"I\u0027d move the grammar definition out of the body of `match`, so you can see the parse/eval logic at a glance.","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"49455e7fd4c47054a9723bc336b790240c799776","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    op_lt \u003d Literal(\"s\u003c\")"},{"line_number":63,"context_line":"    op_lt_eq \u003d Literal(\"s\u003c\u003d\")"},{"line_number":64,"context_line":"    op_gt \u003d Literal(\"s\u003e\")"},{"line_number":65,"context_line":"    op_gt_eq \u003d Literal(\"s\u003e\u003d\")"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    in_ \u003d Literal(\"\u003cin\u003e\")"},{"line_number":68,"context_line":"    all_in_ \u003d Literal(\"\u003call-in\u003e\")"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_d8a2b3fb","line":65,"updated":"2016-05-16 10:10:17.000000000","message":"can we inline some of these? I think most of them are only used once. OTOH on L106 we should re-use these.","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"49455e7fd4c47054a9723bc336b790240c799776","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        op_gt_eq | op_gt)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    # A atom is anything not an operator/keyword followed by anything"},{"line_number":85,"context_line":"    # but whitespace..."},{"line_number":86,"context_line":"    atom \u003d ~(unary_ops | nary_ops | or_) + Regex(r\"\\S+\")"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    unary \u003d unary_ops + atom"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_d5cefe2b","line":85,"updated":"2016-05-16 10:10:17.000000000","message":"Does \"negative lookahead for operator/keyword followed by non-whitespace\" capture the mechanism better? Took me a little while to figure this out (and maybe I got it wrong!)","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"0796111c5203a9f6f9445e32b396ffc12f317ded","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        op_gt_eq | op_gt)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    # A atom is anything not an operator/keyword followed by anything"},{"line_number":85,"context_line":"    # but whitespace..."},{"line_number":86,"context_line":"    atom \u003d ~(unary_ops | nary_ops | or_) + Regex(r\"\\S+\")"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    unary \u003d unary_ops + atom"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_23f0e2fc","line":85,"in_reply_to":"dab17558_d5cefe2b","updated":"2016-05-16 14:21:55.000000000","message":"I\u0027m not sure you even need \"non-whitespace\" - AIUI pyparsing splits tokens on whitespace by default.","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"0796111c5203a9f6f9445e32b396ffc12f317ded","unresolved":false,"context_lines":[{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    unary \u003d unary_ops + atom"},{"line_number":89,"context_line":"    nary \u003d nary_ops + OneOrMore(atom)"},{"line_number":90,"context_line":"    term \u003d nary | unary | atom"},{"line_number":91,"context_line":"    disjunction \u003d OneOrMore(or_ + atom)"},{"line_number":92,"context_line":"    expr \u003d disjunction | term"},{"line_number":93,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_a3e4d23b","line":90,"updated":"2016-05-16 14:21:55.000000000","message":"The \"term\" production is only used in one place now, so you can eliminate it if you want.","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"49455e7fd4c47054a9723bc336b790240c799776","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        ast \u003d expr.parseString(spec)"},{"line_number":99,"context_line":"    except pyparsing.ParseException:"},{"line_number":100,"context_line":"        return cmp_value \u003d\u003d spec"},{"line_number":101,"context_line":"    else:"},{"line_number":102,"context_line":"        if len(ast) \u003d\u003d 1:"},{"line_number":103,"context_line":"            return ast[0] \u003d\u003d cmp_value"},{"line_number":104,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_55916ef0","line":101,"range":{"start_line":101,"start_character":4,"end_line":101,"end_character":8},"updated":"2016-05-16 10:10:17.000000000","message":"unnecessary else","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"49455e7fd4c47054a9723bc336b790240c799776","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    else:"},{"line_number":102,"context_line":"        if len(ast) \u003d\u003d 1:"},{"line_number":103,"context_line":"            return ast[0] \u003d\u003d cmp_value"},{"line_number":104,"context_line":"        else:"},{"line_number":105,"context_line":"            op \u003d op_methods[ast[0]]"},{"line_number":106,"context_line":"            if ast[0] \u003d\u003d \u0027\u003call-in\u003e\u0027 or ast[0] \u003d\u003d \u0027\u003cor\u003e\u0027:"},{"line_number":107,"context_line":"                return op(cmp_value, ast[1:])"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_358e6ad0","line":104,"range":{"start_line":104,"start_character":8,"end_line":104,"end_character":12},"updated":"2016-05-16 10:10:17.000000000","message":"and again","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"49455e7fd4c47054a9723bc336b790240c799776","unresolved":false,"context_lines":[{"line_number":103,"context_line":"            return ast[0] \u003d\u003d cmp_value"},{"line_number":104,"context_line":"        else:"},{"line_number":105,"context_line":"            op \u003d op_methods[ast[0]]"},{"line_number":106,"context_line":"            if ast[0] \u003d\u003d \u0027\u003call-in\u003e\u0027 or ast[0] \u003d\u003d \u0027\u003cor\u003e\u0027:"},{"line_number":107,"context_line":"                return op(cmp_value, ast[1:])"},{"line_number":108,"context_line":"            elif ast[0] \u003d\u003d \u0027\u003cin\u003e\u0027:"},{"line_number":109,"context_line":"                return any(op(cmp_value, a) for a in ast[1:])"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_98eaeb0d","line":106,"updated":"2016-05-16 10:10:17.000000000","message":"can we use all_in_ and or_ here please instead of restating the literal?","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"0796111c5203a9f6f9445e32b396ffc12f317ded","unresolved":false,"context_lines":[{"line_number":103,"context_line":"            return ast[0] \u003d\u003d cmp_value"},{"line_number":104,"context_line":"        else:"},{"line_number":105,"context_line":"            op \u003d op_methods[ast[0]]"},{"line_number":106,"context_line":"            if ast[0] \u003d\u003d \u0027\u003call-in\u003e\u0027 or ast[0] \u003d\u003d \u0027\u003cor\u003e\u0027:"},{"line_number":107,"context_line":"                return op(cmp_value, ast[1:])"},{"line_number":108,"context_line":"            elif ast[0] \u003d\u003d \u0027\u003cin\u003e\u0027:"},{"line_number":109,"context_line":"                return any(op(cmp_value, a) for a in ast[1:])"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_c368f6f7","line":106,"in_reply_to":"dab17558_98eaeb0d","updated":"2016-05-16 14:21:55.000000000","message":"You can eliminate the `if` entirely using the splat operator, as follows:\n\n    op \u003d op_methods[ast[0]]\n    return op(cmp_value, *ast[1:])\n\nThe grammar ensures that we pass the correct number of arguments to `op`. Add an \u0027\u003cor\u003e\u0027 key to `op_methods` and you can eliminate the `elif` branch as well.","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"0796111c5203a9f6f9445e32b396ffc12f317ded","unresolved":false,"context_lines":[{"line_number":105,"context_line":"            op \u003d op_methods[ast[0]]"},{"line_number":106,"context_line":"            if ast[0] \u003d\u003d \u0027\u003call-in\u003e\u0027 or ast[0] \u003d\u003d \u0027\u003cor\u003e\u0027:"},{"line_number":107,"context_line":"                return op(cmp_value, ast[1:])"},{"line_number":108,"context_line":"            elif ast[0] \u003d\u003d \u0027\u003cin\u003e\u0027:"},{"line_number":109,"context_line":"                return any(op(cmp_value, a) for a in ast[1:])"},{"line_number":110,"context_line":"            else:"},{"line_number":111,"context_line":"                return op(cmp_value, ast[1])"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_837b8ebd","line":108,"updated":"2016-05-16 14:21:55.000000000","message":"There\u0027s an \u0027\u003cin\u003e\u0027 key in op_methods above, but no \u0027\u003cor\u003e\u0027 key - I think you might have got \u003cin\u003e and \u003cor\u003e mixed up here.","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"49455e7fd4c47054a9723bc336b790240c799776","unresolved":false,"context_lines":[{"line_number":106,"context_line":"            if ast[0] \u003d\u003d \u0027\u003call-in\u003e\u0027 or ast[0] \u003d\u003d \u0027\u003cor\u003e\u0027:"},{"line_number":107,"context_line":"                return op(cmp_value, ast[1:])"},{"line_number":108,"context_line":"            elif ast[0] \u003d\u003d \u0027\u003cin\u003e\u0027:"},{"line_number":109,"context_line":"                return any(op(cmp_value, a) for a in ast[1:])"},{"line_number":110,"context_line":"            else:"},{"line_number":111,"context_line":"                return op(cmp_value, ast[1])"}],"source_content_type":"text/x-python","patch_set":15,"id":"dab17558_58bc0306","line":109,"updated":"2016-05-16 10:10:17.000000000","message":"You\u0027re supporting \"\u003cin\u003e aes mmx\", making \u003cin\u003e an nary op, but by my reading of the original parser, that\u0027s invalid. I think you can delete lines 108-109.","commit_id":"47d5642e5e24b0062316633f80a019202da90c34"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"ce17a4799cce33298c726ed0154835648353a400","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    \"\"\"Creates the grammar to be used by a spec matcher.\"\"\""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    # This is apparently how pyparsing recommends to be used,"},{"line_number":49,"context_line":"    # as http://pyparsing.wikispaces.com/share/view/644825 states that"},{"line_number":50,"context_line":"    # it is not thread-safe to use a parser across threads."},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    eq \u003d Literal(\"\u003d\")"}],"source_content_type":"text/x-python","patch_set":16,"id":"dab17558_217ee8e3","line":49,"updated":"2016-05-17 11:32:39.000000000","message":"Huh, OK. Thanks for adding this comment!","commit_id":"12dc03f370f271bedee9c3ed30cc877794d17417"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"ce17a4799cce33298c726ed0154835648353a400","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        op_lt_eq | op_lt |"},{"line_number":78,"context_line":"        op_gt_eq | op_gt)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    # A atom is anything not an operator/keyword followed by anything"},{"line_number":81,"context_line":"    # but whitespace..."},{"line_number":82,"context_line":"    atom \u003d ~(unary_ops | all_in_ | or_) + Regex(r\"\\S+\")"},{"line_number":83,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"dab17558_21cc2834","line":80,"updated":"2016-05-17 11:32:39.000000000","message":"Nit: \"an atom\"","commit_id":"12dc03f370f271bedee9c3ed30cc877794d17417"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"ce17a4799cce33298c726ed0154835648353a400","unresolved":false,"context_lines":[{"line_number":86,"context_line":"    disjunction \u003d OneOrMore(or_ + atom)"},{"line_number":87,"context_line":"    expr \u003d disjunction | (nary | unary | atom)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    # Small set of actions when a parse unit is encountered."},{"line_number":90,"context_line":"    disjunction.setParseAction(lambda s, l, t: [\"\u003cor\u003e\"] + t[1::2])"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    return expr"}],"source_content_type":"text/x-python","patch_set":16,"id":"dab17558_219a6814","line":89,"updated":"2016-05-17 11:32:39.000000000","message":"I think something like \"even-numbered tokens will be \u0027\u003cor\u003e\u0027, so we drop them\" is more informative here.","commit_id":"12dc03f370f271bedee9c3ed30cc877794d17417"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"ce17a4799cce33298c726ed0154835648353a400","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    try:"},{"line_number":99,"context_line":"        ast \u003d expr.parseString(spec)"},{"line_number":100,"context_line":"    except pyparsing.ParseException:"},{"line_number":101,"context_line":"        return cmp_value \u003d\u003d spec"},{"line_number":102,"context_line":"    if len(ast) \u003d\u003d 1:"},{"line_number":103,"context_line":"        return ast[0] \u003d\u003d cmp_value"},{"line_number":104,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"dab17558_3cebaf14","line":101,"updated":"2016-05-17 11:32:39.000000000","message":"This slightly disagrees with the old parser\u0027s behaviour on the mal-formed input \"\u003cor\u003e \u003e\u003d\", but that probably doesn\u0027t matter.","commit_id":"12dc03f370f271bedee9c3ed30cc877794d17417"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"397ffe4d91ff444386c51d49382b6871557903d0","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    try:"},{"line_number":99,"context_line":"        ast \u003d expr.parseString(spec)"},{"line_number":100,"context_line":"    except pyparsing.ParseException:"},{"line_number":101,"context_line":"        return cmp_value \u003d\u003d spec"},{"line_number":102,"context_line":"    if len(ast) \u003d\u003d 1:"},{"line_number":103,"context_line":"        return ast[0] \u003d\u003d cmp_value"},{"line_number":104,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"dab17558_3e24345e","line":101,"in_reply_to":"dab17558_3cebaf14","updated":"2016-05-17 15:48:33.000000000","message":"Hmmm, we can probably special-case that (if we want).","commit_id":"12dc03f370f271bedee9c3ed30cc877794d17417"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"227d709b3e23aa5002051f112c3fc67e1ed81cc6","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    try:"},{"line_number":99,"context_line":"        ast \u003d expr.parseString(spec)"},{"line_number":100,"context_line":"    except pyparsing.ParseException:"},{"line_number":101,"context_line":"        return cmp_value \u003d\u003d spec"},{"line_number":102,"context_line":"    if len(ast) \u003d\u003d 1:"},{"line_number":103,"context_line":"        return ast[0] \u003d\u003d cmp_value"},{"line_number":104,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"bab6814e_2904d07c","line":101,"in_reply_to":"dab17558_3e24345e","updated":"2016-05-18 11:24:17.000000000","message":"I don\u0027t think it matters, honestly. Undefined constructions can cause demons to fly out of your nose, and all that.","commit_id":"12dc03f370f271bedee9c3ed30cc877794d17417"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a53b035eb495a9a71612bd744a1305a4f0a7b98","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"op_methods \u003d {"},{"line_number":24,"context_line":"    # This one is special/odd,"},{"line_number":25,"context_line":"    # TODO(harlowja): fix it so that it\u0027s not greater than or"},{"line_number":26,"context_line":"    # equal, see https://review.openstack.org/#/c/8089/"},{"line_number":27,"context_line":"    \u0027\u003d\u0027: lambda x, y: float(x) \u003e\u003d float(y),"},{"line_number":28,"context_line":"    # More sane ops/methods"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_8627e961","line":25,"updated":"2016-07-01 01:37:26.000000000","message":"How can you fix it? whatever you do would make it not backwards compatible.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"8a149c57f0eace9c972826d3f7b62b7f8c165c7e","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"op_methods \u003d {"},{"line_number":24,"context_line":"    # This one is special/odd,"},{"line_number":25,"context_line":"    # TODO(harlowja): fix it so that it\u0027s not greater than or"},{"line_number":26,"context_line":"    # equal, see https://review.openstack.org/#/c/8089/"},{"line_number":27,"context_line":"    \u0027\u003d\u0027: lambda x, y: float(x) \u003e\u003d float(y),"},{"line_number":28,"context_line":"    # More sane ops/methods"}],"source_content_type":"text/x-python","patch_set":17,"id":"1aa78d24_3e87ffb5","line":25,"in_reply_to":"3aaa91ec_8627e961","updated":"2016-07-09 05:07:30.000000000","message":"I can fix anything!","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a53b035eb495a9a71612bd744a1305a4f0a7b98","unresolved":false,"context_lines":[{"line_number":23,"context_line":"op_methods \u003d {"},{"line_number":24,"context_line":"    # This one is special/odd,"},{"line_number":25,"context_line":"    # TODO(harlowja): fix it so that it\u0027s not greater than or"},{"line_number":26,"context_line":"    # equal, see https://review.openstack.org/#/c/8089/"},{"line_number":27,"context_line":"    \u0027\u003d\u0027: lambda x, y: float(x) \u003e\u003d float(y),"},{"line_number":28,"context_line":"    # More sane ops/methods"},{"line_number":29,"context_line":"    \u0027!\u003d\u0027: lambda x, y: float(x) !\u003d float(y),"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_86836902","line":26,"updated":"2016-07-01 01:37:26.000000000","message":"i thought this link was the fix. That\u0027s the original patch, right? Maybe add this above your TODO. Eg, something like \nThis one is special/odd, from https://...\u0027 \nTODO blah blah.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"8a149c57f0eace9c972826d3f7b62b7f8c165c7e","unresolved":false,"context_lines":[{"line_number":23,"context_line":"op_methods \u003d {"},{"line_number":24,"context_line":"    # This one is special/odd,"},{"line_number":25,"context_line":"    # TODO(harlowja): fix it so that it\u0027s not greater than or"},{"line_number":26,"context_line":"    # equal, see https://review.openstack.org/#/c/8089/"},{"line_number":27,"context_line":"    \u0027\u003d\u0027: lambda x, y: float(x) \u003e\u003d float(y),"},{"line_number":28,"context_line":"    # More sane ops/methods"},{"line_number":29,"context_line":"    \u0027!\u003d\u0027: lambda x, y: float(x) !\u003d float(y),"}],"source_content_type":"text/x-python","patch_set":17,"id":"1aa78d24_debebb63","line":26,"in_reply_to":"3aaa91ec_86836902","updated":"2016-07-09 05:07:30.000000000","message":"Fair enough.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a53b035eb495a9a71612bd744a1305a4f0a7b98","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    # TODO(harlowja): fix it so that it\u0027s not greater than or"},{"line_number":26,"context_line":"    # equal, see https://review.openstack.org/#/c/8089/"},{"line_number":27,"context_line":"    \u0027\u003d\u0027: lambda x, y: float(x) \u003e\u003d float(y),"},{"line_number":28,"context_line":"    # More sane ops/methods"},{"line_number":29,"context_line":"    \u0027!\u003d\u0027: lambda x, y: float(x) !\u003d float(y),"},{"line_number":30,"context_line":"    \u0027\u003c\u003d\u0027: lambda x, y: float(x) \u003c\u003d float(y),"},{"line_number":31,"context_line":"    \u0027\u003d\u003d\u0027: lambda x, y: float(x) \u003d\u003d float(y),"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_86ffe964","line":28,"updated":"2016-07-01 01:37:26.000000000","message":"I\u0027m not crazy about this comment. Wondering if a comment is necessary...","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"8a149c57f0eace9c972826d3f7b62b7f8c165c7e","unresolved":false,"context_lines":[{"line_number":25,"context_line":"    # TODO(harlowja): fix it so that it\u0027s not greater than or"},{"line_number":26,"context_line":"    # equal, see https://review.openstack.org/#/c/8089/"},{"line_number":27,"context_line":"    \u0027\u003d\u0027: lambda x, y: float(x) \u003e\u003d float(y),"},{"line_number":28,"context_line":"    # More sane ops/methods"},{"line_number":29,"context_line":"    \u0027!\u003d\u0027: lambda x, y: float(x) !\u003d float(y),"},{"line_number":30,"context_line":"    \u0027\u003c\u003d\u0027: lambda x, y: float(x) \u003c\u003d float(y),"},{"line_number":31,"context_line":"    \u0027\u003d\u003d\u0027: lambda x, y: float(x) \u003d\u003d float(y),"}],"source_content_type":"text/x-python","patch_set":17,"id":"1aa78d24_1eb5e37c","line":28,"in_reply_to":"3aaa91ec_86ffe964","updated":"2016-07-09 05:07:30.000000000","message":"That means u must be sane. haha","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a53b035eb495a9a71612bd744a1305a4f0a7b98","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        Literal(\"!\u003d\") | Literal(\"\u003cin\u003e\") |"},{"line_number":55,"context_line":"        Literal(\"\u003e\u003d\") | Literal(\"\u003c\u003d\") |"},{"line_number":56,"context_line":"        Literal(\"s\u003d\u003d\") | Literal(\"s!\u003d\") |"},{"line_number":57,"context_line":"        # Order matters here (so that \u0027\u003e\u0027 doesn\u0027t match before \u0027\u003e\u003d\u0027)"},{"line_number":58,"context_line":"        Literal(\"s\u003c\u003d\") | Literal(\"s\u003c\") |"},{"line_number":59,"context_line":"        Literal(\"s\u003e\u003d\") | Literal(\"s\u003e\"))"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_66975dec","line":57,"updated":"2016-07-01 01:37:26.000000000","message":"doesn\u0027t this refer to line 59?","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"8a149c57f0eace9c972826d3f7b62b7f8c165c7e","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        Literal(\"!\u003d\") | Literal(\"\u003cin\u003e\") |"},{"line_number":55,"context_line":"        Literal(\"\u003e\u003d\") | Literal(\"\u003c\u003d\") |"},{"line_number":56,"context_line":"        Literal(\"s\u003d\u003d\") | Literal(\"s!\u003d\") |"},{"line_number":57,"context_line":"        # Order matters here (so that \u0027\u003e\u0027 doesn\u0027t match before \u0027\u003e\u003d\u0027)"},{"line_number":58,"context_line":"        Literal(\"s\u003c\u003d\") | Literal(\"s\u003c\") |"},{"line_number":59,"context_line":"        Literal(\"s\u003e\u003d\") | Literal(\"s\u003e\"))"},{"line_number":60,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1aa78d24_9ea9d326","line":57,"in_reply_to":"3aaa91ec_66975dec","updated":"2016-07-09 05:07:30.000000000","message":"Ya, it applies to 58 and 59, will clear up.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a53b035eb495a9a71612bd744a1305a4f0a7b98","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    all_in_ \u003d Literal(\"\u003call-in\u003e\")"},{"line_number":62,"context_line":"    or_ \u003d Literal(\"\u003cor\u003e\")"},{"line_number":63,"context_line":"    # An atom is anything not an operator/keyword followed by anything"},{"line_number":64,"context_line":"    # but whitespace"},{"line_number":65,"context_line":"    atom \u003d ~(unary_ops | all_in_ | or_) + Regex(r\"\\S+\")"},{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_86b7e983","line":63,"updated":"2016-07-01 01:37:26.000000000","message":"What do you mean by \u0027keyword\u0027?","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"8a149c57f0eace9c972826d3f7b62b7f8c165c7e","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    all_in_ \u003d Literal(\"\u003call-in\u003e\")"},{"line_number":62,"context_line":"    or_ \u003d Literal(\"\u003cor\u003e\")"},{"line_number":63,"context_line":"    # An atom is anything not an operator/keyword followed by anything"},{"line_number":64,"context_line":"    # but whitespace"},{"line_number":65,"context_line":"    atom \u003d ~(unary_ops | all_in_ | or_) + Regex(r\"\\S+\")"},{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"}],"source_content_type":"text/x-python","patch_set":17,"id":"1aa78d24_de335b12","line":63,"in_reply_to":"1aa78d24_21fbf6c2","updated":"2016-07-09 05:07:30.000000000","message":"Ya, so this can be confusing; I\u0027ll adjust.\n\nI think the formal name for some of this would be \u0027keyword\u0027 and how they work would be a binary or unary (or ...) operator in that they operate on 1 or 2 or more values.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"213985f1bbcff656e49ab02ba303ccd26193f51c","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    all_in_ \u003d Literal(\"\u003call-in\u003e\")"},{"line_number":62,"context_line":"    or_ \u003d Literal(\"\u003cor\u003e\")"},{"line_number":63,"context_line":"    # An atom is anything not an operator/keyword followed by anything"},{"line_number":64,"context_line":"    # but whitespace"},{"line_number":65,"context_line":"    atom \u003d ~(unary_ops | all_in_ | or_) + Regex(r\"\\S+\")"},{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"}],"source_content_type":"text/x-python","patch_set":17,"id":"1aa78d24_21fbf6c2","line":63,"in_reply_to":"3aaa91ec_6738c9d5","updated":"2016-07-05 14:08:03.000000000","message":"Oh. I view \"\u003cor\u003e\" as an operator; it is in the op_methods dict above.\n\nI suppose we could rename \u0027all_in_\u0027 and \u0027or_\u0027 to \u0027all_in_op\u0027 \u0026 \u0027or_op\u0027 respectively to make it more obvious that they are all operators?","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"940d49c56e0e0eac4ac77cc92f8d2eb87cdb1d1f","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    all_in_ \u003d Literal(\"\u003call-in\u003e\")"},{"line_number":62,"context_line":"    or_ \u003d Literal(\"\u003cor\u003e\")"},{"line_number":63,"context_line":"    # An atom is anything not an operator/keyword followed by anything"},{"line_number":64,"context_line":"    # but whitespace"},{"line_number":65,"context_line":"    atom \u003d ~(unary_ops | all_in_ | or_) + Regex(r\"\\S+\")"},{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_6738c9d5","line":63,"in_reply_to":"3aaa91ec_86b7e983","updated":"2016-07-01 16:46:46.000000000","message":"A word with special meaning in the language, which therefore isn\u0027t available for use as a variable name. In Python that would be something like \"class\", but here it means \"\u003cor\u003e\".","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a53b035eb495a9a71612bd744a1305a4f0a7b98","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    all_in_ \u003d Literal(\"\u003call-in\u003e\")"},{"line_number":62,"context_line":"    or_ \u003d Literal(\"\u003cor\u003e\")"},{"line_number":63,"context_line":"    # An atom is anything not an operator/keyword followed by anything"},{"line_number":64,"context_line":"    # but whitespace"},{"line_number":65,"context_line":"    atom \u003d ~(unary_ops | all_in_ | or_) + Regex(r\"\\S+\")"},{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"},{"line_number":67,"context_line":"    nary \u003d all_in_ + OneOrMore(atom)"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_a1a3effe","line":64,"updated":"2016-07-01 01:37:26.000000000","message":"Maybe I\u0027m tired, but I cannot parse this sentence. :-(\n\nLooks like an atom is anything (string of non-whitespace chars) that isn\u0027t an operator?","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"940d49c56e0e0eac4ac77cc92f8d2eb87cdb1d1f","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    all_in_ \u003d Literal(\"\u003call-in\u003e\")"},{"line_number":62,"context_line":"    or_ \u003d Literal(\"\u003cor\u003e\")"},{"line_number":63,"context_line":"    # An atom is anything not an operator/keyword followed by anything"},{"line_number":64,"context_line":"    # but whitespace"},{"line_number":65,"context_line":"    atom \u003d ~(unary_ops | all_in_ | or_) + Regex(r\"\\S+\")"},{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"},{"line_number":67,"context_line":"    nary \u003d all_in_ + OneOrMore(atom)"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_077105a9","line":64,"in_reply_to":"3aaa91ec_a1a3effe","updated":"2016-07-01 16:46:46.000000000","message":"No, because \"\u003call-in\u003e2132145\" isn\u0027t a valid atom.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"6a53b035eb495a9a71612bd744a1305a4f0a7b98","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"},{"line_number":67,"context_line":"    nary \u003d all_in_ + OneOrMore(atom)"},{"line_number":68,"context_line":"    disjunction \u003d OneOrMore(or_ + atom)"},{"line_number":69,"context_line":"    # For even-numbered tokens will be \u0027\u003cor\u003e\u0027, so we drop them."},{"line_number":70,"context_line":"    disjunction.setParseAction(lambda _s, _l, t: [\"\u003cor\u003e\"] + t[1::2])"},{"line_number":71,"context_line":"    expr \u003d disjunction | nary | unary | atom"},{"line_number":72,"context_line":"    return expr"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_9e2729c9","line":69,"updated":"2016-07-01 01:37:26.000000000","message":"I don\u0027t understand this, maybe I\u0027m not parsing the sentence properly.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"8a149c57f0eace9c972826d3f7b62b7f8c165c7e","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"},{"line_number":67,"context_line":"    nary \u003d all_in_ + OneOrMore(atom)"},{"line_number":68,"context_line":"    disjunction \u003d OneOrMore(or_ + atom)"},{"line_number":69,"context_line":"    # For even-numbered tokens will be \u0027\u003cor\u003e\u0027, so we drop them."},{"line_number":70,"context_line":"    disjunction.setParseAction(lambda _s, _l, t: [\"\u003cor\u003e\"] + t[1::2])"},{"line_number":71,"context_line":"    expr \u003d disjunction | nary | unary | atom"},{"line_number":72,"context_line":"    return expr"}],"source_content_type":"text/x-python","patch_set":17,"id":"1aa78d24_fe13b762","line":69,"in_reply_to":"1aa78d24_c19dd25a","updated":"2016-07-09 05:07:30.000000000","message":"Will adjust.","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"940d49c56e0e0eac4ac77cc92f8d2eb87cdb1d1f","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"},{"line_number":67,"context_line":"    nary \u003d all_in_ + OneOrMore(atom)"},{"line_number":68,"context_line":"    disjunction \u003d OneOrMore(or_ + atom)"},{"line_number":69,"context_line":"    # For even-numbered tokens will be \u0027\u003cor\u003e\u0027, so we drop them."},{"line_number":70,"context_line":"    disjunction.setParseAction(lambda _s, _l, t: [\"\u003cor\u003e\"] + t[1::2])"},{"line_number":71,"context_line":"    expr \u003d disjunction | nary | unary | atom"},{"line_number":72,"context_line":"    return expr"}],"source_content_type":"text/x-python","patch_set":17,"id":"3aaa91ec_c7841d5f","line":69,"in_reply_to":"3aaa91ec_9e2729c9","updated":"2016-07-01 16:46:46.000000000","message":"Is \"Even-numbered tokens will be \u0027\u003cor\u003e\u0027, so we drop them\" clearer?","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"213985f1bbcff656e49ab02ba303ccd26193f51c","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    unary \u003d unary_ops + atom"},{"line_number":67,"context_line":"    nary \u003d all_in_ + OneOrMore(atom)"},{"line_number":68,"context_line":"    disjunction \u003d OneOrMore(or_ + atom)"},{"line_number":69,"context_line":"    # For even-numbered tokens will be \u0027\u003cor\u003e\u0027, so we drop them."},{"line_number":70,"context_line":"    disjunction.setParseAction(lambda _s, _l, t: [\"\u003cor\u003e\"] + t[1::2])"},{"line_number":71,"context_line":"    expr \u003d disjunction | nary | unary | atom"},{"line_number":72,"context_line":"    return expr"}],"source_content_type":"text/x-python","patch_set":17,"id":"1aa78d24_c19dd25a","line":69,"in_reply_to":"3aaa91ec_c7841d5f","updated":"2016-07-05 14:08:03.000000000","message":"Yup, I understand that!","commit_id":"94be934851bf05d1c160870a88546fe28aa8d69b"}],"requirements.txt":[{"author":{"_account_id":18893,"name":"Miles Gould","email":"mgould@redhat.com","username":"pozorvlak"},"change_message_id":"984f959cb38947ffd062a10dd43450ba3549c426","unresolved":false,"context_lines":[{"line_number":17,"context_line":"netaddr!\u003d0.7.16,\u003e\u003d0.7.12 # BSD"},{"line_number":18,"context_line":"netifaces\u003e\u003d0.10.4 # MIT"},{"line_number":19,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":20,"context_line":"pyparsing\u003e\u003d2.0.1 # MIT"}],"source_content_type":"text/plain","patch_set":8,"id":"dab17558_7e60cfa5","line":20,"updated":"2016-05-10 11:19:56.000000000","message":"I guess you\u0027ll need to submit a change to global-requirements and Depend-On it here.","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"d4fdce97760e33184d0b5783e60e16ffd5ea886b","unresolved":false,"context_lines":[{"line_number":17,"context_line":"netaddr!\u003d0.7.16,\u003e\u003d0.7.12 # BSD"},{"line_number":18,"context_line":"netifaces\u003e\u003d0.10.4 # MIT"},{"line_number":19,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":20,"context_line":"pyparsing\u003e\u003d2.0.1 # MIT"}],"source_content_type":"text/plain","patch_set":8,"id":"dab17558_7299c478","line":20,"in_reply_to":"dab17558_7e60cfa5","updated":"2016-05-11 22:47:09.000000000","message":"Afaik its already there.\n\nhttps://github.com/openstack/requirements/blob/master/global-requirements.txt#L167","commit_id":"dc2233e7b929e70f6d702bf26e3cd626b0e671a6"}]}
