)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"811f4b7b8fea09b9d40d32708a5fbd13654a77cf","unresolved":false,"context_lines":[{"line_number":16,"context_line":"in the entry, add the attribute to the object with"},{"line_number":17,"context_line":"a value of None.  Changed and added several tests"},{"line_number":18,"context_line":"to reflect this new behavior."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: I3e1b298ed2d3464212c8daab60af5f01e4981bd0"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"AAAAVn%2F%2FGM0%3D","line":19,"updated":"2014-03-09 21:47:26.000000000","message":"Reference the bug in the commit message -- see https://wiki.openstack.org/wiki/GitCommitMessages#Including_external_references","commit_id":"65a2527f714173b10ca5ebfb533f6f661a7f2953"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"97cc20f3ee7e6760cfc0da73e69eb80a894a3fe7","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"better handling for empty/None ldap values"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When adding an LDAP entry, if there are attributes"},{"line_number":10,"context_line":"with values of None or empty - \u0027\u0027, [], () - just"},{"line_number":11,"context_line":"skip adding the attribute"},{"line_number":12,"context_line":"When modifying an LDAP entry, if the new value is"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":12,"id":"AAAAXH%2F%2Fxp4%3D","line":9,"updated":"2014-04-17 19:54:08.000000000","message":"I think this grouping needs a little cleanup. If nothing else periods at the end of each sentence and maybe a newline between each one or make them a bulleted list. It\u0027s very hard to read.","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When adding an LDAP entry, if there are attributes"},{"line_number":10,"context_line":"with values of None or empty - \u0027\u0027, [], (), {} - just"},{"line_number":11,"context_line":"skip adding the attribute."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"When modifying an LDAP entry, if the new value is"},{"line_number":14,"context_line":"None or empty, just delete the attribute from LDAP."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"7adec928_dc17a6ec","line":11,"updated":"2014-05-18 15:36:36.000000000","message":"If the entry\u0027s objectclass requires the attribute to be present then adding the entry will now fail.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"b9671dd43e40eab842c67170e2c8e85458e5a02d","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When adding an LDAP entry, if there are attributes"},{"line_number":10,"context_line":"with values of None or empty - \u0027\u0027, [], (), {} - just"},{"line_number":11,"context_line":"skip adding the attribute."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"When modifying an LDAP entry, if the new value is"},{"line_number":14,"context_line":"None or empty, just delete the attribute from LDAP."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"7adec928_f26a7080","line":11,"in_reply_to":"7adec928_dc17a6ec","updated":"2014-05-20 17:54:53.000000000","message":"\"now fail\", as opposed to how it is currently handled?\nWhat about when Keystone is used with an SQL backend, with columns which use the SQL NOT NULL constraint?  How is an attempt to add an entry/row handled, when there is a property missing which corresponds to a NOT NULL column?","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":11,"context_line":"skip adding the attribute."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"When modifying an LDAP entry, if the new value is"},{"line_number":14,"context_line":"None or empty, just delete the attribute from LDAP."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"When reading an LDAP entry, if the entry is missing"},{"line_number":17,"context_line":"attributes that a client expects should be present"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"7adec928_9ce8bee3","line":14,"updated":"2014-05-18 15:36:36.000000000","message":"If the entry\u0027s objectclass requires the attribute to be present then the mod will fail.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":14,"context_line":"None or empty, just delete the attribute from LDAP."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"When reading an LDAP entry, if the entry is missing"},{"line_number":17,"context_line":"attributes that a client expects should be present"},{"line_number":18,"context_line":"in the entry, add the attribute to the object with"},{"line_number":19,"context_line":"a value of None."},{"line_number":20,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"7adec928_fceb82d9","line":17,"updated":"2014-05-18 15:36:36.000000000","message":"How does the server know what the client expects to be present?","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"b9671dd43e40eab842c67170e2c8e85458e5a02d","unresolved":false,"context_lines":[{"line_number":14,"context_line":"None or empty, just delete the attribute from LDAP."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"When reading an LDAP entry, if the entry is missing"},{"line_number":17,"context_line":"attributes that a client expects should be present"},{"line_number":18,"context_line":"in the entry, add the attribute to the object with"},{"line_number":19,"context_line":"a value of None."},{"line_number":20,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"7adec928_12c43c5e","line":17,"in_reply_to":"7adec928_fceb82d9","updated":"2014-05-20 17:54:53.000000000","message":"This is the list of properties/attributes specified in attribute_options_names or in the config in $object_additional_attribute_mapping.  For example, in ProjectApi.attribute_options_names this is name, description, enabled, domain_id","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":19,"context_line":"a value of None."},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Several tests were added and changed to reflect"},{"line_number":22,"context_line":"this new behavior."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"Change-Id: I3e1b298ed2d3464212c8daab60af5f01e4981bd0"},{"line_number":25,"context_line":"Closes-Bug: #1282676"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"7adec928_1cbcaedb","line":22,"updated":"2014-05-18 15:36:36.000000000","message":"Remove this since it\u0027s implied.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"}],"etc/keystone.conf.sample":[{"author":{"_account_id":7186,"name":"Matthieu Huin","email":"mhuin@redhat.com","username":"mhu"},"change_message_id":"1224c7726bcb69b6dad68e4155778480aa454d2c","unresolved":false,"context_lines":[{"line_number":919,"context_line":"# format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where ldap_attr is the"},{"line_number":920,"context_line":"# attribute in the LDAP entry and user_attr is the Identity"},{"line_number":921,"context_line":"# API attribute. (list value)"},{"line_number":922,"context_line":"#user_additional_attribute_mapping\u003ddescription:description"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"# Search base for projects (string value)"},{"line_number":925,"context_line":"#tenant_tree_dn\u003d\u003cNone\u003e"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"AAAAWH%2F%2Bm8Y%3D","line":922,"updated":"2014-03-25 15:52:11.000000000","message":"why isn\u0027t it set like tenants, see line 944 : tenant_desc_attribute ?","commit_id":"b11a84decef2deb9ed179c5ee6c6b097dcead75f"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"b7022bdbb7d681ab7a5da7c06d12f191e67cde75","unresolved":false,"context_lines":[{"line_number":919,"context_line":"# format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where ldap_attr is the"},{"line_number":920,"context_line":"# attribute in the LDAP entry and user_attr is the Identity"},{"line_number":921,"context_line":"# API attribute. (list value)"},{"line_number":922,"context_line":"#user_additional_attribute_mapping\u003ddescription:description"},{"line_number":923,"context_line":""},{"line_number":924,"context_line":"# Search base for projects (string value)"},{"line_number":925,"context_line":"#tenant_tree_dn\u003d\u003cNone\u003e"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"AAAAWH%2F92P0%3D","line":922,"in_reply_to":"AAAAWH%2F%2Bm8Y%3D","updated":"2014-04-01 17:29:01.000000000","message":"I had it that way originally, but was told to use the user_additional_attribute_mapping instead.","commit_id":"b11a84decef2deb9ed179c5ee6c6b097dcead75f"}],"keystone/assignment/backends/ldap.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        data \u003d tenant.copy()"},{"line_number":73,"context_line":"        if \u0027id\u0027 not in data or data[\u0027id\u0027] is None:"},{"line_number":74,"context_line":"            data[\u0027id\u0027] \u003d str(uuid.uuid4().hex)"},{"line_number":75,"context_line":"        if \u0027description\u0027 in data and data[\u0027description\u0027] in [\u0027\u0027, None]:"},{"line_number":76,"context_line":"            data.pop(\u0027description\u0027)"},{"line_number":77,"context_line":"        return self._set_default_domain(self.project.create(data))"},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_7cb772f5","side":"PARENT","line":75,"updated":"2014-05-18 15:36:36.000000000","message":"I wonder why the server was handling this one.","commit_id":"820e4f153aa12f9686a98fcae309636216666909"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"e8c5b9796be8c70f8d94cb3062708150a9c64238","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        data \u003d tenant.copy()"},{"line_number":73,"context_line":"        if \u0027id\u0027 not in data or data[\u0027id\u0027] is None:"},{"line_number":74,"context_line":"            data[\u0027id\u0027] \u003d str(uuid.uuid4().hex)"},{"line_number":75,"context_line":"        if \u0027description\u0027 in data and data[\u0027description\u0027] in [\u0027\u0027, None]:"},{"line_number":76,"context_line":"            data.pop(\u0027description\u0027)"},{"line_number":77,"context_line":"        return self._set_default_domain(self.project.create(data))"},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"baada198_f08896c8","side":"PARENT","line":75,"in_reply_to":"1ae5cdf2_e28632b8","updated":"2014-06-30 23:35:22.000000000","message":"I believe my fix is cleaner - instead of having a special case for this particular attribute at this place in the code, the handling for all LDAP attributes is centralized.","commit_id":"820e4f153aa12f9686a98fcae309636216666909"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"b9671dd43e40eab842c67170e2c8e85458e5a02d","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        data \u003d tenant.copy()"},{"line_number":73,"context_line":"        if \u0027id\u0027 not in data or data[\u0027id\u0027] is None:"},{"line_number":74,"context_line":"            data[\u0027id\u0027] \u003d str(uuid.uuid4().hex)"},{"line_number":75,"context_line":"        if \u0027description\u0027 in data and data[\u0027description\u0027] in [\u0027\u0027, None]:"},{"line_number":76,"context_line":"            data.pop(\u0027description\u0027)"},{"line_number":77,"context_line":"        return self._set_default_domain(self.project.create(data))"},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_87b80ce7","side":"PARENT","line":75,"in_reply_to":"7adec928_7cb772f5","updated":"2014-05-20 17:54:53.000000000","message":"This was from commit fafdf072f5a34ee12ffe9d7651551c83459759bb by Adam.  Adam, I\u0027m assuming this was added because adding an empty or None description was causing failures.","commit_id":"820e4f153aa12f9686a98fcae309636216666909"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"44aafdcbcd2c55cfcc3e9338354147830cbb7d37","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        data \u003d tenant.copy()"},{"line_number":73,"context_line":"        if \u0027id\u0027 not in data or data[\u0027id\u0027] is None:"},{"line_number":74,"context_line":"            data[\u0027id\u0027] \u003d str(uuid.uuid4().hex)"},{"line_number":75,"context_line":"        if \u0027description\u0027 in data and data[\u0027description\u0027] in [\u0027\u0027, None]:"},{"line_number":76,"context_line":"            data.pop(\u0027description\u0027)"},{"line_number":77,"context_line":"        return self._set_default_domain(self.project.create(data))"},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_e28632b8","side":"PARENT","line":75,"in_reply_to":"7adec928_87b80ce7","updated":"2014-06-06 07:56:31.000000000","message":"Yes, some fields in LDAP (not all) couldn\u0027t be empty or None. This check was added to escape follow unclear exception:\n\n INVALID_SYNTAX: {\u0027info\u0027: \u0027description: value #0 invalid per syntax\u0027, \u0027desc\u0027: \u0027Invalid syntax\u0027}","commit_id":"820e4f153aa12f9686a98fcae309636216666909"}],"keystone/assignment/core.py":[{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"ac6cd6d0166350ec49900cfa5750ea081dd0e30b","unresolved":false,"context_lines":[{"line_number":934,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":935,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":936,"context_line":"        if isinstance(ref, dict):"},{"line_number":937,"context_line":"            if \u0027domain_id\u0027 not in ref or ref[\u0027domain_id\u0027] is None:"},{"line_number":938,"context_line":"                ref \u003d ref.copy()"},{"line_number":939,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"},{"line_number":940,"context_line":"            return ref"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAVn%2F%2FiGc%3D","line":937,"updated":"2014-03-05 15:32:39.000000000","message":"if ref.get(\u0027domain_id\u0027) is None:","commit_id":"27b51c13adf871cac2bf749cf98de68dee4aedd1"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"72e5e385bdec8333268f34bc06793d8b59961e2b","unresolved":false,"context_lines":[{"line_number":994,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":995,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":996,"context_line":"        if isinstance(ref, dict):"},{"line_number":997,"context_line":"            if \u0027domain_id\u0027 not in ref or ref[\u0027domain_id\u0027] is None:"},{"line_number":998,"context_line":"                ref \u003d ref.copy()"},{"line_number":999,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"},{"line_number":1000,"context_line":"            return ref"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2B3LM%3D","line":997,"updated":"2014-03-22 15:48:53.000000000","message":"this looks like it\u0027s fixing a bigger bug, suggest put it in a separate commit.","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"e61a177d8892a96946d08a2c19ce7383f9e2714c","unresolved":false,"context_lines":[{"line_number":994,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":995,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":996,"context_line":"        if isinstance(ref, dict):"},{"line_number":997,"context_line":"            if \u0027domain_id\u0027 not in ref or ref[\u0027domain_id\u0027] is None:"},{"line_number":998,"context_line":"                ref \u003d ref.copy()"},{"line_number":999,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"},{"line_number":1000,"context_line":"            return ref"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2BsoQ%3D","line":997,"in_reply_to":"AAAAWH%2F%2B3LM%3D","updated":"2014-03-25 00:31:42.000000000","message":"It is a direct consequence of \u0027domain_id\u0027 being in the attribute_options_name list in ProjectApi.  This is the list that the LDAP backend uses to determine if the property must always be present in the object, even if the attribute does not exist in LDAP.  If the attribute does not exist in LDAP, and the name is in that list, the ldap backend adds the property to the object with a None value.","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"97cc20f3ee7e6760cfc0da73e69eb80a894a3fe7","unresolved":false,"context_lines":[{"line_number":995,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":996,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":997,"context_line":"        if isinstance(ref, dict):"},{"line_number":998,"context_line":"            if \u0027domain_id\u0027 not in ref or ref[\u0027domain_id\u0027] is None:"},{"line_number":999,"context_line":"                ref \u003d ref.copy()"},{"line_number":1000,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"},{"line_number":1001,"context_line":"            return ref"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAXH%2F%2Fvyg%3D","line":998,"updated":"2014-04-17 19:54:08.000000000","message":"Is there any reason to not use the new is_empty method instead of just checking against None?","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6ed3de5e7e5e4110b54b031a50a594f679376bf2","unresolved":false,"context_lines":[{"line_number":996,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":997,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":998,"context_line":"        if isinstance(ref, dict):"},{"line_number":999,"context_line":"            if \u0027domain_id\u0027 not in ref or \\"},{"line_number":1000,"context_line":"                    ldap.core.BaseLdap.is_empty(ref[\u0027domain_id\u0027]):"},{"line_number":1001,"context_line":"                ref \u003d ref.copy()"},{"line_number":1002,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAXH%2F%2FugA%3D","line":999,"updated":"2014-04-17 21:38:25.000000000","message":"(nit) instead of line continuation you should use parens.","commit_id":"7b4e1950b384ebba457096c4d3490a35bc43a653"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f19ee6c9044b2ab5d4ed6c238311e358e0c74ea2","unresolved":false,"context_lines":[{"line_number":996,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":997,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":998,"context_line":"        if isinstance(ref, dict):"},{"line_number":999,"context_line":"            if \u0027domain_id\u0027 not in ref or \\"},{"line_number":1000,"context_line":"                    ldap.core.BaseLdap.is_empty(ref[\u0027domain_id\u0027]):"},{"line_number":1001,"context_line":"                ref \u003d ref.copy()"},{"line_number":1002,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAXH%2F%2FuWo%3D","line":999,"in_reply_to":"AAAAXH%2F%2Fubg%3D","updated":"2014-04-17 21:55:11.000000000","message":"That would work for me.","commit_id":"7b4e1950b384ebba457096c4d3490a35bc43a653"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"e4256d7698869edb832ef560098dede97078f3a0","unresolved":false,"context_lines":[{"line_number":996,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":997,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":998,"context_line":"        if isinstance(ref, dict):"},{"line_number":999,"context_line":"            if \u0027domain_id\u0027 not in ref or \\"},{"line_number":1000,"context_line":"                    ldap.core.BaseLdap.is_empty(ref[\u0027domain_id\u0027]):"},{"line_number":1001,"context_line":"                ref \u003d ref.copy()"},{"line_number":1002,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAXH%2F%2Fud0%3D","line":999,"in_reply_to":"AAAAXH%2F%2FugA%3D","updated":"2014-04-17 21:44:14.000000000","message":"++","commit_id":"7b4e1950b384ebba457096c4d3490a35bc43a653"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"7ddc782832193e810b34d269853c99d87777439a","unresolved":false,"context_lines":[{"line_number":996,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":997,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":998,"context_line":"        if isinstance(ref, dict):"},{"line_number":999,"context_line":"            if \u0027domain_id\u0027 not in ref or \\"},{"line_number":1000,"context_line":"                    ldap.core.BaseLdap.is_empty(ref[\u0027domain_id\u0027]):"},{"line_number":1001,"context_line":"                ref \u003d ref.copy()"},{"line_number":1002,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAXH%2F%2Fubg%3D","line":999,"in_reply_to":"AAAAXH%2F%2FugA%3D","updated":"2014-04-17 21:49:18.000000000","message":"Like this?\n            if ((\u0027domain_id\u0027 not in ref) or\n                ldap.core.BaseLdap.is_empty(ref[\u0027domain_id\u0027])):\n?","commit_id":"7b4e1950b384ebba457096c4d3490a35bc43a653"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"d00f178546d34d12a926326a2ea8465d34ba5910","unresolved":false,"context_lines":[{"line_number":996,"context_line":"    def _set_default_domain(self, ref):"},{"line_number":997,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":998,"context_line":"        if isinstance(ref, dict):"},{"line_number":999,"context_line":"            if ((\u0027domain_id\u0027 not in ref) or"},{"line_number":1000,"context_line":"                    ldap.core.BaseLdap.is_empty(ref[\u0027domain_id\u0027])):"},{"line_number":1001,"context_line":"                ref \u003d ref.copy()"},{"line_number":1002,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"}],"source_content_type":"text/x-python","patch_set":16,"id":"9ad9bd40_7ad0eb53","line":999,"updated":"2014-04-30 14:12:36.000000000","message":"I think we need not brackets here:\n\n (\u0027domain id\u0027 not in ref)","commit_id":"f5491713d3e087368cba0a8722e264044f756a6d"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"c75ab6ad698c1f0acc6916121674a128ad674475","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from keystone.common import cache"},{"line_number":23,"context_line":"from keystone.common import dependency"},{"line_number":24,"context_line":"from keystone.common import driver_hints"},{"line_number":25,"context_line":"from keystone.common import ldap"},{"line_number":26,"context_line":"from keystone.common import manager"},{"line_number":27,"context_line":"from keystone import config"},{"line_number":28,"context_line":"from keystone import exception"}],"source_content_type":"text/x-python","patch_set":17,"id":"7adec928_00513462","line":25,"updated":"2014-05-08 01:15:27.000000000","message":"I believe that this is causing your tempest test failures.  This will indirectly require python-ldap to be installed, even when LDAP is not actually being used.  It seems that python-ldap isn\u0027t installed when tempest sets up devstack, so the tests fail with import errors.\n\nDo we really need to call the keystone.common.ldap code from here?  It seems like it would be better to contain anything that would load python-ldap to code that is only used when LDAP is actually configured.  I think is_empty() needs to be put somewhere outside of keystone.common.ldap if it is truly general purpose.","commit_id":"201222c54c6adf89695c91aba8a81840a362e3d9"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":997,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":998,"context_line":"        if isinstance(ref, dict):"},{"line_number":999,"context_line":"            if (\u0027domain_id\u0027 not in ref or"},{"line_number":1000,"context_line":"                    utils.is_empty(ref[\u0027domain_id\u0027])):"},{"line_number":1001,"context_line":"                ref \u003d ref.copy()"},{"line_number":1002,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"},{"line_number":1003,"context_line":"            return ref"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_bccc9a8a","line":1000,"updated":"2014-05-18 15:36:36.000000000","message":"If someone sends in an empty string for domain_id the server shouldn\u0027t change it to the default domain id.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"e8c5b9796be8c70f8d94cb3062708150a9c64238","unresolved":false,"context_lines":[{"line_number":997,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":998,"context_line":"        if isinstance(ref, dict):"},{"line_number":999,"context_line":"            if (\u0027domain_id\u0027 not in ref or"},{"line_number":1000,"context_line":"                    utils.is_empty(ref[\u0027domain_id\u0027])):"},{"line_number":1001,"context_line":"                ref \u003d ref.copy()"},{"line_number":1002,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"},{"line_number":1003,"context_line":"            return ref"}],"source_content_type":"text/x-python","patch_set":18,"id":"baada198_90c11ae7","line":1000,"in_reply_to":"7adec928_6798606b","updated":"2014-06-30 23:35:22.000000000","message":"Please respond - I would like some guidance on this issue.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"b9671dd43e40eab842c67170e2c8e85458e5a02d","unresolved":false,"context_lines":[{"line_number":997,"context_line":"        \"\"\"If the domain ID has not been set, set it to the default.\"\"\""},{"line_number":998,"context_line":"        if isinstance(ref, dict):"},{"line_number":999,"context_line":"            if (\u0027domain_id\u0027 not in ref or"},{"line_number":1000,"context_line":"                    utils.is_empty(ref[\u0027domain_id\u0027])):"},{"line_number":1001,"context_line":"                ref \u003d ref.copy()"},{"line_number":1002,"context_line":"                ref[\u0027domain_id\u0027] \u003d CONF.identity.default_domain_id"},{"line_number":1003,"context_line":"            return ref"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_6798606b","line":1000,"in_reply_to":"7adec928_bccc9a8a","updated":"2014-05-20 17:54:53.000000000","message":"What about a value of None?  When using the DB (as opposed to LDAP) backend, what is stored for an empty or None domain_id?\nOr, is this a value that is not stored?","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"}],"keystone/common/config.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"811f4b7b8fea09b9d40d32708a5fbd13654a77cf","unresolved":false,"context_lines":[{"line_number":398,"context_line":"        cfg.IntOpt(\u0027user_enabled_mask\u0027, default\u003d0),"},{"line_number":399,"context_line":"        cfg.StrOpt(\u0027user_enabled_default\u0027, default\u003d\u0027True\u0027),"},{"line_number":400,"context_line":"        cfg.StrOpt(\u0027user_description_attribute\u0027, default\u003d\u0027description\u0027,"},{"line_number":401,"context_line":"                   help\u003d\u0027LDAP attribute mapped to the user description\u0027),"},{"line_number":402,"context_line":"        cfg.ListOpt(\u0027user_attribute_ignore\u0027,"},{"line_number":403,"context_line":"                    default\u003d[\u0027default_project_id\u0027, \u0027tenants\u0027],"},{"line_number":404,"context_line":"                    help\u003d\u0027List of attributes stripped off the user on update\u0027),"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAVn%2F%2FGMY%3D","line":401,"updated":"2014-03-09 21:47:26.000000000","message":"we\u0027ve already got user_additional_attribute_mapping so we don\u0027t need to add all of these separately.","commit_id":"65a2527f714173b10ca5ebfb533f6f661a7f2953"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"72e5e385bdec8333268f34bc06793d8b59961e2b","unresolved":false,"context_lines":[{"line_number":469,"context_line":"                   help\u003d\u0027DN of the group entry to hold enabled users when \u0027"},{"line_number":470,"context_line":"                        \u0027using enabled emulation.\u0027),"},{"line_number":471,"context_line":"        cfg.ListOpt(\u0027user_additional_attribute_mapping\u0027,"},{"line_number":472,"context_line":"                    default\u003d[\u0027description:description\u0027],"},{"line_number":473,"context_line":"                    help\u003d\u0027List of additional LDAP attributes used for mapping \u0027"},{"line_number":474,"context_line":"                         \u0027Additional attribute mappings for users. Attribute \u0027"},{"line_number":475,"context_line":"                         \u0027mapping format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where \u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2B3LI%3D","line":472,"updated":"2014-03-22 15:48:53.000000000","message":"seems like a bad idea to change the default... for somebody using the default before it wouldn\u0027t work anymore.","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"e61a177d8892a96946d08a2c19ce7383f9e2714c","unresolved":false,"context_lines":[{"line_number":469,"context_line":"                   help\u003d\u0027DN of the group entry to hold enabled users when \u0027"},{"line_number":470,"context_line":"                        \u0027using enabled emulation.\u0027),"},{"line_number":471,"context_line":"        cfg.ListOpt(\u0027user_additional_attribute_mapping\u0027,"},{"line_number":472,"context_line":"                    default\u003d[\u0027description:description\u0027],"},{"line_number":473,"context_line":"                    help\u003d\u0027List of additional LDAP attributes used for mapping \u0027"},{"line_number":474,"context_line":"                         \u0027Additional attribute mappings for users. Attribute \u0027"},{"line_number":475,"context_line":"                         \u0027mapping format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where \u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2BuLI%3D","line":472,"in_reply_to":"AAAAWH%2F%2B3LI%3D","updated":"2014-03-25 00:31:42.000000000","message":"I can\u0027t add description as another user attribute e.g. user_description_attribute.  I can\u0027t add it to the additional attributes.  How should I denote, in the User object, that the description attribute should always be present, and may not be None when using LDAP?","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":496,"context_line":"                   help\u003d\u0027DN of the group entry to hold enabled users when \u0027"},{"line_number":497,"context_line":"                        \u0027using enabled emulation.\u0027),"},{"line_number":498,"context_line":"        cfg.ListOpt(\u0027user_additional_attribute_mapping\u0027,"},{"line_number":499,"context_line":"                    default\u003d[\u0027description:description\u0027],"},{"line_number":500,"context_line":"                    help\u003d\u0027List of additional LDAP attributes used for mapping \u0027"},{"line_number":501,"context_line":"                         \u0027additional attribute mappings for users. Attribute \u0027"},{"line_number":502,"context_line":"                         \u0027mapping format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where \u0027"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_dcc5e65c","line":499,"updated":"2014-05-18 15:36:36.000000000","message":"revert this change. We can\u0027t change the default since this could cause a problem for an existing deployment. Also, this isn\u0027t mentioned in the commit message, and I don\u0027t see how it\u0027s required to fix the problem.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"e8c5b9796be8c70f8d94cb3062708150a9c64238","unresolved":false,"context_lines":[{"line_number":496,"context_line":"                   help\u003d\u0027DN of the group entry to hold enabled users when \u0027"},{"line_number":497,"context_line":"                        \u0027using enabled emulation.\u0027),"},{"line_number":498,"context_line":"        cfg.ListOpt(\u0027user_additional_attribute_mapping\u0027,"},{"line_number":499,"context_line":"                    default\u003d[\u0027description:description\u0027],"},{"line_number":500,"context_line":"                    help\u003d\u0027List of additional LDAP attributes used for mapping \u0027"},{"line_number":501,"context_line":"                         \u0027additional attribute mappings for users. Attribute \u0027"},{"line_number":502,"context_line":"                         \u0027mapping format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where \u0027"}],"source_content_type":"text/x-python","patch_set":18,"id":"baada198_904f5a92","line":499,"in_reply_to":"7adec928_c7ccd464","updated":"2014-06-30 23:35:22.000000000","message":"Please respond - I would like some guidance on this issue.  Should I use my earlier change, which added description to the default attribute list attribute_options_names in identity.backends.ldap.UserApi ?","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"b9671dd43e40eab842c67170e2c8e85458e5a02d","unresolved":false,"context_lines":[{"line_number":496,"context_line":"                   help\u003d\u0027DN of the group entry to hold enabled users when \u0027"},{"line_number":497,"context_line":"                        \u0027using enabled emulation.\u0027),"},{"line_number":498,"context_line":"        cfg.ListOpt(\u0027user_additional_attribute_mapping\u0027,"},{"line_number":499,"context_line":"                    default\u003d[\u0027description:description\u0027],"},{"line_number":500,"context_line":"                    help\u003d\u0027List of additional LDAP attributes used for mapping \u0027"},{"line_number":501,"context_line":"                         \u0027additional attribute mappings for users. Attribute \u0027"},{"line_number":502,"context_line":"                         \u0027mapping format is \u003cldap_attr\u003e:\u003cuser_attr\u003e, where \u0027"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_c7ccd464","line":499,"in_reply_to":"7adec928_dcc5e65c","updated":"2014-05-20 17:54:53.000000000","message":"Description is used elsewhere in the code as a property of user objects, but is not explicitly specified in UserApi.attribute_options_names.  It is the list of properties in attribute_options_names that is used to determine which properties to fill in with None as the value if the corresponding attribute is not present in the LDAP entry.\nSomewhere among one of the comments for the 17 other reviews, a commenter suggested that I could not add description to UserApi.attribute_options_names, and that instead I should add it to user_additional_attribute_mapping.  I\u0027m not sure how to easily search through all of these reviews to find that comment.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"}],"keystone/common/ldap/core.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"811f4b7b8fea09b9d40d32708a5fbd13654a77cf","unresolved":false,"context_lines":[{"line_number":279,"context_line":"        # a value of 0 or False is not empty"},{"line_number":280,"context_line":"        ret \u003d False"},{"line_number":281,"context_line":"        if v is None:"},{"line_number":282,"context_line":"            ret \u003d True"},{"line_number":283,"context_line":"        else:"},{"line_number":284,"context_line":"            try:"},{"line_number":285,"context_line":"                ret \u003d (len(v) \u003d\u003d 0)"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAVn%2F%2FGMM%3D","line":282,"updated":"2014-03-09 21:47:26.000000000","message":"just return then don\u0027t need to keep a ret variable.","commit_id":"65a2527f714173b10ca5ebfb533f6f661a7f2953"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"08900817d89c66ffa90f2442c74c3e243e742bb8","unresolved":false,"context_lines":[{"line_number":274,"context_line":"            return self._id_to_dn_string(object_id)"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @staticmethod"},{"line_number":277,"context_line":"    def isempty(v):"},{"line_number":278,"context_line":"        # we can\u0027t just return if v: -"},{"line_number":279,"context_line":"        # a value of 0 or False is not empty"},{"line_number":280,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2Fd%2Bc%3D","line":277,"updated":"2014-03-17 18:18:56.000000000","message":"is_empty","commit_id":"72ed34e2e477d455a9387a13c20b48e7e4f9e03c"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"08900817d89c66ffa90f2442c74c3e243e742bb8","unresolved":false,"context_lines":[{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @staticmethod"},{"line_number":277,"context_line":"    def isempty(v):"},{"line_number":278,"context_line":"        # we can\u0027t just return if v: -"},{"line_number":279,"context_line":"        # a value of 0 or False is not empty"},{"line_number":280,"context_line":"        try:"},{"line_number":281,"context_line":"            if v is None or (len(v) \u003d\u003d 0):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2Fd%2B8%3D","line":278,"updated":"2014-03-17 18:18:56.000000000","message":"of?","commit_id":"72ed34e2e477d455a9387a13c20b48e7e4f9e03c"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"08900817d89c66ffa90f2442c74c3e243e742bb8","unresolved":false,"context_lines":[{"line_number":365,"context_line":"                for attr in extra_attrs:"},{"line_number":366,"context_line":"                    attrs.append((attr, [v]))"},{"line_number":367,"context_line":"            else:"},{"line_number":368,"context_line":"                LOG.debug(_(\u0027skipping attribute with empty value: %s\u0027), k)"},{"line_number":369,"context_line":"                continue"},{"line_number":370,"context_line":""},{"line_number":371,"context_line":"        if \u0027groupOfNames\u0027 in object_classes and self.use_dumb_member:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2Fd8Q%3D","line":368,"updated":"2014-03-17 18:18:56.000000000","message":"use the exact same string on both debug statements so that you\u0027re not introducing two string translations for the same thing","commit_id":"72ed34e2e477d455a9387a13c20b48e7e4f9e03c"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"08900817d89c66ffa90f2442c74c3e243e742bb8","unresolved":false,"context_lines":[{"line_number":457,"context_line":"                                    self.attribute_mapping.get(k, k),"},{"line_number":458,"context_line":"                                    None))"},{"line_number":459,"context_line":"                else:"},{"line_number":460,"context_line":"                    LOG.debug(_(\u0027Skipping empty value for attribute %s\u0027), k)"},{"line_number":461,"context_line":"                continue"},{"line_number":462,"context_line":""},{"line_number":463,"context_line":"            current_value \u003d old_obj.get(k)"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2Fd8E%3D","line":460,"updated":"2014-03-17 18:18:56.000000000","message":"compare to above","commit_id":"72ed34e2e477d455a9387a13c20b48e7e4f9e03c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"72e5e385bdec8333268f34bc06793d8b59961e2b","unresolved":false,"context_lines":[{"line_number":275,"context_line":""},{"line_number":276,"context_line":"    @staticmethod"},{"line_number":277,"context_line":"    def is_empty(v):"},{"line_number":278,"context_line":"        # we can\u0027t just return the value of the expression"},{"line_number":279,"context_line":"        # if v:"},{"line_number":280,"context_line":"        # because a value of 0 or False is not empty"},{"line_number":281,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2B3LA%3D","line":278,"updated":"2014-03-22 15:48:53.000000000","message":"suggest document the function with a docstring.","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"72e5e385bdec8333268f34bc06793d8b59961e2b","unresolved":false,"context_lines":[{"line_number":356,"context_line":"        for k, v in six.iteritems(values):"},{"line_number":357,"context_line":"            if k \u003d\u003d \u0027id\u0027 or k in self.attribute_ignore:"},{"line_number":358,"context_line":"                continue"},{"line_number":359,"context_line":"            if not self.is_empty(v):"},{"line_number":360,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":361,"context_line":"                if attr_type is not None:"},{"line_number":362,"context_line":"                    attrs.append((attr_type, [v]))"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2B3K4%3D","line":359,"updated":"2014-03-22 15:48:53.000000000","message":"suggest change this to a positive test rather than a negative one...\n\n if self.is_empty(v):\n    LOG.debug(_(\u0027Skipping empty value for attribute %s\u0027), k)\n    continue","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":822,"context_line":"                v \u003d lower_res[self.attribute_mapping.get(k, k).lower()]"},{"line_number":823,"context_line":"            except KeyError:"},{"line_number":824,"context_line":"                # if expected attribute is missing, and it is"},{"line_number":825,"context_line":"                # an attribute we know about, set value to None"},{"line_number":826,"context_line":"                if k in self.attribute_mapping:"},{"line_number":827,"context_line":"                    obj[k] \u003d None"},{"line_number":828,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_fcc2a251","line":825,"updated":"2014-05-18 15:36:36.000000000","message":"This is repeating what the next couple of lines do. The comment should explain why instead.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":878,"context_line":"            if k \u003d\u003d \u0027id\u0027 or k in self.attribute_ignore:"},{"line_number":879,"context_line":"                continue"},{"line_number":880,"context_line":"            if utils.is_empty(v):"},{"line_number":881,"context_line":"                LOG.debug(_(\u0027Skipping empty value for attribute %s\u0027), k)"},{"line_number":882,"context_line":"                continue"},{"line_number":883,"context_line":"            else:"},{"line_number":884,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_5ca9d68e","line":881,"updated":"2014-05-18 15:36:36.000000000","message":"log guidelines say don\u0027t translate debug logs. Remove _()","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":880,"context_line":"            if utils.is_empty(v):"},{"line_number":881,"context_line":"                LOG.debug(_(\u0027Skipping empty value for attribute %s\u0027), k)"},{"line_number":882,"context_line":"                continue"},{"line_number":883,"context_line":"            else:"},{"line_number":884,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":885,"context_line":"                if attr_type is not None:"},{"line_number":886,"context_line":"                    attrs.append((attr_type, [v]))"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_7cae9299","line":883,"updated":"2014-05-18 15:36:36.000000000","message":"since continued could unindent the next lines rather than use else here. Alternatively, use elif at line 880 for consistency.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"44aafdcbcd2c55cfcc3e9338354147830cbb7d37","unresolved":false,"context_lines":[{"line_number":880,"context_line":"            if utils.is_empty(v):"},{"line_number":881,"context_line":"                LOG.debug(_(\u0027Skipping empty value for attribute %s\u0027), k)"},{"line_number":882,"context_line":"                continue"},{"line_number":883,"context_line":"            else:"},{"line_number":884,"context_line":"                attr_type \u003d self.attribute_mapping.get(k, k)"},{"line_number":885,"context_line":"                if attr_type is not None:"},{"line_number":886,"context_line":"                    attrs.append((attr_type, [v]))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1ae5cdf2_e2f55283","line":883,"in_reply_to":"7adec928_7cae9299","updated":"2014-06-06 07:56:31.000000000","message":"+","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":997,"context_line":"                    modlist.append((ldap.MOD_DELETE,"},{"line_number":998,"context_line":"                                    self.attribute_mapping.get(k, k),"},{"line_number":999,"context_line":"                                    None))"},{"line_number":1000,"context_line":"                else:"},{"line_number":1001,"context_line":"                    LOG.debug(_(\u0027Skipping empty value for attribute %s\u0027), k)"},{"line_number":1002,"context_line":"                continue"},{"line_number":1003,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_fc99c279","line":1000,"updated":"2014-05-18 15:36:36.000000000","message":"There should be a check right after the \"attribute value has not changed\" check - \"if utils.is_empty(v) and utils.is_empty(old_obj.get(k)): continue\". Otherwise a non-change could get caught by the \"changing an immutable\" check at line 990.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":998,"context_line":"                                    self.attribute_mapping.get(k, k),"},{"line_number":999,"context_line":"                                    None))"},{"line_number":1000,"context_line":"                else:"},{"line_number":1001,"context_line":"                    LOG.debug(_(\u0027Skipping empty value for attribute %s\u0027), k)"},{"line_number":1002,"context_line":"                continue"},{"line_number":1003,"context_line":""},{"line_number":1004,"context_line":"            current_value \u003d old_obj.get(k)"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_9c96fe4a","line":1001,"updated":"2014-05-18 15:36:36.000000000","message":"log guidelines say don\u0027t translate debug logs. Remove _()","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"88aa589a3a698fa11ad595a0a1df7170443bffb6","unresolved":false,"context_lines":[{"line_number":17,"context_line":"import re"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import codecs"},{"line_number":20,"context_line":"import ldap"},{"line_number":21,"context_line":"import ldap.filter"},{"line_number":22,"context_line":"import six"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_d3a73807","side":"PARENT","line":20,"updated":"2014-08-12 14:41:42.000000000","message":"Isn\u0027t this being used in the module still?","commit_id":"fac022a55074ebf6bc6356e47cbbb88dc4e55d04"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"7723a8e9f88f21aa957b6751e843f9124ed19f75","unresolved":false,"context_lines":[{"line_number":17,"context_line":"import re"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"import codecs"},{"line_number":20,"context_line":"import ldap"},{"line_number":21,"context_line":"import ldap.filter"},{"line_number":22,"context_line":"import six"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"7ac7a964_d42b78e9","side":"PARENT","line":20,"in_reply_to":"baada198_d3a73807","updated":"2014-08-19 14:20:42.000000000","message":"Importing \u0027ldap.filter\u0027 will also import the \u0027ldap\u0027 name as a side effect. So the explicit import is not needed.","commit_id":"fac022a55074ebf6bc6356e47cbbb88dc4e55d04"}],"keystone/common/utils.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":531,"context_line":"    value False - it has a non-empty value - the False value"},{"line_number":532,"context_line":"    \"\"\""},{"line_number":533,"context_line":"    try:"},{"line_number":534,"context_line":"        if v is None or (len(v) \u003d\u003d 0):"},{"line_number":535,"context_line":"            return True"},{"line_number":536,"context_line":"    except TypeError:"},{"line_number":537,"context_line":"        # object has no length attribute -"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_5c80f6f6","line":534,"updated":"2014-05-18 15:36:36.000000000","message":"it\u0027s inefficient to count the entire length of something if all we need to know is if it\u0027s empty or not. Is there a more efficient way to do this?","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"b9671dd43e40eab842c67170e2c8e85458e5a02d","unresolved":false,"context_lines":[{"line_number":531,"context_line":"    value False - it has a non-empty value - the False value"},{"line_number":532,"context_line":"    \"\"\""},{"line_number":533,"context_line":"    try:"},{"line_number":534,"context_line":"        if v is None or (len(v) \u003d\u003d 0):"},{"line_number":535,"context_line":"            return True"},{"line_number":536,"context_line":"    except TypeError:"},{"line_number":537,"context_line":"        # object has no length attribute -"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_e704701a","line":534,"in_reply_to":"7adec928_5c80f6f6","updated":"2014-05-20 17:54:53.000000000","message":"Looks like I can use this: if v is None or  (hasattr(v, \u0027__contains__\u0027) and not v): - this looks like the pep8 way to do it http://legacy.python.org/dev/peps/pep-0008/#programming-recommendations - presumably the pep8 recommended way to do this will also be the most efficient","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"26c47c05ca6dd9395af352e6db90f168153ad847","unresolved":false,"context_lines":[{"line_number":531,"context_line":"    value False - it has a non-empty value - the False value"},{"line_number":532,"context_line":"    \"\"\""},{"line_number":533,"context_line":"    try:"},{"line_number":534,"context_line":"        if v is None or (len(v) \u003d\u003d 0):"},{"line_number":535,"context_line":"            return True"},{"line_number":536,"context_line":"    except TypeError:"},{"line_number":537,"context_line":"        # object has no length attribute -"}],"source_content_type":"text/x-python","patch_set":18,"id":"baada198_b06e1ec8","line":534,"in_reply_to":"7adec928_e704701a","updated":"2014-06-30 22:59:36.000000000","message":"Can you add some tests to show the expected behavior for different types?  I think the \u0027if\u0027 statement from your comment is probably the right way to do this.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"}],"keystone/tests/core.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"811f4b7b8fea09b9d40d32708a5fbd13654a77cf","unresolved":false,"context_lines":[{"line_number":664,"context_line":"                (msg or \u0027%r !\u003d %r\u0027 % (first, second))"},{"line_number":665,"context_line":""},{"line_number":666,"context_line":"    def assertDictEqualNoneEmpty(self, d1, d2, msg\u003dNone):"},{"line_number":667,"context_line":"        \"\"\"same as assertDictEqualNoneEmpty, except consider keys"},{"line_number":668,"context_line":"           with empty values to be the same as non-existent keys"},{"line_number":669,"context_line":"        \"\"\""},{"line_number":670,"context_line":"        self.assertIsInstance(d1, dict)"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAVn%2F%2FGLs%3D","line":667,"updated":"2014-03-09 21:47:26.000000000","message":"the method is the same as itself?","commit_id":"65a2527f714173b10ca5ebfb533f6f661a7f2953"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"08900817d89c66ffa90f2442c74c3e243e742bb8","unresolved":false,"context_lines":[{"line_number":650,"context_line":"    def assertEqualNoneEmpty(self, first, second, msg\u003dNone):"},{"line_number":651,"context_line":"        \"\"\"Fail if the two objects are unequal as determined"},{"line_number":652,"context_line":"           by the \u0027\u003d\u003d\u0027 operator.  Consider None"},{"line_number":653,"context_line":"           equal to len(obj) \u003d\u003d 0"},{"line_number":654,"context_line":"        \"\"\""},{"line_number":655,"context_line":"        if not first \u003d\u003d second:"},{"line_number":656,"context_line":"            # if both values are empty, they are equal"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2Fd7Y%3D","line":653,"updated":"2014-03-17 18:18:56.000000000","message":"i\u0027m not sure what this last sentence is trying to say","commit_id":"72ed34e2e477d455a9387a13c20b48e7e4f9e03c"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6395f2527deaa6e893d4bf4842a0892c78befb0b","unresolved":false,"context_lines":[{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    _config_file_list \u003d []"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    # these are the list of properties that an object may"},{"line_number":344,"context_line":"    # have a None value for, if the corresponding LDAP"},{"line_number":345,"context_line":"    # entry does not have the corresponding attribute"},{"line_number":346,"context_line":"    _none_val_props \u003d [\u0027description\u0027, \u0027email\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAXH%2F%2F4uE%3D","line":343,"updated":"2014-04-16 17:48:09.000000000","message":"It would be nice to put this entire new block with the LDAP test cases if we don\u0027t have a need for them in other places.","commit_id":"82c5e73efaad971e5907f34d0f9adf85f90ef15e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"10752297857da8137e1efad43ac6f21ab6233722","unresolved":false,"context_lines":[{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    _config_file_list \u003d []"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    # these are the list of properties that an object may"},{"line_number":344,"context_line":"    # have a None value for, if the corresponding LDAP"},{"line_number":345,"context_line":"    # entry does not have the corresponding attribute"},{"line_number":346,"context_line":"    _none_val_props \u003d [\u0027description\u0027, \u0027email\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAXH%2F%2F4CQ%3D","line":343,"in_reply_to":"AAAAXH%2F%2F4aI%3D","updated":"2014-04-16 18:50:19.000000000","message":"Yeah, I think so. I\u0027ve been trying to cut out a lot of what\u0027s in core and move things closer to the usage. We can always pull them up if/when there is a need.","commit_id":"82c5e73efaad971e5907f34d0f9adf85f90ef15e"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"2938f726a98530d651741d92dd346975a2da7462","unresolved":false,"context_lines":[{"line_number":340,"context_line":""},{"line_number":341,"context_line":"    _config_file_list \u003d []"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    # these are the list of properties that an object may"},{"line_number":344,"context_line":"    # have a None value for, if the corresponding LDAP"},{"line_number":345,"context_line":"    # entry does not have the corresponding attribute"},{"line_number":346,"context_line":"    _none_val_props \u003d [\u0027description\u0027, \u0027email\u0027]"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAXH%2F%2F4aI%3D","line":343,"in_reply_to":"AAAAXH%2F%2F4uE%3D","updated":"2014-04-16 18:06:05.000000000","message":"_prop_can_be_none and _mutate_test_obj are both used in test_backend.py, which is not LDAP specific - should I put this code in test_backend.py?","commit_id":"82c5e73efaad971e5907f34d0f9adf85f90ef15e"}],"keystone/tests/fakeldap.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"97cc20f3ee7e6760cfc0da73e69eb80a894a3fe7","unresolved":false,"context_lines":[{"line_number":289,"context_line":"                emptyattrs.append(k)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        if emptyattrs:"},{"line_number":292,"context_line":"            raise ldap.INVALID_SYNTAX(\"empty attribute values for \""},{"line_number":293,"context_line":"                                      \"attributes \" + str(emptyattrs))"},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"        self.db[key] \u003d dict([(k, _internal_attr(k, v))"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAXH%2F%2FvwQ%3D","line":292,"updated":"2014-04-17 19:54:08.000000000","message":"Should this be internationalized? _()?\n\nShould use single quotes.","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b54499cee1fe641ffe25ecd9fd3af42797047f00","unresolved":false,"context_lines":[{"line_number":289,"context_line":"                emptyattrs.append(k)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        if emptyattrs:"},{"line_number":292,"context_line":"            raise ldap.INVALID_SYNTAX(\"empty attribute values for \""},{"line_number":293,"context_line":"                                      \"attributes \" + str(emptyattrs))"},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"        self.db[key] \u003d dict([(k, _internal_attr(k, v))"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAXH%2F%2FvI0%3D","line":292,"in_reply_to":"AAAAXH%2F%2FvLg%3D","updated":"2014-04-17 20:08:41.000000000","message":"Brant, yep, you\u0027re right.","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"9a2ed063c0a57993aac4e8af8f001cb7540e9c4b","unresolved":false,"context_lines":[{"line_number":289,"context_line":"                emptyattrs.append(k)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        if emptyattrs:"},{"line_number":292,"context_line":"            raise ldap.INVALID_SYNTAX(\"empty attribute values for \""},{"line_number":293,"context_line":"                                      \"attributes \" + str(emptyattrs))"},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"        self.db[key] \u003d dict([(k, _internal_attr(k, v))"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAXH%2F%2FvLg%3D","line":292,"in_reply_to":"AAAAXH%2F%2FvwQ%3D","updated":"2014-04-17 20:03:41.000000000","message":"David - let\u0027s not waste the translator\u0027s time by marking test code for translation.","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"97cc20f3ee7e6760cfc0da73e69eb80a894a3fe7","unresolved":false,"context_lines":[{"line_number":360,"context_line":"            if core.BaseLdap.is_empty(v):"},{"line_number":361,"context_line":"                # the syntaxes of most LDAP attributes do not allow empty"},{"line_number":362,"context_line":"                # values"},{"line_number":363,"context_line":"                raise ldap.INVALID_SYNTAX(\"empty value for attribute \" + k)"},{"line_number":364,"context_line":"            values \u003d entry.setdefault(k, [])"},{"line_number":365,"context_line":"            if cmd \u003d\u003d ldap.MOD_ADD:"},{"line_number":366,"context_line":"                v \u003d _internal_attr(k, v)"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAXH%2F%2FvwI%3D","line":363,"updated":"2014-04-17 19:54:08.000000000","message":"Should this be internationalized? _()?\n\nShould use single quotes.","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":280,"context_line":"                      core.utf8_decode(dn))"},{"line_number":281,"context_line":"            raise ldap.ALREADY_EXISTS(dn)"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        # ldap forbids adding an attribute with an empty value, depending"},{"line_number":284,"context_line":"        # on the syntax - most syntaxes disallow a zero-length value -"},{"line_number":285,"context_line":"        # reject empty values"},{"line_number":286,"context_line":"        emptyattrs \u003d []"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_fc70e241","line":283,"updated":"2014-05-18 15:36:36.000000000","message":"capitalize LDAP","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":11717,"name":"Ryan Oshima","email":"ryan.oshima@hp.com","username":"RyanOshima"},"change_message_id":"9068bc1189162074f0057dd9338a6ecdefdbc4c7","unresolved":false,"context_lines":[{"line_number":365,"context_line":""},{"line_number":366,"context_line":"        for cmd, k, v in modlist:"},{"line_number":367,"context_line":"            if utils.is_empty(v):"},{"line_number":368,"context_line":"                # the syntaxes of most LDAP attributes do not allow empty"},{"line_number":369,"context_line":"                # values"},{"line_number":370,"context_line":"                raise ldap.INVALID_SYNTAX(\u0027empty value for attribute \u0027 + k)"},{"line_number":371,"context_line":"            values \u003d entry.setdefault(k, [])"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_5f84a30a","line":368,"updated":"2014-07-23 19:51:03.000000000","message":"\"the\"-\u003e\"The","commit_id":"c9e35780ed2052390fc614bedbd007220f655f40"}],"keystone/tests/test_backend.py":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"811f4b7b8fea09b9d40d32708a5fbd13654a77cf","unresolved":false,"context_lines":[{"line_number":100,"context_line":"        #               not be returned by the api"},{"line_number":101,"context_line":"        self.user_sna.pop(\u0027password\u0027)"},{"line_number":102,"context_line":"        self.user_sna[\u0027enabled\u0027] \u003d True"},{"line_number":103,"context_line":"        self.assertDictEqualNoneEmpty(user_ref, self.user_sna)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def test_authenticate_and_get_roles_no_metadata(self):"},{"line_number":106,"context_line":"        user \u003d {"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAVn%2F%2FGKQ%3D","line":103,"updated":"2014-03-09 21:47:26.000000000","message":"this seems really dangerous. We used to know when we messed up the user  returned and now we won\u0027t in some cases. Why is this necessary?","commit_id":"65a2527f714173b10ca5ebfb533f6f661a7f2953"},{"author":{"_account_id":4,"name":"Dolph Mathews","email":"dolph.mathews@gmail.com","username":"dolph"},"change_message_id":"08900817d89c66ffa90f2442c74c3e243e742bb8","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        #               it easier to authenticate in tests, but should"},{"line_number":197,"context_line":"        #               not be returned by the api"},{"line_number":198,"context_line":"        self.user_foo.pop(\u0027password\u0027)"},{"line_number":199,"context_line":"        self.assertDictEqualNoneEmpty(user_ref, self.user_foo)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def test_get_user_404(self):"},{"line_number":202,"context_line":"        self.assertRaises(exception.UserNotFound,"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2Fd6U%3D","line":199,"updated":"2014-03-17 18:18:56.000000000","message":"with the new assertion methods, it\u0027s not really clear what you\u0027re testing here anymore (the assertions are much weaker) -- i\u0027d suggest explicitly asserting the state of one object, mutating it to look like the other, and then using assertDictEqual per usual","commit_id":"72ed34e2e477d455a9387a13c20b48e7e4f9e03c"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"72e5e385bdec8333268f34bc06793d8b59961e2b","unresolved":false,"context_lines":[{"line_number":2569,"context_line":"                project[\u0027id\u0027], project)"},{"line_number":2570,"context_line":"            is_equal \u003d project_ref[key] \u003d\u003d value"},{"line_number":2571,"context_line":"            if not is_equal and self._prop_can_be_none(key):"},{"line_number":2572,"context_line":"                is_equal \u003d project_ref[key] is None and \\"},{"line_number":2573,"context_line":"                    ((value is None) or (value \u003d\u003d \u0027\u0027))"},{"line_number":2574,"context_line":"            self.assertTrue(is_equal)"},{"line_number":2575,"context_line":"            project_ref \u003d self.assignment_api.get_project(project[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2B3Kc%3D","line":2572,"updated":"2014-03-22 15:48:53.000000000","message":"use () to continue a line rather than \\","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"72e5e385bdec8333268f34bc06793d8b59961e2b","unresolved":false,"context_lines":[{"line_number":2571,"context_line":"            if not is_equal and self._prop_can_be_none(key):"},{"line_number":2572,"context_line":"                is_equal \u003d project_ref[key] is None and \\"},{"line_number":2573,"context_line":"                    ((value is None) or (value \u003d\u003d \u0027\u0027))"},{"line_number":2574,"context_line":"            self.assertTrue(is_equal)"},{"line_number":2575,"context_line":"            project_ref \u003d self.assignment_api.get_project(project[\u0027id\u0027])"},{"line_number":2576,"context_line":"            is_equal \u003d project_ref[key] \u003d\u003d value"},{"line_number":2577,"context_line":"            if not is_equal and self._prop_can_be_none(key):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2B3KQ%3D","line":2574,"updated":"2014-03-22 15:48:53.000000000","message":"this needs a better error message... it\u0027s just going to say \"false is not true\"... have it print out something useful instead.","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"72e5e385bdec8333268f34bc06793d8b59961e2b","unresolved":false,"context_lines":[{"line_number":2577,"context_line":"            if not is_equal and self._prop_can_be_none(key):"},{"line_number":2578,"context_line":"                is_equal \u003d project_ref[key] is None and \\"},{"line_number":2579,"context_line":"                    ((value is None) or (value \u003d\u003d \u0027\u0027))"},{"line_number":2580,"context_line":"            self.assertTrue(is_equal)"},{"line_number":2581,"context_line":""},{"line_number":2582,"context_line":"        def assert_get_key_is(value):"},{"line_number":2583,"context_line":"            project_ref \u003d self.assignment_api.update_project("}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2B3KU%3D","line":2580,"updated":"2014-03-22 15:48:53.000000000","message":"this needs a better error message... it\u0027s just going to say \"false is not true\"... have it print out something useful instead.","commit_id":"3f67d80dd3610e0a0096ed8060a0a52530fc97a2"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"97cc20f3ee7e6760cfc0da73e69eb80a894a3fe7","unresolved":false,"context_lines":[{"line_number":2602,"context_line":"            if not is_equal and self._prop_can_be_none(key):"},{"line_number":2603,"context_line":"                is_equal \u003d (project_ref[key] is None and"},{"line_number":2604,"context_line":"                            ((value is None) or (value \u003d\u003d \u0027\u0027)))"},{"line_number":2605,"context_line":"            self.assertTrue(is_equal, \"Project key %s value %s not equal \""},{"line_number":2606,"context_line":"                            \"to expected value %s\" % (key, project_ref[key],"},{"line_number":2607,"context_line":"                                                      value))"},{"line_number":2608,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAXH%2F%2FvP8%3D","line":2605,"updated":"2014-04-17 19:54:08.000000000","message":"Should use single quotes.","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"97cc20f3ee7e6760cfc0da73e69eb80a894a3fe7","unresolved":false,"context_lines":[{"line_number":2619,"context_line":"            if not is_equal and self._prop_can_be_none(key):"},{"line_number":2620,"context_line":"                is_equal \u003d (project_ref.get(key) is None and"},{"line_number":2621,"context_line":"                            ((value is None) or (value \u003d\u003d \u0027\u0027)))"},{"line_number":2622,"context_line":"            self.assertTrue(is_equal, \"Project key %s value %s not equal \""},{"line_number":2623,"context_line":"                            \"to expected value %s\" % (key,"},{"line_number":2624,"context_line":"                                                      project_ref.get(key),"},{"line_number":2625,"context_line":"                                                      value))"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAXH%2F%2FvPw%3D","line":2622,"updated":"2014-04-17 19:54:08.000000000","message":"Should use single quotes.","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"e4256d7698869edb832ef560098dede97078f3a0","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    def _prop_can_be_none(self, prop):"},{"line_number":50,"context_line":"        return prop in self._none_val_props"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def _mutate_test_obj(self, dict_obj):"},{"line_number":53,"context_line":"        for prop in self._none_val_props:"},{"line_number":54,"context_line":"            if prop in dict_obj and (dict_obj[prop] is None or"},{"line_number":55,"context_line":"                                     dict_obj[prop] \u003d\u003d \u0027\u0027):"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAXH%2F%2Fuco%3D","line":52,"updated":"2014-04-17 21:44:14.000000000","message":"This name is a pretty poor description of what it does.  Would \"remove_falsey_values\" be better?","commit_id":"7b4e1950b384ebba457096c4d3490a35bc43a653"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"f19ee6c9044b2ab5d4ed6c238311e358e0c74ea2","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    def _prop_can_be_none(self, prop):"},{"line_number":50,"context_line":"        return prop in self._none_val_props"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def _mutate_test_obj(self, dict_obj):"},{"line_number":53,"context_line":"        for prop in self._none_val_props:"},{"line_number":54,"context_line":"            if prop in dict_obj and (dict_obj[prop] is None or"},{"line_number":55,"context_line":"                                     dict_obj[prop] \u003d\u003d \u0027\u0027):"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAXH%2F%2FuWU%3D","line":52,"in_reply_to":"AAAAXH%2F%2FuZE%3D","updated":"2014-04-17 21:55:11.000000000","message":"Nice","commit_id":"7b4e1950b384ebba457096c4d3490a35bc43a653"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"7ddc782832193e810b34d269853c99d87777439a","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    def _prop_can_be_none(self, prop):"},{"line_number":50,"context_line":"        return prop in self._none_val_props"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def _mutate_test_obj(self, dict_obj):"},{"line_number":53,"context_line":"        for prop in self._none_val_props:"},{"line_number":54,"context_line":"            if prop in dict_obj and (dict_obj[prop] is None or"},{"line_number":55,"context_line":"                                     dict_obj[prop] \u003d\u003d \u0027\u0027):"}],"source_content_type":"text/x-python","patch_set":14,"id":"AAAAXH%2F%2FuZE%3D","line":52,"in_reply_to":"AAAAXH%2F%2Fuco%3D","updated":"2014-04-17 21:49:18.000000000","message":"new name will be _remove_empty_valued_props","commit_id":"7b4e1950b384ebba457096c4d3490a35bc43a653"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"d00f178546d34d12a926326a2ea8465d34ba5910","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    def _remove_empty_valued_props(self, dict_obj):"},{"line_number":53,"context_line":"        for prop in self._none_val_props:"},{"line_number":54,"context_line":"            if prop in dict_obj and (dict_obj[prop] is None or"},{"line_number":55,"context_line":"                                     dict_obj[prop] \u003d\u003d \u0027\u0027):"},{"line_number":56,"context_line":"                dict_obj.pop(prop)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def _get_domain_fixture(self):"}],"source_content_type":"text/x-python","patch_set":16,"id":"9ad9bd40_7ab62bde","line":55,"updated":"2014-04-30 14:12:36.000000000","message":"May be it\u0027s better to use:\n\n if prop in dict_obj and dict_obj[prop] in [None, \u0027\u0027]\n\nto have shorter condition and to escape double getting from the dictionary","commit_id":"f5491713d3e087368cba0a8722e264044f756a6d"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"d00f178546d34d12a926326a2ea8465d34ba5910","unresolved":false,"context_lines":[{"line_number":2595,"context_line":"            is_equal \u003d project_ref[key] \u003d\u003d value"},{"line_number":2596,"context_line":"            if not is_equal and self._prop_can_be_none(key):"},{"line_number":2597,"context_line":"                is_equal \u003d (project_ref[key] is None and"},{"line_number":2598,"context_line":"                            ((value is None) or (value \u003d\u003d \u0027\u0027)))"},{"line_number":2599,"context_line":"            self.assertTrue(is_equal)"},{"line_number":2600,"context_line":"            project_ref \u003d self.assignment_api.get_project(project[\u0027id\u0027])"},{"line_number":2601,"context_line":"            is_equal \u003d project_ref[key] \u003d\u003d value"}],"source_content_type":"text/x-python","patch_set":16,"id":"9ad9bd40_c5cf5caf","line":2598,"updated":"2014-04-30 14:12:36.000000000","message":"To get \u0027is_equal\u0027 you use the same code four times. May be you should move it to some method?\n\nAlso you can use:\n\n value in [None, \u0027\u0027]\n\ninstead of:\n\n((value is None) or (value \u003d\u003d \u0027\u0027))","commit_id":"f5491713d3e087368cba0a8722e264044f756a6d"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"c680ed7cba32daf2f25cd0d38983a3db0927e85d","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        #               not be returned by the api"},{"line_number":116,"context_line":"        self.user_sna.pop(\u0027password\u0027)"},{"line_number":117,"context_line":"        self.user_sna[\u0027enabled\u0027] \u003d True"},{"line_number":118,"context_line":"        self._remove_empty_valued_props(user_ref)"},{"line_number":119,"context_line":"        self.assertDictEqual(user_ref, self.user_sna)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def test_authenticate_and_get_roles_no_metadata(self):"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_9ca43ea7","line":118,"updated":"2014-05-18 15:36:36.000000000","message":"I thought this was only changing the behavior of the LDAP backend, so why do we need to change tests for all backends?","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"b9671dd43e40eab842c67170e2c8e85458e5a02d","unresolved":false,"context_lines":[{"line_number":115,"context_line":"        #               not be returned by the api"},{"line_number":116,"context_line":"        self.user_sna.pop(\u0027password\u0027)"},{"line_number":117,"context_line":"        self.user_sna[\u0027enabled\u0027] \u003d True"},{"line_number":118,"context_line":"        self._remove_empty_valued_props(user_ref)"},{"line_number":119,"context_line":"        self.assertDictEqual(user_ref, self.user_sna)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def test_authenticate_and_get_roles_no_metadata(self):"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_b2db887c","line":118,"in_reply_to":"7adec928_9ca43ea7","updated":"2014-05-20 17:54:53.000000000","message":"I will see if I can figure out a way to override these tests in the LDAP backend subclass BaseLDAPIdentity without too much code duplication.","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":9098,"name":"Nathan Kinder","email":"nkinder@redhat.com","username":"nkinder"},"change_message_id":"2d5c1b9fa93f8e7b40566269d7adf2fc2b0daa00","unresolved":false,"context_lines":[{"line_number":2537,"context_line":""},{"line_number":2538,"context_line":"        def is_equal_or_empty(vdict, key, value):"},{"line_number":2539,"context_line":"            ret \u003d vdict[key] \u003d\u003d value"},{"line_number":2540,"context_line":"            if not ret and self._prop_can_be_none(key):"},{"line_number":2541,"context_line":"                ret \u003d vdict[key] is None and value in [None, \u0027\u0027]"},{"line_number":2542,"context_line":"            return ret"},{"line_number":2543,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_ded51848","line":2540,"updated":"2014-07-23 18:54:37.000000000","message":"How does this work for non-LDAP backends given that _prop_can_be_none is only defined in the BaseLDAPIdentity class?\n\nIt seems like the method definition should be here in the IdentityTests class and overridden as necessary in the BaseLDAPIdentity class.","commit_id":"c9e35780ed2052390fc614bedbd007220f655f40"}],"keystone/tests/test_backend_ldap.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"6395f2527deaa6e893d4bf4842a0892c78befb0b","unresolved":false,"context_lines":[{"line_number":809,"context_line":"        role_ref \u003d self.assignment_api.get_role(self.role_member[\u0027id\u0027])"},{"line_number":810,"context_line":"        self.assertEqual(self.role_member[\u0027id\u0027], role_ref[\u0027id\u0027])"},{"line_number":811,"context_line":"        self.assertTrue((\u0027name\u0027 not in role_ref) or (role_ref[\u0027name\u0027] is None),"},{"line_number":812,"context_line":"                        \"Role name should be missing but it is present \""},{"line_number":813,"context_line":"                        \"with value %s\" % role_ref[\u0027name\u0027])"},{"line_number":814,"context_line":""},{"line_number":815,"context_line":"    def test_role_attribute_ignore(self):"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAXH%2F%2F43c%3D","line":812,"updated":"2014-04-16 17:48:09.000000000","message":"I think you want to add a bit to the comment to say it should be missing or equal to None.","commit_id":"82c5e73efaad971e5907f34d0f9adf85f90ef15e"},{"author":{"_account_id":9983,"name":"Richard Megginson","email":"rmeggins@redhat.com","username":"rmeggins"},"change_message_id":"2938f726a98530d651741d92dd346975a2da7462","unresolved":false,"context_lines":[{"line_number":809,"context_line":"        role_ref \u003d self.assignment_api.get_role(self.role_member[\u0027id\u0027])"},{"line_number":810,"context_line":"        self.assertEqual(self.role_member[\u0027id\u0027], role_ref[\u0027id\u0027])"},{"line_number":811,"context_line":"        self.assertTrue((\u0027name\u0027 not in role_ref) or (role_ref[\u0027name\u0027] is None),"},{"line_number":812,"context_line":"                        \"Role name should be missing but it is present \""},{"line_number":813,"context_line":"                        \"with value %s\" % role_ref[\u0027name\u0027])"},{"line_number":814,"context_line":""},{"line_number":815,"context_line":"    def test_role_attribute_ignore(self):"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAXH%2F%2F4Z8%3D","line":812,"in_reply_to":"AAAAXH%2F%2F43c%3D","updated":"2014-04-16 18:06:05.000000000","message":"Done","commit_id":"82c5e73efaad971e5907f34d0f9adf85f90ef15e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"97cc20f3ee7e6760cfc0da73e69eb80a894a3fe7","unresolved":false,"context_lines":[{"line_number":855,"context_line":"        role_ref \u003d self.assignment_api.get_role(self.role_member[\u0027id\u0027])"},{"line_number":856,"context_line":"        self.assertEqual(self.role_member[\u0027id\u0027], role_ref[\u0027id\u0027])"},{"line_number":857,"context_line":"        self.assertTrue((\u0027name\u0027 not in role_ref) or (role_ref[\u0027name\u0027] is None),"},{"line_number":858,"context_line":"                        \"Role name should be missing or None but it is \""},{"line_number":859,"context_line":"                        \"present with value %s\" % role_ref[\u0027name\u0027])"},{"line_number":860,"context_line":""},{"line_number":861,"context_line":"    def test_role_attribute_ignore(self):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAXH%2F%2FvPo%3D","line":858,"updated":"2014-04-17 19:54:08.000000000","message":"Should use single quotes.","commit_id":"6fd06440861dff2a48fe448a50d0b288eb7ec2f6"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"d00f178546d34d12a926326a2ea8465d34ba5910","unresolved":false,"context_lines":[{"line_number":857,"context_line":"                                                self.role_member[\u0027id\u0027])"},{"line_number":858,"context_line":"        role_ref \u003d self.assignment_api.get_role(self.role_member[\u0027id\u0027])"},{"line_number":859,"context_line":"        self.assertEqual(self.role_member[\u0027id\u0027], role_ref[\u0027id\u0027])"},{"line_number":860,"context_line":"        self.assertTrue((\u0027name\u0027 not in role_ref) or (role_ref[\u0027name\u0027] is None),"},{"line_number":861,"context_line":"                        \u0027Role name should be missing or None but it is \u0027"},{"line_number":862,"context_line":"                        \u0027present with value %s\u0027 % role_ref[\u0027name\u0027])"},{"line_number":863,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"9ad9bd40_45034c0f","line":860,"updated":"2014-04-30 14:12:36.000000000","message":"You can use here:\n\n assertTrue(role_ref.get(\u0027name\u0027) is None, ...)\n\nrole_ref.get(\u0027name\u0027) will return None in both cases if role_ref has no key \u0027name\u0027 and if value for key \u0027name\u0027 is None","commit_id":"f5491713d3e087368cba0a8722e264044f756a6d"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"16616663a45264a5b2f34a7306bb4f61caae6997","unresolved":false,"context_lines":[{"line_number":1579,"context_line":"            userd[\u0027id\u0027], domain_scope\u003dCONF.identity.default_domain_id)"},{"line_number":1580,"context_line":"        del userd[\u0027password\u0027]"},{"line_number":1581,"context_line":"        self._remove_empty_valued_props(ref)"},{"line_number":1582,"context_line":"        self.assertDictEqual(ref, userd)"},{"line_number":1583,"context_line":"        self.assertRaises(exception.UserNotFound,"},{"line_number":1584,"context_line":"                          self.identity_api.get_user,"},{"line_number":1585,"context_line":"                          userd[\u0027id\u0027],"}],"source_content_type":"text/x-python","patch_set":18,"id":"7adec928_3fac7ced","line":1582,"updated":"2014-05-08 18:45:41.000000000","message":"Potential refinement:  merge the remote and the assert together into a single assertion:  self.assertDictEqualNoEmptyValuesProperties()\n\nBut that is not a reason to not approve","commit_id":"5cadd7f9aae51862b9a6532db3b1dbbce7d44974"},{"author":{"_account_id":11717,"name":"Ryan Oshima","email":"ryan.oshima@hp.com","username":"RyanOshima"},"change_message_id":"9068bc1189162074f0057dd9338a6ecdefdbc4c7","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"class BaseLDAPIdentity(test_backend.IdentityTests):"},{"line_number":43,"context_line":"    # these are the list of properties that an object may"},{"line_number":44,"context_line":"    # have a None value for, if the corresponding LDAP"},{"line_number":45,"context_line":"    # entry does not have the corresponding attribute"},{"line_number":46,"context_line":"    _none_val_props \u003d [\u0027description\u0027, \u0027email\u0027]"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_bf74df36","line":43,"updated":"2014-07-23 19:51:03.000000000","message":"\"these\"-\u003e\"These\"","commit_id":"c9e35780ed2052390fc614bedbd007220f655f40"}],"keystone/tests/unit/common/test_utils.py":[{"author":{"_account_id":11333,"name":"David J Hu","email":"david.hu@hpe.com","username":"dhu"},"change_message_id":"1d97c3ab8e814b0b763acd2bf421100650721afc","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        self.assertFalse(utils.is_empty([\"this is a non-empty list\"]))"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def test_dict_is_not_empty(self):"},{"line_number":76,"context_line":"        self.assertFalse(utils.is_empty({\"this\": \"is a non-empty dict\"}))"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_aed4a5e9","line":76,"updated":"2014-07-24 06:24:30.000000000","message":"What about an additional test which validates that space is not empty.\n\ndef test_space_is_not_empty(self):\n    self.assertFalse(utils.is_empty(\" \"))","commit_id":"c9e35780ed2052390fc614bedbd007220f655f40"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"88aa589a3a698fa11ad595a0a1df7170443bffb6","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        self.assertFalse(utils.is_empty([\"this is a non-empty list\"]))"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def test_dict_is_not_empty(self):"},{"line_number":76,"context_line":"        self.assertFalse(utils.is_empty({\"this\": \"is a non-empty dict\"}))"}],"source_content_type":"text/x-python","patch_set":19,"id":"baada198_9354e0fd","line":76,"in_reply_to":"baada198_aed4a5e9","updated":"2014-08-12 14:41:42.000000000","message":"This case should be covered by test_string_not_empty()","commit_id":"c9e35780ed2052390fc614bedbd007220f655f40"}]}
