)]}'
{"keystone/common/controller.py":[{"author":{"_account_id":10873,"name":"Juan Antonio Osorio Robles","email":"jaosorior@redhat.com","username":"ejuaoso"},"change_message_id":"dfac8c174a5f42bc4ae97925a09cc6418cdcbb7a","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            return"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"        exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":639,"context_line":"                          \u0027attributes\u0027: \u0027, \u0027.join(blocked_keys)}"},{"line_number":640,"context_line":"        raise exception.ImmutableAttributeError(**exception_args)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9x7I%3D","line":639,"updated":"2014-04-02 07:37:46.000000000","message":"Perhaps a more json style approach would be to include an actual list of the blocked keys, and not a string joined by commas.","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":10873,"name":"Juan Antonio Osorio Robles","email":"jaosorior@redhat.com","username":"ejuaoso"},"change_message_id":"ccf96776fe6a3afbb65a97b3756838f9194aff6f","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            return"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"        exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":639,"context_line":"                          \u0027attributes\u0027: \u0027, \u0027.join(blocked_keys)}"},{"line_number":640,"context_line":"        raise exception.ImmutableAttributeError(**exception_args)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9x2U%3D","line":639,"in_reply_to":"AAAAWH%2F9x5I%3D","updated":"2014-04-02 07:48:59.000000000","message":"Well, if the goal was json schema compatibility, then it would be appropriate to have explicitly something like\n\n\u0027attributes\u0027 : [\u0027key1\u0027, \u0027key2\u0027, \u0027key3\u0027]\n\nbut I guess this should be discussed further with core developers.","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"a47cdb5a6cb6932167e2147fe682ceb705f992c5","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            return"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"        exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":639,"context_line":"                          \u0027attributes\u0027: \u0027, \u0027.join(blocked_keys)}"},{"line_number":640,"context_line":"        raise exception.ImmutableAttributeError(**exception_args)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9x5I%3D","line":639,"in_reply_to":"AAAAWH%2F9x7I%3D","updated":"2014-04-02 07:41:13.000000000","message":"so str(blocked_keys) instead of \u0027, \u0027.join() ? This all go to the human-readable message, so I wanted to avoid str()\u0027ed Python structures.","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":10873,"name":"Juan Antonio Osorio Robles","email":"jaosorior@redhat.com","username":"ejuaoso"},"change_message_id":"dfac8c174a5f42bc4ae97925a09cc6418cdcbb7a","unresolved":false,"context_lines":[{"line_number":662,"context_line":""},{"line_number":663,"context_line":"        if len(missing_args) \u003e 0:"},{"line_number":664,"context_line":"            exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":665,"context_line":"                              \u0027attribute\u0027: \u0027, \u0027.join(missing_args)}"},{"line_number":666,"context_line":"            raise exception.ValidationError(**exception_args)"},{"line_number":667,"context_line":"        else:"},{"line_number":668,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9x6w%3D","line":665,"updated":"2014-04-02 07:37:46.000000000","message":"same as above","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"f1f60ee84f6c2fda196abebcd9bec3ef5c3e8808","unresolved":false,"context_lines":[{"line_number":662,"context_line":""},{"line_number":663,"context_line":"        if len(missing_args) \u003e 0:"},{"line_number":664,"context_line":"            exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":665,"context_line":"                              \u0027attribute\u0027: \u0027, \u0027.join(missing_args)}"},{"line_number":666,"context_line":"            raise exception.ValidationError(**exception_args)"},{"line_number":667,"context_line":"        else:"},{"line_number":668,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9qT4%3D","line":665,"updated":"2014-04-03 00:53:04.000000000","message":"this needs to be attributes and not attribute.\n\nWhy don\u0027t the tests fail?","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"0988b97a88ddde50252064e5caf4203db86eddd7","unresolved":false,"context_lines":[{"line_number":662,"context_line":""},{"line_number":663,"context_line":"        if len(missing_args) \u003e 0:"},{"line_number":664,"context_line":"            exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":665,"context_line":"                              \u0027attribute\u0027: \u0027, \u0027.join(missing_args)}"},{"line_number":666,"context_line":"            raise exception.ValidationError(**exception_args)"},{"line_number":667,"context_line":"        else:"},{"line_number":668,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9o0o%3D","line":665,"in_reply_to":"AAAAWH%2F9qNc%3D","updated":"2014-04-03 06:56:33.000000000","message":"removed, as indeed it\u0027s not used for now.","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"1780010454f522b35eb04b72b947b7be5e7d1049","unresolved":false,"context_lines":[{"line_number":662,"context_line":""},{"line_number":663,"context_line":"        if len(missing_args) \u003e 0:"},{"line_number":664,"context_line":"            exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":665,"context_line":"                              \u0027attribute\u0027: \u0027, \u0027.join(missing_args)}"},{"line_number":666,"context_line":"            raise exception.ValidationError(**exception_args)"},{"line_number":667,"context_line":"        else:"},{"line_number":668,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9qNc%3D","line":665,"in_reply_to":"AAAAWH%2F9qOU%3D","updated":"2014-04-03 01:14:01.000000000","message":"this method actually isn\u0027t used at all. Maybe it should just be removed?","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"65b695906eaef8869774ebf08e522b0d1bb1f291","unresolved":false,"context_lines":[{"line_number":662,"context_line":""},{"line_number":663,"context_line":"        if len(missing_args) \u003e 0:"},{"line_number":664,"context_line":"            exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":665,"context_line":"                              \u0027attribute\u0027: \u0027, \u0027.join(missing_args)}"},{"line_number":666,"context_line":"            raise exception.ValidationError(**exception_args)"},{"line_number":667,"context_line":"        else:"},{"line_number":668,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9qOU%3D","line":665,"in_reply_to":"AAAAWH%2F9qT4%3D","updated":"2014-04-03 01:10:35.000000000","message":"I see why the tests don\u0027t fail, it\u0027s because this function is untested: http://logs.openstack.org/d8/d8c0c81d685a4b1b7ab2439bb140a4d3fd7c18c3/post/keystone-coverage/bd52ad1/cover/keystone_common_controller.html#n643","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"a47cdb5a6cb6932167e2147fe682ceb705f992c5","unresolved":false,"context_lines":[{"line_number":662,"context_line":""},{"line_number":663,"context_line":"        if len(missing_args) \u003e 0:"},{"line_number":664,"context_line":"            exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":665,"context_line":"                              \u0027attribute\u0027: \u0027, \u0027.join(missing_args)}"},{"line_number":666,"context_line":"            raise exception.ValidationError(**exception_args)"},{"line_number":667,"context_line":"        else:"},{"line_number":668,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAWH%2F9x48%3D","line":665,"in_reply_to":"AAAAWH%2F9x6w%3D","updated":"2014-04-02 07:41:13.000000000","message":"same as above :-)","commit_id":"13ac0a73ce12f1ccbe06ccf5ba776155becd44c1"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f3222f655a9bf1904038b035c118ea2403e89128","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            return"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"        exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":639,"context_line":"                          \u0027attribute\u0027: blocked_keys.pop()}"},{"line_number":640,"context_line":"        raise exception.ImmutableAttributeError(**exception_args)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F9h60%3D","side":"PARENT","line":639,"updated":"2014-04-03 21:42:47.000000000","message":"Is there a tests for multple blocked keys already?","commit_id":"b803fe85ba53a9c666b9badd0923502fcb5c3b0e"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"36d0153d1cdaaef07d083f73a12a729b1ca615b6","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            return"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"        exception_args \u003d {\u0027target\u0027: cls.__name__,"},{"line_number":639,"context_line":"                          \u0027attribute\u0027: blocked_keys.pop()}"},{"line_number":640,"context_line":"        raise exception.ImmutableAttributeError(**exception_args)"},{"line_number":641,"context_line":""},{"line_number":642,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F9hdc%3D","side":"PARENT","line":639,"in_reply_to":"AAAAWH%2F9h60%3D","updated":"2014-04-03 22:57:45.000000000","message":"in fact, there is: https://github.com/openstack/keystone/blob/master/keystone/tests/test_v3_federation.py#L266 . We are trying to update attributes \u0027id\u0027 and \u0027protocols\u0027 whereas mutable parameters are \u0027description\u0027 and \u0027enabled\u0027 . However, I think to make the test more \u0027generic\u0027 I can change fixed key names to uuids.\nDo you think it should be within the scope of this patch?","commit_id":"b803fe85ba53a9c666b9badd0923502fcb5c3b0e"}],"keystone/exception.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f3222f655a9bf1904038b035c118ea2403e89128","unresolved":false,"context_lines":[{"line_number":176,"context_line":""},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"class ImmutableAttributeError(Forbidden):"},{"line_number":179,"context_line":"    message_format \u003d _(\"Could not change immutable attributes %(attributes)s\""},{"line_number":180,"context_line":"                       \" in target %(target)s\")"},{"line_number":181,"context_line":""},{"line_number":182,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F9h7c%3D","line":179,"updated":"2014-04-03 21:42:47.000000000","message":"I think you may want to put the attributes in some sort of container like \u0027 or (). I think it\u0027ll make it easier to read.\n\n - Could not change immutable attributes attr1 in target t\n - Could not change immutable attributes attr1, attr2 in target t\n vs.\n - Could not change immutable attribute(s) \u0027attr1\u0027 in target t\n - Could not change immutable attribute(s) \u0027attr1, attr2\u0027 in target t","commit_id":"eb663a291cebc77a521b88738c2c4aa88a919442"}],"keystone/tests/test_v3_controller.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"0317166ae1748e2e19efe65bc56da5f6ad44697c","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        super(V3ControllerTestCase, self).setUp()"},{"line_number":33,"context_line":"        self.api \u003d controller.V3Controller()"},{"line_number":34,"context_line":"        controller.V3Controller._mutable_parameters \u003d frozenset("},{"line_number":35,"context_line":"            [\u0027hello\u0027, \u0027world\u0027])"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def test_check_immutabel_params(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F9cVg%3D","line":34,"updated":"2014-04-04 13:53:32.000000000","message":"The bad thing about doing this is that you are leaving state hanging around. Any reason not to just make a subclass here like:\n\ndef setUp(self):\n    super(...).setup()\n    class ControllerUnderTest(controller.V3Controller):\n        _mutable_parameters \u003d frozenset(...)\n    self.api \u003d ControllerUnderTest()","commit_id":"0fa424124c7498b27bbd8517474e1e8d2c4c95fc"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"37460e0b7e7cae192ee7cd3add2e754107a1738a","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        super(V3ControllerTestCase, self).setUp()"},{"line_number":33,"context_line":"        self.api \u003d controller.V3Controller()"},{"line_number":34,"context_line":"        controller.V3Controller._mutable_parameters \u003d frozenset("},{"line_number":35,"context_line":"            [\u0027hello\u0027, \u0027world\u0027])"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def test_check_immutabel_params(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F9cIw%3D","line":34,"in_reply_to":"AAAAWH%2F9cVg%3D","updated":"2014-04-04 14:17:08.000000000","message":"Done","commit_id":"0fa424124c7498b27bbd8517474e1e8d2c4c95fc"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"0317166ae1748e2e19efe65bc56da5f6ad44697c","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        controller.V3Controller._mutable_parameters \u003d frozenset("},{"line_number":35,"context_line":"            [\u0027hello\u0027, \u0027world\u0027])"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def test_check_immutabel_params(self):"},{"line_number":38,"context_line":"        \"\"\"Pass valid parameters to the method and expect no failure."},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F9cXU%3D","line":37,"updated":"2014-04-04 13:53:32.000000000","message":"immutable","commit_id":"0fa424124c7498b27bbd8517474e1e8d2c4c95fc"},{"author":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"change_message_id":"37460e0b7e7cae192ee7cd3add2e754107a1738a","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        controller.V3Controller._mutable_parameters \u003d frozenset("},{"line_number":35,"context_line":"            [\u0027hello\u0027, \u0027world\u0027])"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def test_check_immutabel_params(self):"},{"line_number":38,"context_line":"        \"\"\"Pass valid parameters to the method and expect no failure."},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F9cLg%3D","line":37,"in_reply_to":"AAAAWH%2F9cXU%3D","updated":"2014-04-04 14:17:08.000000000","message":"Done","commit_id":"0fa424124c7498b27bbd8517474e1e8d2c4c95fc"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"11a73b631e6bf74a42cade666959887952ed1e2c","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# -*- coding: utf-8 -*-"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2014 IBM Corp."},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9bj0%3D","line":1,"updated":"2014-04-04 15:16:44.000000000","message":"remove the editor headers","commit_id":"4894352781287f58fa233d2737c2e43a691d48c0"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"11a73b631e6bf74a42cade666959887952ed1e2c","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# -*- coding: utf-8 -*-"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2014 IBM Corp."},{"line_number":4,"context_line":"#"},{"line_number":5,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":6,"context_line":"# not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9bjk%3D","line":3,"updated":"2014-04-04 15:16:44.000000000","message":"remove the IBM header as you work for CERN :)","commit_id":"4894352781287f58fa233d2737c2e43a691d48c0"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"11a73b631e6bf74a42cade666959887952ed1e2c","unresolved":false,"context_lines":[{"line_number":25,"context_line":"class V3ControllerTestCase(tests.TestCase):"},{"line_number":26,"context_line":"    \"\"\"Tests for the V3Controller class."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    These tests exercise :class:`keystone.assignment.controllers.Tenant`."},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    \"\"\""},{"line_number":31,"context_line":"    def setUp(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9bjU%3D","line":28,"updated":"2014-04-04 15:16:44.000000000","message":"this comment seems incorrect","commit_id":"4894352781287f58fa233d2737c2e43a691d48c0"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"11a73b631e6bf74a42cade666959887952ed1e2c","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    def test_check_immutable_params_fail(self):"},{"line_number":50,"context_line":"        \"\"\"Test whether immutable parameters are correctly catched."},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"        \"\"\""},{"line_number":53,"context_line":"        ref \u003d dict([(uuid.uuid4().hex, uuid.uuid4().hex) for _ in range(3)])"},{"line_number":54,"context_line":"        self.assertRaises(exception.ImmutableAttributeError,"},{"line_number":55,"context_line":"                          self.api.check_immutable_params, ref)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F9bic%3D","line":52,"updated":"2014-04-04 15:16:44.000000000","message":"move the \"\u0027s to the line above?","commit_id":"4894352781287f58fa233d2737c2e43a691d48c0"},{"author":{"_account_id":7191,"name":"Jamie Lennox","email":"jamielennox@gmail.com","username":"jamielennox"},"change_message_id":"2777309b8c70f10da6c71c8ecdf228da83ebf6c2","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        \"\"\"Pass invalid parameter to the method and expect failure.\"\"\""},{"line_number":43,"context_line":"        ref \u003d dict([(uuid.uuid4().hex, uuid.uuid4().hex) for _ in range(3)])"},{"line_number":44,"context_line":"        self.assertRaises(exception.ImmutableAttributeError,"},{"line_number":45,"context_line":"                          self.api.check_immutable_params, ref)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F9VP4%3D","line":45,"updated":"2014-04-06 22:22:33.000000000","message":"you should check that the keys in the dictionary are contained in the exception message.\n\n(normally this would be a nit, but this is the change you are making)","commit_id":"b1f2d23a1e41fe4f3c8b634e177fb220b2534ed2"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"4e4da15dab9de1e436d4325a967d444548895f89","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        \"\"\"Pass invalid parameter to the method and expect failure.\"\"\""},{"line_number":43,"context_line":"        ref \u003d dict([(uuid.uuid4().hex, uuid.uuid4().hex) for _ in range(3)])"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"        ref_msg \u003d (\"Could not change immutable attribute(s) \""},{"line_number":46,"context_line":"                   \"\u0027%(attributes)s\u0027 in target %(target)s\")"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"        ref_msg \u003d ref_msg % {\u0027attributes\u0027: \u0027, \u0027.join(ref.keys()),"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAWH%2F9SA8%3D","line":45,"updated":"2014-04-07 12:58:11.000000000","message":"You should be able to get rid of most of this code and do something like:\n\n    # untested\n    ref \u003d dict([(uuid.uuid4().hex, uuid.uuid4().hex) for _ in range(3)])\n\n    ex \u003d self.assertRaises(exception.ImmutableAttributeError,\n                           self.api.check_immutable_params, ref)\n    ex_msg \u003d unicode(ex)\n    self.assertThat(ex_msg, matchers.Contains(self.api.__class__.__name__))\n    for key in ref:\n        self.assertThat(ex_msg, matchers.Contains(key))","commit_id":"8b7323f04a6353c04776b9ddbc656282073df7f2"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"7ab5763b0c17894b9e398f58db6dc6b947a52516","unresolved":false,"context_lines":[{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from testtools import matchers"},{"line_number":16,"context_line":"import uuid"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from keystone.common import controller"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAWH%2F9RAA%3D","line":15,"updated":"2014-04-07 14:47:24.000000000","message":"This is a third party library and should be moved into its own section in between the stdlib section and the keystone section.","commit_id":"028d632cbdb28b18a51f4d7c01d8b55e469624e6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"bba8471aa7ba0ae870db527d12d6002666e4897f","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright 2014 CERN."},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":4,"context_line":"# not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAW3%2F%2F2Bo%3D","line":1,"updated":"2014-04-10 00:57:17.000000000","message":"most of this test works even without the change to the message, so this should be split into a separate commit that the change to the message depends on.","commit_id":"70377885b40cdcefd34833ed2cf5af6aee0e775d"}]}
