)]}'
{"openstack/common/policy.py":[{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"2efb0be816fe06e719f09168ff689168f08dbfc8","unresolved":false,"context_lines":[{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    # If it is False, raise the exception if requested"},{"line_number":203,"context_line":"    if exc and result is False:"},{"line_number":204,"context_line":"        raise exc(*args, **kwargs)"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    return result"},{"line_number":207,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FLN0%3D","line":204,"updated":"2012-10-09 12:44:25.000000000","message":"I know we have this exception throwing support already, but I think I\u0027d prefer if this function just returned false and the caller just raises an exception if that\u0027s what they want","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"2efb0be816fe06e719f09168ff689168f08dbfc8","unresolved":false,"context_lines":[{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    # If it is False, raise the exception if requested"},{"line_number":203,"context_line":"    if exc and result is False:"},{"line_number":204,"context_line":"        raise exc(*args, **kwargs)"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    return result"},{"line_number":207,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FK6U%3D","line":204,"in_reply_to":"AAAALH%2F%2FLAE%3D","updated":"2012-10-09 16:39:42.000000000","message":"Ok, let\u0027s leave it for now","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"unresolved":false,"context_lines":[{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    # If it is False, raise the exception if requested"},{"line_number":203,"context_line":"    if exc and result is False:"},{"line_number":204,"context_line":"        raise exc(*args, **kwargs)"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    return result"},{"line_number":207,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FLAE%3D","line":204,"in_reply_to":"AAAALH%2F%2FLN0%3D","updated":"2012-10-09 15:42:46.000000000","message":"This does make one usage a little simpler.  I\u0027m already starting on getting nova converted over to use the new policy code, and I have this in its enforce() function:\n\n    extra \u003d {}\n    if do_raise:\n        extra.update(exc\u003dexception.PolicyNotAuthorized, action\u003daction)\n\n    return policy.check(action, target, credentials, **extra)\n\nIf I don\u0027t have the exception throwing available here, then I would have to do something like this:\n\n    result \u003d policy.check(action, target, credentials)\n    if do_raise and result is False:\n        raise exception.PolicyNotAuthorized, action\u003daction)\n\n    return result\n\nProbably 6 of one, half-dozen of another, though :)","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"2efb0be816fe06e719f09168ff689168f08dbfc8","unresolved":false,"context_lines":[{"line_number":209,"context_line":"class Brain(Rules):"},{"line_number":210,"context_line":"    \"\"\""},{"line_number":211,"context_line":"    Provided for backwards compatibility.  Implements the functions of"},{"line_number":212,"context_line":"    a classic Brain.  Deprecated; use Rules instead."},{"line_number":213,"context_line":"    \"\"\""},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def __init__(self, rules\u003dNone, default_rule\u003dNone):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FLNw%3D","line":212,"updated":"2012-10-09 12:44:25.000000000","message":"We could just kill this off instead of deprecating it?\n\ni.e. the point of openstack-common \"incubation\" is that we can make incompatible API changes\n\nWe definitely need to retain support for the old file format, but not necessarily the old API","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"2efb0be816fe06e719f09168ff689168f08dbfc8","unresolved":false,"context_lines":[{"line_number":209,"context_line":"class Brain(Rules):"},{"line_number":210,"context_line":"    \"\"\""},{"line_number":211,"context_line":"    Provided for backwards compatibility.  Implements the functions of"},{"line_number":212,"context_line":"    a classic Brain.  Deprecated; use Rules instead."},{"line_number":213,"context_line":"    \"\"\""},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def __init__(self, rules\u003dNone, default_rule\u003dNone):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FK6Q%3D","line":212,"in_reply_to":"AAAALH%2F%2FK%2F0%3D","updated":"2012-10-09 16:39:42.000000000","message":"The only difference between my patch series and your patch is the removal of these backwards compat APIs. See the second patch in the series","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"unresolved":false,"context_lines":[{"line_number":209,"context_line":"class Brain(Rules):"},{"line_number":210,"context_line":"    \"\"\""},{"line_number":211,"context_line":"    Provided for backwards compatibility.  Implements the functions of"},{"line_number":212,"context_line":"    a classic Brain.  Deprecated; use Rules instead."},{"line_number":213,"context_line":"    \"\"\""},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def __init__(self, rules\u003dNone, default_rule\u003dNone):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FK%2F0%3D","line":212,"in_reply_to":"AAAALH%2F%2FLNw%3D","updated":"2012-10-09 15:42:46.000000000","message":"I would love to, just wasn\u0027t sure I had permission to do so :)  I\u0027ll alter to kill this and some other back-compat stuff.  (And yes, I\u0027ll preserve the support for the old file format.)","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"2efb0be816fe06e719f09168ff689168f08dbfc8","unresolved":false,"context_lines":[{"line_number":722,"context_line":"                # It\u0027s a quoted string"},{"line_number":723,"context_line":"                yield \u0027string\u0027, tok[1:-1]"},{"line_number":724,"context_line":"            else:"},{"line_number":725,"context_line":"                yield \u0027check\u0027, _parse_check(clean)"},{"line_number":726,"context_line":""},{"line_number":727,"context_line":"        # Yield the trailing parens"},{"line_number":728,"context_line":"        for i in range(trail):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FLMk%3D","line":725,"updated":"2012-10-09 12:44:25.000000000","message":"Random comment - I would have expected the tokenizer to just return the check string and we\u0027d parse it elsewhere","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"2efb0be816fe06e719f09168ff689168f08dbfc8","unresolved":false,"context_lines":[{"line_number":722,"context_line":"                # It\u0027s a quoted string"},{"line_number":723,"context_line":"                yield \u0027string\u0027, tok[1:-1]"},{"line_number":724,"context_line":"            else:"},{"line_number":725,"context_line":"                yield \u0027check\u0027, _parse_check(clean)"},{"line_number":726,"context_line":""},{"line_number":727,"context_line":"        # Yield the trailing parens"},{"line_number":728,"context_line":"        for i in range(trail):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FK6M%3D","line":725,"in_reply_to":"AAAALH%2F%2FK%2Fk%3D","updated":"2012-10-09 16:39:42.000000000","message":"OK","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"unresolved":false,"context_lines":[{"line_number":722,"context_line":"                # It\u0027s a quoted string"},{"line_number":723,"context_line":"                yield \u0027string\u0027, tok[1:-1]"},{"line_number":724,"context_line":"            else:"},{"line_number":725,"context_line":"                yield \u0027check\u0027, _parse_check(clean)"},{"line_number":726,"context_line":""},{"line_number":727,"context_line":"        # Yield the trailing parens"},{"line_number":728,"context_line":"        for i in range(trail):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FK%2Fk%3D","line":725,"in_reply_to":"AAAALH%2F%2FLMk%3D","updated":"2012-10-09 15:42:46.000000000","message":"Tokenizers typically return the token type and the token\u0027s semantic value.  Here I decided that the semantic value for a rule would be a Check object.  This is the sort of thing I\u0027ve done when building parsers in C, so I just made the same decision here.  It also simplifies the logic in the actual parser…","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"}],"tests/unit/test_policy.py":[{"author":{"_account_id":385,"name":"Jason Kölker","email":"jason@koelker.net","username":"jason-koelker"},"change_message_id":"2fcd55dbbb4c290d2cec36c152a4c60b967e930f","unresolved":false,"context_lines":[{"line_number":15,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":16,"context_line":"#    under the License."},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"\"\"\"Test of Policy Engine For Nova\"\"\""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"import os.path"},{"line_number":21,"context_line":"import StringIO"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAALH%2F%2FL1g%3D","line":18,"updated":"2012-10-08 15:43:09.000000000","message":"Zeptonit: Not nova","commit_id":"3c9086fc8d3d9dd4055d7556485f12da0ede45b3"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"f731170e6322a4f14d65c3ce898d50b361f5bc12","unresolved":false,"context_lines":[{"line_number":15,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":16,"context_line":"#    under the License."},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"\"\"\"Test of Policy Engine For Nova\"\"\""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"import os.path"},{"line_number":21,"context_line":"import StringIO"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAALH%2F%2FLxY%3D","line":18,"in_reply_to":"AAAALH%2F%2FL1g%3D","updated":"2012-10-08 16:05:34.000000000","message":"Yeah, that was there before I got started :)","commit_id":"3c9086fc8d3d9dd4055d7556485f12da0ede45b3"},{"author":{"_account_id":385,"name":"Jason Kölker","email":"jason@koelker.net","username":"jason-koelker"},"change_message_id":"2fcd55dbbb4c290d2cec36c152a4c60b967e930f","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"from openstack.common import jsonutils"},{"line_number":29,"context_line":"from openstack.common import policy"},{"line_number":30,"context_line":"from openstack.common import testutils"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class TestException(Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAALH%2F%2FL1k%3D","line":30,"updated":"2012-10-08 15:43:09.000000000","message":"Attonit: Not used.","commit_id":"3c9086fc8d3d9dd4055d7556485f12da0ede45b3"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"f731170e6322a4f14d65c3ce898d50b361f5bc12","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"from openstack.common import jsonutils"},{"line_number":29,"context_line":"from openstack.common import policy"},{"line_number":30,"context_line":"from openstack.common import testutils"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class TestException(Exception):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAALH%2F%2FLxc%3D","line":30,"in_reply_to":"AAAALH%2F%2FL1k%3D","updated":"2012-10-08 16:05:34.000000000","message":"Ah, right; I didn\u0027t rewrite test_policy.py from scratch, like I did policy.py, so I ended up skipping a bunch of tests, then un-skipped as I fixed or of course as I decided they had to go.  Forgot to remove the testutils import...","commit_id":"3c9086fc8d3d9dd4055d7556485f12da0ede45b3"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"2efb0be816fe06e719f09168ff689168f08dbfc8","unresolved":false,"context_lines":[{"line_number":172,"context_line":"        policy._rules \u003d dict(default\u003dFakeCheck(\"result\"))"},{"line_number":173,"context_line":"        result \u003d policy.check(\"default\", \"target\", \"creds\")"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"        self.assertEqual(result, (\"target\", \"creds\"))"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    def test_check_raises(self):"},{"line_number":178,"context_line":"        policy._rules \u003d None"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FLHg%3D","line":175,"updated":"2012-10-09 12:44:25.000000000","message":"This looked wrong and sure enough, there\u0027s another test case by the same name so this one wasn\u0027t being run at all","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":1247,"name":"Mark McLoughlin","email":"markmc@redhat.com","username":"markmc"},"change_message_id":"2efb0be816fe06e719f09168ff689168f08dbfc8","unresolved":false,"context_lines":[{"line_number":172,"context_line":"        policy._rules \u003d dict(default\u003dFakeCheck(\"result\"))"},{"line_number":173,"context_line":"        result \u003d policy.check(\"default\", \"target\", \"creds\")"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"        self.assertEqual(result, (\"target\", \"creds\"))"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    def test_check_raises(self):"},{"line_number":178,"context_line":"        policy._rules \u003d None"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FK6A%3D","line":175,"in_reply_to":"AAAALH%2F%2FK%2FY%3D","updated":"2012-10-09 16:39:42.000000000","message":"Yeah, the terminology is messed up here - AIUI the class is a \"test case\" and individual methods are \"tests\"","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"unresolved":false,"context_lines":[{"line_number":172,"context_line":"        policy._rules \u003d dict(default\u003dFakeCheck(\"result\"))"},{"line_number":173,"context_line":"        result \u003d policy.check(\"default\", \"target\", \"creds\")"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"        self.assertEqual(result, (\"target\", \"creds\"))"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    def test_check_raises(self):"},{"line_number":178,"context_line":"        policy._rules \u003d None"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FK3g%3D","line":175,"in_reply_to":"AAAALH%2F%2FK6A%3D","updated":"2012-10-09 17:20:45.000000000","message":"Makes sense; I\u0027ll make a mental note of that terminology :)","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"unresolved":false,"context_lines":[{"line_number":172,"context_line":"        policy._rules \u003d dict(default\u003dFakeCheck(\"result\"))"},{"line_number":173,"context_line":"        result \u003d policy.check(\"default\", \"target\", \"creds\")"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"        self.assertEqual(result, (\"target\", \"creds\"))"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    def test_check_raises(self):"},{"line_number":178,"context_line":"        policy._rules \u003d None"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAALH%2F%2FK%2FY%3D","line":175,"in_reply_to":"AAAALH%2F%2FLHg%3D","updated":"2012-10-09 15:42:46.000000000","message":"No, there isn\u0027t another test case by the same name…but there is another test case *class* by the same name; took me forever to figure out that\u0027s what you were referring to :)","commit_id":"1fd01a60f8e95ebc1fdd4cda4d77ee8c93d42d99"}]}
