)]}'
{"oslo_versionedobjects/base.py":[{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"edaa63151fd245c64d7651a9b4b16051811c470e","unresolved":false,"context_lines":[{"line_number":641,"context_line":"        # loaded objects from db and fields which are dropped out differ"},{"line_number":642,"context_line":"        if hasattr(obj, \u0027obj_to_primitive\u0027):"},{"line_number":643,"context_line":"            return self.obj_to_primitive() \u003d\u003d obj.obj_to_primitive()"},{"line_number":644,"context_line":"        return False"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"class VersionedObjectDictCompat(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_b04e476d","line":644,"updated":"2015-08-11 23:39:34.000000000","message":"This should return NotImplemented, not False. https://docs.python.org/2.7/reference/datamodel.html#object.__eq__ and https://docs.python.org/3/reference/datamodel.html#object.__eq__\n\nWe should also be implementing __ne__ if we implement __eq__, but that can be treated separately (unless we don\u0027t support older Python versions).","commit_id":"3d9afd00e2d81c65dc3b9e07def17765a0e351a6"},{"author":{"_account_id":9796,"name":"ChangBo Guo","email":"glongwave@gmail.com","username":"gcb"},"change_message_id":"040159f68c3b17472dd6ea8a68c79ef621050023","unresolved":false,"context_lines":[{"line_number":641,"context_line":"        # loaded objects from db and fields which are dropped out differ"},{"line_number":642,"context_line":"        if hasattr(obj, \u0027obj_to_primitive\u0027):"},{"line_number":643,"context_line":"            return self.obj_to_primitive() \u003d\u003d obj.obj_to_primitive()"},{"line_number":644,"context_line":"        return False"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"class VersionedObjectDictCompat(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_174efc3a","line":644,"in_reply_to":"1a4dcd0f_036f9bfc","updated":"2015-12-03 09:21:28.000000000","message":"ComparableVersionedObject is used for heat, neutron,  cinder now \n\nFrom user side ,  a boolean  value is friendly for caller,  otherewise   they must catch  NotImplemented in code.","commit_id":"3d9afd00e2d81c65dc3b9e07def17765a0e351a6"},{"author":{"_account_id":8247,"name":"Thang Pham","email":"thang.g.pham@gmail.com","username":"thang.pham"},"change_message_id":"4c576d5aefa680f2d263c7f8022fcf91f7d2eb03","unresolved":false,"context_lines":[{"line_number":641,"context_line":"        # loaded objects from db and fields which are dropped out differ"},{"line_number":642,"context_line":"        if hasattr(obj, \u0027obj_to_primitive\u0027):"},{"line_number":643,"context_line":"            return self.obj_to_primitive() \u003d\u003d obj.obj_to_primitive()"},{"line_number":644,"context_line":"        return False"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"class VersionedObjectDictCompat(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a4dcd0f_036f9bfc","line":644,"in_reply_to":"1a4dcd0f_b04e476d","updated":"2015-08-12 13:42:55.000000000","message":"I do not know if this is really \"NotImplemented\".  This is used when the versionedobject is compared to something else.  If a versionedobject is compared to a non-versionedobject, False is the correct value to return.  It is not that it is not implemented; it should be false because it is not a versionedobject.","commit_id":"3d9afd00e2d81c65dc3b9e07def17765a0e351a6"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"ca1ef34f70dd65182514f2ed1f38d0fc637f05e7","unresolved":false,"context_lines":[{"line_number":641,"context_line":"        # loaded objects from db and fields which are dropped out differ"},{"line_number":642,"context_line":"        if hasattr(obj, \u0027obj_to_primitive\u0027):"},{"line_number":643,"context_line":"            return self.obj_to_primitive() \u003d\u003d obj.obj_to_primitive()"},{"line_number":644,"context_line":"        return False"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":""},{"line_number":647,"context_line":"class VersionedObjectDictCompat(object):"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a68dd71_64b05e44","line":644,"in_reply_to":"9a8ffd7b_174efc3a","updated":"2016-01-21 15:56:54.000000000","message":"\u003e From user side, a boolean value is friendly for caller, otherewise they must catch NotImplemented in code.\n\nIt\u0027s part of the __eq__ protocol in Python: no application call directly the __eq__() method, but use x \u003d\u003d y. The \u003d\u003d operator always return a boolean.\n\n\"return NotImplemented\" is better to support comparison to other objects: if x.__eq__(y) returns NotImplemented, x\u003d\u003dy then tries y.__eq__(x).\n\nAnd yes, you must also define __ne__() for Python 2. (On Python 3, __ne__() now calls __eq__() by default.)","commit_id":"3d9afd00e2d81c65dc3b9e07def17765a0e351a6"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"fd73c8173d8931a33bdca81510ee18d235392aa6","unresolved":false,"context_lines":[{"line_number":677,"context_line":"        return NotImplemented"},{"line_number":678,"context_line":""},{"line_number":679,"context_line":"    def __ne__(self, obj):"},{"line_number":680,"context_line":"        if hasattr(obj, \u0027obj_to_primitive\u0027):"},{"line_number":681,"context_line":"            return self.obj_to_primitive() !\u003d obj.obj_to_primitive()"},{"line_number":682,"context_line":"        return NotImplemented"},{"line_number":683,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a68dd71_98eb2f13","line":680,"range":{"start_line":680,"start_character":8,"end_line":680,"end_character":10},"updated":"2016-01-22 17:27:35.000000000","message":"I suggest to simply call __eq__():\n\n # On Python 3, it\u0027s already the default behaviour\n if six.PY2:\n     def __ne__(self, other):\n         return not(self \u003d\u003d other)","commit_id":"fe3c4f9dc1a0b8a060d8b5826910fe14ffff99a4"},{"author":{"_account_id":8247,"name":"Thang Pham","email":"thang.g.pham@gmail.com","username":"thang.pham"},"change_message_id":"645e59cd9bc01c80462c3340bdd1e1fd57aa4053","unresolved":false,"context_lines":[{"line_number":677,"context_line":"        return NotImplemented"},{"line_number":678,"context_line":""},{"line_number":679,"context_line":"    def __ne__(self, obj):"},{"line_number":680,"context_line":"        if hasattr(obj, \u0027obj_to_primitive\u0027):"},{"line_number":681,"context_line":"            return self.obj_to_primitive() !\u003d obj.obj_to_primitive()"},{"line_number":682,"context_line":"        return NotImplemented"},{"line_number":683,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a68dd71_837184aa","line":680,"range":{"start_line":680,"start_character":8,"end_line":680,"end_character":10},"in_reply_to":"9a68dd71_98eb2f13","updated":"2016-01-22 17:45:13.000000000","message":"Like below?\nif hasattr(obj, \u0027obj_to_primitive\u0027):\n    return not self.__eq__(obj)\nreturn NotImplemented","commit_id":"fe3c4f9dc1a0b8a060d8b5826910fe14ffff99a4"}],"oslo_versionedobjects/tests/test_objects.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"de1f061438dc5a111c361e668601e5bdd0a23ea5","unresolved":false,"context_lines":[{"line_number":1075,"context_line":"        obj4 \u003d NonVersionedObject()"},{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":""},{"line_number":1080,"context_line":"    def test_compound_clone(self):"},{"line_number":1081,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a50d1a3_e85a5c81","line":1078,"updated":"2015-07-29 15:40:09.000000000","message":"Shouldn\u0027t we also test \u003d\u003dNone here since that\u0027s the case that caused this to come up (I think) ?","commit_id":"60087a29c0c34ac9e159da426e5efef1d17d5a77"},{"author":{"_account_id":8247,"name":"Thang Pham","email":"thang.g.pham@gmail.com","username":"thang.pham"},"change_message_id":"f4e1b1c2f404694c68c60eb4baa8945403825bfc","unresolved":false,"context_lines":[{"line_number":1075,"context_line":"        obj4 \u003d NonVersionedObject()"},{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":""},{"line_number":1080,"context_line":"    def test_compound_clone(self):"},{"line_number":1081,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a50d1a3_cf575bff","line":1078,"in_reply_to":"3a50d1a3_e31d9d62","updated":"2015-07-29 19:02:43.000000000","message":"The problem was !\u003d was calling the __eq__, so I added a test to cover !\u003d.","commit_id":"60087a29c0c34ac9e159da426e5efef1d17d5a77"},{"author":{"_account_id":8247,"name":"Thang Pham","email":"thang.g.pham@gmail.com","username":"thang.pham"},"change_message_id":"3d2b6df89946c950ac51b80e0371f0f6d04d21bd","unresolved":false,"context_lines":[{"line_number":1075,"context_line":"        obj4 \u003d NonVersionedObject()"},{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":""},{"line_number":1080,"context_line":"    def test_compound_clone(self):"},{"line_number":1081,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a50d1a3_e31d9d62","line":1078,"in_reply_to":"3a50d1a3_e85a5c81","updated":"2015-07-29 15:45:01.000000000","message":"Sure, I can add another case.","commit_id":"60087a29c0c34ac9e159da426e5efef1d17d5a77"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f0eb05e981a2d9972c5aa9cdd0de50c524a0839d","unresolved":false,"context_lines":[{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":"        self.assertTrue(obj1 is not None)"},{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"    def test_compound_clone(self):"},{"line_number":1082,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a4dcd0f_7869188b","line":1079,"updated":"2015-08-03 17:02:05.000000000","message":"This is true by definition, right?\n\nI think you need:\n\n  self.assertFalse(obj1 \u003d\u003d None)\n\nright?","commit_id":"ee65fda76e33d7df1b8b24ff573792ad15f10740"},{"author":{"_account_id":8247,"name":"Thang Pham","email":"thang.g.pham@gmail.com","username":"thang.pham"},"change_message_id":"57e6a95460c1191c7d90c0e06774c480e3dfc982","unresolved":false,"context_lines":[{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":"        self.assertTrue(obj1 is not None)"},{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"    def test_compound_clone(self):"},{"line_number":1082,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a4dcd0f_f040dc09","line":1079,"in_reply_to":"1a4dcd0f_7869188b","updated":"2015-08-03 18:45:46.000000000","message":"The original problem had to do with when __eq__ was called in py34 (see below).  To properly test this for py34, I decided to use the !\u003d equivalent.\n\nclass Thingee(object):\n\n  def __eq__(self, obj):\n    print \u0027thingee eq called with %s\u0027 % obj\n    return False\n\na \u003d Thingee()\nprint a \u003d\u003d None\nprint a !\u003d None\n\nIn python 2.7, the results are:\nthingee eq called with None\nFalse\nTrue\n\nIn python 3.4, the results are:\nthingee eq called with None\nFalse\nthingee eq called with None\nTrue\n\nIn python 3.4, !\u003d calls __eq__.","commit_id":"ee65fda76e33d7df1b8b24ff573792ad15f10740"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"dc30ef13a87f36cede0a76e2b8986d71f91b0c45","unresolved":false,"context_lines":[{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":"        self.assertFalse(obj1 is None)"},{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"    def test_compound_clone(self):"},{"line_number":1082,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a4dcd0f_c6053c14","line":1079,"updated":"2015-08-06 15:35:54.000000000","message":"We seem to keep talking past each other, and I\u0027m not sure why. I don\u0027t think the \"is None\" test is useful at all, and I think you\u0027re missing an \u003d\u003dNone test. The problem claimed in the commit message is around comparing an object to None, but you don\u0027t do that anywhere in here. So, I think you should do this:\n\n  http://pastebin.com/f5vau72g\n\nWhat am I missing?","commit_id":"7ccc00ab1935e6eed793d7412730eb9e5b3b13c6"},{"author":{"_account_id":8247,"name":"Thang Pham","email":"thang.g.pham@gmail.com","username":"thang.pham"},"change_message_id":"17914fdf99533e3f70e42530d6c77a4d7024a3db","unresolved":false,"context_lines":[{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":"        self.assertFalse(obj1 is None)"},{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"    def test_compound_clone(self):"},{"line_number":1082,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a4dcd0f_9792fc4a","line":1079,"in_reply_to":"1a4dcd0f_29f7118c","updated":"2015-08-06 16:13:55.000000000","message":"Ah ok, thx!","commit_id":"7ccc00ab1935e6eed793d7412730eb9e5b3b13c6"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a5a1275ddc6115cb49db2f108a676af71891b790","unresolved":false,"context_lines":[{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":"        self.assertFalse(obj1 is None)"},{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"    def test_compound_clone(self):"},{"line_number":1082,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a4dcd0f_29f7118c","line":1079,"in_reply_to":"1a4dcd0f_49f29d07","updated":"2015-08-06 15:45:00.000000000","message":"But \u0027is\u0027 is not the same as \u0027\u003d\u003d\u0027. What you really want is this:\n\n  self.assertNotEqual(obj1, None)\n\nWhich uses \u003d\u003d and passes pep8.","commit_id":"7ccc00ab1935e6eed793d7412730eb9e5b3b13c6"},{"author":{"_account_id":8247,"name":"Thang Pham","email":"thang.g.pham@gmail.com","username":"thang.pham"},"change_message_id":"eba9892c0396f677bf702a11c988b737d7040792","unresolved":false,"context_lines":[{"line_number":1076,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1077,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1078,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1079,"context_line":"        self.assertFalse(obj1 is None)"},{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"    def test_compound_clone(self):"},{"line_number":1082,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a4dcd0f_49f29d07","line":1079,"in_reply_to":"1a4dcd0f_c6053c14","updated":"2015-08-06 15:41:52.000000000","message":"I ran into a pep8 error when I use \u003d\u003d.  It said I had to use \"is\" instead.  See http://logs.openstack.org/79/206679/4/check/gate-oslo.versionedobjects-pep8/1cdb9b5/console.html","commit_id":"7ccc00ab1935e6eed793d7412730eb9e5b3b13c6"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"fd73c8173d8931a33bdca81510ee18d235392aa6","unresolved":false,"context_lines":[{"line_number":1290,"context_line":"        obj1 \u003d MyComparableObj(foo\u003d1)"},{"line_number":1291,"context_line":"        obj2 \u003d MyComparableObj(foo\u003d1)"},{"line_number":1292,"context_line":"        obj3 \u003d MyComparableObj(foo\u003d2)"},{"line_number":1293,"context_line":"        obj4 \u003d NonVersionedObject()"},{"line_number":1294,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1295,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1296,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a68dd71_9807afc9","line":1293,"range":{"start_line":1293,"start_character":15,"end_line":1293,"end_character":33},"updated":"2016-01-22 17:27:35.000000000","message":"You can use an integer (obj4 \u003d 123) or object (obj4 \u003d object()). No need to create a custom type.","commit_id":"fe3c4f9dc1a0b8a060d8b5826910fe14ffff99a4"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"fd73c8173d8931a33bdca81510ee18d235392aa6","unresolved":false,"context_lines":[{"line_number":1294,"context_line":"        self.assertTrue(obj1 \u003d\u003d obj2)"},{"line_number":1295,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj3)"},{"line_number":1296,"context_line":"        self.assertFalse(obj1 \u003d\u003d obj4)"},{"line_number":1297,"context_line":"        self.assertNotEqual(obj1, None)"},{"line_number":1298,"context_line":""},{"line_number":1299,"context_line":"    def test_compound_clone(self):"},{"line_number":1300,"context_line":"        obj \u003d MyCompoundObject()"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a68dd71_1875ff62","line":1297,"range":{"start_line":1297,"start_character":28,"end_line":1297,"end_character":32},"updated":"2016-01-22 17:27:35.000000000","message":"Hum, I suggest to use assertEqual/assertNotEqual for all tests. Or if you prefer, only use assertTrue/assertFalse.","commit_id":"fe3c4f9dc1a0b8a060d8b5826910fe14ffff99a4"}]}
