)]}'
{"id":"openstack%2Fglance~625114","triplet_id":"openstack%2Fglance~master~Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af","project":"openstack/glance","branch":"master","topic":"bug/1808063","hashtags":[],"change_id":"Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af","subject":"Make QuotaImageTagsProxy deep-copyable","status":"MERGED","created":"2018-12-13 20:59:19.000000000","updated":"2019-01-09 13:49:25.000000000","submitted":"2019-01-09 13:17:20.000000000","submitter":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"total_comment_count":7,"unresolved_comment_count":0,"has_review_started":true,"submission_id":"625114-1547039840885-795c03e7","meta_rev_id":"2629c6f871c8dca0c43272456a47be8dfea1e08e","_number":625114,"virtual_id_number":625114,"owner":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"actions":{},"labels":{"Verified":{"approved":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"all":[{"value":0,"date":"2018-12-18 21:48:49.000000000","_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},{"value":0,"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},{"value":0,"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},{"value":0,"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},{"value":0,"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},{"value":0,"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},{"value":0,"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},{"value":0,"date":"2018-12-21 20:58:13.000000000","_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"value":2,"date":"2019-01-09 13:17:20.000000000","post_submit":true,"permitted_voting_range":{"min":2,"max":2},"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}],"values":{"-2":"Fails","-1":"Doesn\u0027t seem to work"," 0":"No score","+1":"Works for me","+2":"Verified"},"description":"","default_value":0,"optional":true},"Code-Review":{"approved":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"all":[{"value":0,"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},{"value":2,"date":"2019-01-09 11:46:49.000000000","permitted_voting_range":{"min":2,"max":2},"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},{"value":0,"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},{"value":1,"date":"2018-12-20 01:38:11.000000000","permitted_voting_range":{"min":1,"max":1},"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},{"value":1,"date":"2018-12-21 21:49:08.000000000","permitted_voting_range":{"min":1,"max":1},"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},{"value":2,"date":"2018-12-22 00:20:51.000000000","permitted_voting_range":{"min":2,"max":2},"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},{"value":0,"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},{"value":0,"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"value":0,"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}],"values":{"-2":"Do not merge","-1":"This patch needs further work before it can be merged"," 0":"No score","+1":"Looks good to me, but someone else must approve","+2":"Looks good to me (core reviewer)"},"description":"","default_value":0,"optional":true},"Workflow":{"approved":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"all":[{"value":0,"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},{"value":1,"date":"2019-01-09 11:46:49.000000000","permitted_voting_range":{"min":1,"max":1},"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},{"value":0,"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},{"value":0,"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},{"value":0,"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},{"value":0,"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},{"value":0,"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},{"value":0,"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"value":0,"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}],"values":{"-1":"Work in progress"," 0":"Ready for reviews","+1":"Approved"},"description":"","default_value":0,"optional":true},"Review-Priority":{"all":[{"value":0,"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},{"value":0,"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},{"value":0,"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},{"value":0,"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},{"value":0,"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},{"value":0,"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},{"value":0,"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},{"value":0,"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"value":0,"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}],"values":{"-1":"Branch Freeze"," 0":"No Priority","+1":"Important Change","+2":"Top Priority / Holds Gate"},"description":"","default_value":0,"optional":true}},"removable_reviewers":[],"reviewers":{"REVIEWER":[{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"}]},"pending_reviewers":{},"reviewer_updates":[{"updated":"2018-12-17 20:46:27.000000000","updated_by":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"reviewer":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"state":"REVIEWER"},{"updated":"2018-12-18 20:44:57.000000000","updated_by":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"reviewer":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"state":"REVIEWER"},{"updated":"2018-12-18 21:48:49.000000000","updated_by":{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},"reviewer":{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},"state":"REVIEWER"},{"updated":"2018-12-20 01:38:11.000000000","updated_by":{"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},"reviewer":{"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},"state":"REVIEWER"},{"updated":"2018-12-21 21:49:08.000000000","updated_by":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"reviewer":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"state":"REVIEWER"},{"updated":"2018-12-22 00:20:51.000000000","updated_by":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"reviewer":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"state":"REVIEWER"},{"updated":"2019-01-09 11:46:49.000000000","updated_by":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"reviewer":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"state":"REVIEWER"},{"updated":"2019-01-09 13:17:20.000000000","updated_by":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"reviewer":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"state":"REVIEWER"}],"messages":[{"id":"cb59a4dd0cef5b2f83158b68d78736023ffab6e1","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-13 20:59:19.000000000","message":"Uploaded patch set 1.","accounts_in_message":[],"_revision_number":1},{"id":"37367ccd07ef804322878a0003f50f97d674b988","author":{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},"date":"2018-12-13 20:59:39.000000000","message":"Patch Set 1:\n\nBuild failed\n\n- ext-glance-zuul : NOT_REGISTERED","accounts_in_message":[],"_revision_number":1},{"id":"d2b47da77b247034213f2e00ea95feb9642fd301","author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"date":"2018-12-13 21:19:31.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"96081bd46fe035a12b16b6778756e2c06a7442a3","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-13 21:25:30.000000000","message":"Uploaded patch set 2: Commit message was updated.","accounts_in_message":[],"_revision_number":2},{"id":"e44b8cdd61bb22b9836e8d0749524c1c8e579794","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-13 21:25:48.000000000","message":"Uploaded patch set 3: Commit message was updated.","accounts_in_message":[],"_revision_number":3},{"id":"109ec2506b3f154a4c368c9220fd473d59c9e0d2","author":{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},"date":"2018-12-13 21:25:50.000000000","message":"Patch Set 2:\n\nBuild failed\n\n- ext-glance-zuul : NOT_REGISTERED","accounts_in_message":[],"_revision_number":2},{"id":"220a1656ac8419dafb0615c80066d5fe90a8806b","author":{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},"date":"2018-12-13 21:26:08.000000000","message":"Patch Set 3:\n\nBuild failed\n\n- ext-glance-zuul : NOT_REGISTERED","accounts_in_message":[],"_revision_number":3},{"id":"29e28463a76d51f52a06c9a2c1a5e024129cc332","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-13 21:26:57.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"c050526f8f1b224fccea11bc3f00b05dd03dae4a","author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"date":"2018-12-13 21:46:57.000000000","message":"Patch Set 3:\n\nLooking at b9fd10e2612f26c93d49c168a0408aba6d20e5bf I see no particular reason why that needs to be doing a deepcopy in the first place. mask_dict_password() already creates a new dictionary to return.","accounts_in_message":[],"_revision_number":3},{"id":"b5f341627dd20c520f3d1e63ac7fc03398a7c0b3","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2018-12-13 23:14:45.000000000","message":"Patch Set 3: Verified+1\n\nBuild succeeded (check pipeline).\n\n- tempest-full http://logs.openstack.org/14/625114/3/check/tempest-full/163b8f1/ : SUCCESS in 1h 38m 08s\n- neutron-grenade http://logs.openstack.org/14/625114/3/check/neutron-grenade/565adbe/ : SUCCESS in 59m 49s\n- grenade-py3 http://logs.openstack.org/14/625114/3/check/grenade-py3/2bb8303/ : SUCCESS in 1h 02m 40s\n- tempest-full-py3 http://logs.openstack.org/14/625114/3/check/tempest-full-py3/267b216/ : SUCCESS in 1h 14m 04s\n- openstack-tox-lower-constraints http://logs.openstack.org/14/625114/3/check/openstack-tox-lower-constraints/f35ce85/ : SUCCESS in 4m 03s\n- openstack-tox-pep8 http://logs.openstack.org/14/625114/3/check/openstack-tox-pep8/dc9916f/ : SUCCESS in 4m 16s\n- openstack-tox-py27 http://logs.openstack.org/14/625114/3/check/openstack-tox-py27/defbe39/ : SUCCESS in 4m 13s\n- openstack-tox-py35 http://logs.openstack.org/14/625114/3/check/openstack-tox-py35/d8fe9c4/ : SUCCESS in 4m 37s\n- openstack-tox-py36 http://logs.openstack.org/14/625114/3/check/openstack-tox-py36/7485b35/ : SUCCESS in 3m 57s\n- openstack-tox-docs http://logs.openstack.org/14/625114/3/check/openstack-tox-docs/9c4202a/html/ : SUCCESS in 4m 51s\n- openstack-tox-functional http://logs.openstack.org/14/625114/3/check/openstack-tox-functional/416ba8f/ : SUCCESS in 8m 33s\n- openstack-tox-functional-py35 http://logs.openstack.org/14/625114/3/check/openstack-tox-functional-py35/72adcea/ : SUCCESS in 7m 51s\n- glance-eventlet-ssl-handshake-broken-py35 http://logs.openstack.org/14/625114/3/check/glance-eventlet-ssl-handshake-broken-py35/a83a45f/ : FAILURE in 4m 17s (non-voting)\n- devstack-plugin-ceph-tempest http://logs.openstack.org/14/625114/3/check/devstack-plugin-ceph-tempest/3c2514d/ : FAILURE in 1h 41m 49s (non-voting)","accounts_in_message":[],"_revision_number":3},{"id":"5855ab3f01bfb32860f11f649fc8ce4e1965aa34","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-14 00:56:08.000000000","message":"Patch Set 3:\n\nTo be clear: even if the behavior in oslo.policy changes, we still need/want this in glance because we can\u0027t predict what might try to copy the object and that needs to be safe.","accounts_in_message":[],"_revision_number":3},{"id":"d59ccde9ccc31095879e92cfde6f9ec937be1d63","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-14 08:57:59.000000000","message":"Uploaded patch set 4.","accounts_in_message":[],"_revision_number":4},{"id":"d424ac4a9f8ade65ca78581faefa63e0c7e9efb0","author":{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},"date":"2018-12-14 08:58:26.000000000","message":"Patch Set 4:\n\nBuild failed\n\n- ext-glance-zuul : NOT_REGISTERED","accounts_in_message":[],"_revision_number":4},{"id":"96ee29f30b2986833874dc7d35a3d19adc4f53de","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2018-12-14 10:36:29.000000000","message":"Patch Set 4: Verified+1\n\nBuild succeeded (check pipeline).\n\n- tempest-full http://logs.openstack.org/14/625114/4/check/tempest-full/3bfe98e/ : SUCCESS in 1h 14m 56s\n- neutron-grenade http://logs.openstack.org/14/625114/4/check/neutron-grenade/fde62d2/ : SUCCESS in 55m 06s\n- grenade-py3 http://logs.openstack.org/14/625114/4/check/grenade-py3/5d18a77/ : SUCCESS in 58m 05s\n- tempest-full-py3 http://logs.openstack.org/14/625114/4/check/tempest-full-py3/8cdb365/ : SUCCESS in 1h 02m 19s\n- openstack-tox-lower-constraints http://logs.openstack.org/14/625114/4/check/openstack-tox-lower-constraints/dff79bc/ : SUCCESS in 4m 08s\n- openstack-tox-pep8 http://logs.openstack.org/14/625114/4/check/openstack-tox-pep8/6334a22/ : SUCCESS in 4m 28s\n- openstack-tox-py27 http://logs.openstack.org/14/625114/4/check/openstack-tox-py27/dd3aba8/ : SUCCESS in 4m 34s\n- openstack-tox-py35 http://logs.openstack.org/14/625114/4/check/openstack-tox-py35/00fe300/ : SUCCESS in 4m 27s\n- openstack-tox-py36 http://logs.openstack.org/14/625114/4/check/openstack-tox-py36/86bca65/ : SUCCESS in 3m 53s\n- openstack-tox-docs http://logs.openstack.org/14/625114/4/check/openstack-tox-docs/2fbb56d/html/ : SUCCESS in 4m 39s\n- openstack-tox-functional http://logs.openstack.org/14/625114/4/check/openstack-tox-functional/64b0d41/ : SUCCESS in 8m 29s\n- openstack-tox-functional-py35 http://logs.openstack.org/14/625114/4/check/openstack-tox-functional-py35/b85de73/ : SUCCESS in 7m 46s\n- glance-eventlet-ssl-handshake-broken-py35 http://logs.openstack.org/14/625114/4/check/glance-eventlet-ssl-handshake-broken-py35/625f2f3/ : FAILURE in 4m 44s (non-voting)\n- devstack-plugin-ceph-tempest http://logs.openstack.org/14/625114/4/check/devstack-plugin-ceph-tempest/f53e042/ : FAILURE in 1h 35m 49s (non-voting)","accounts_in_message":[],"_revision_number":4},{"id":"e4993a5b53792795dbc05446da36d2844215953c","author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"date":"2018-12-14 16:16:33.000000000","message":"Patch Set 4:\n\n\u003e Looking at b9fd10e2612f26c93d49c168a0408aba6d20e5bf I see no\n \u003e particular reason why that needs to be doing a deepcopy in the\n \u003e first place. mask_dict_password() already creates a new dictionary\n \u003e to return.\n\nMore context around the deepcopy here - http://eavesdrop.openstack.org/irclogs/%23openstack-keystone/%23openstack-keystone.2018-12-05.log.html#t2018-12-05T22:24:42 \n\nBut yeah, I can clean up that in oslo.policy if needed. Just let me know.","accounts_in_message":[],"_revision_number":4},{"id":"7487245e0cce963cd72b85ff0e654ee9bd58f2c4","author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"date":"2018-12-17 20:46:27.000000000","message":"Patch Set 4: Code-Review+1\n\n(1 comment)","accounts_in_message":[],"_revision_number":4},{"id":"5bb0886ee70e05b6cb3ec4258a624ea9ce4d8b89","author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"date":"2018-12-18 04:33:51.000000000","message":"Patch Set 4: Code-Review+2","accounts_in_message":[],"_revision_number":4},{"id":"31532405e639884124e662b05583504b3ccde951","author":{"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},"date":"2018-12-18 08:58:15.000000000","message":"Patch Set 4: Code-Review-1\n\nGenerally speaking, we may need to avoid calling __getattribute__ inside __getattr__, because if __getattribute__ failed then __getattr__ will be called automatically. So there will be a recursive call.\n\nSeems fortunately python3 interpreter will stop this recursive call when recursive depth achieved 2 (What I see is 2). But I think we\u0027d better to catch the exception explicitly, like:\n\n171         if name \u003d\u003d \u0027tags\u0027:\n172             try:\n173                 return self.__getattribute__(\u0027tags\u0027)\n174             except AttributeError:\n175                 return None\n176         return getattr(self.tags, name)","accounts_in_message":[],"_revision_number":4},{"id":"163e07a945cace98be655e3128acd24945c75fad","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 10:25:44.000000000","message":"Patch Set 4:\n\n\u003e Generally speaking, we may need to avoid calling __getattribute__\n \u003e inside __getattr__, because if __getattribute__ failed then\n \u003e __getattr__ will be called automatically. So there will be a\n \u003e recursive call.\n \u003e \n \u003e Seems fortunately python3 interpreter will stop this recursive call\n \u003e when recursive depth achieved 2 (What I see is 2). But I think we\u0027d\n \u003e better to catch the exception explicitly, like:\n \u003e \n \u003e 171         if name \u003d\u003d \u0027tags\u0027:\n \u003e 172             try:\n \u003e 173                 return self.__getattribute__(\u0027tags\u0027)\n \u003e 174             except AttributeError:\n \u003e 175                 return None\n \u003e 176         return getattr(self.tags, name)\n\nDid you try this, because I was unable to generate the recursion that you are describing. What \"failure\" of __getattribute__ can happen?\n\nAs things stand, if the \u0027tags\u0027 attribute is not present self.__getattribute__(\u0027tags\u0027) will raise AttributeError, which is pretty much exactly what we want (we don\u0027t want None, because that presumes the attribute is there with a value). What are the other ways that it can fail?","accounts_in_message":[],"_revision_number":4},{"id":"4cf3bf4065934330d8bee097346920379a6b6b8a","author":{"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},"date":"2018-12-18 10:41:33.000000000","message":"Patch Set 4:\n\nYes, I tried. You just need to set breakpoint in line \"return self.__getattribute__(\u0027tags\u0027)\", then you can see it enter twice.\n\nIf raise AttributeError here (the default/current behaviour), __getattr__ will re-entry, just as I said in above.\n\nYour code seems can work, because python interpreter seems captured the re-entry. But if there\u0027s no side-effect found, I prefer to catch the exception explicitly as I mentioned.\n\nWhat I tested is py35 and functional-py35","accounts_in_message":[],"_revision_number":4},{"id":"4d55933dade84ee8a5be87cbd34190746696d73c","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 10:56:12.000000000","message":"Patch Set 4:\n\n\u003e If raise AttributeError here (the default/current behaviour),\n \u003e __getattr__ will re-entry, just as I said in above.\n\nCan you write up a minimal test case for this, because I\u0027m not seeing the behavior you are describing when I try myself, and I think I must be missing a detail from your description, and thus doing it wrong, and seeing an example will probably get us to a result sooner.\n\nIt could be that this is only an apparent in 3.5, I\u0027ve been testing with 3.7 and 2.7.\n\nIn any case :\n\nThe desire outcome is that when the tags attribute is requested two things happen:\n\n* if \u0027tags\u0027 is present, return the value\n* if \u0027tags\u0027 is not present, raise AttributeError\n\n\nTo avoid possible interference from super classes, it may make sense to change the call to __getattribute__ to  object.__getattribute__(self, name)\n\nBut in any case it would be great to see the failure you mode you describe. It\u0027s not that I don\u0027t believe you, it\u0027s simply that I can\u0027t make it happen, and would like to.","accounts_in_message":[],"_revision_number":4},{"id":"01194f1e88806ce73d94d33f72aab44f07bd9c0b","author":{"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},"date":"2018-12-18 12:58:57.000000000","message":"Patch Set 4:\n\nHi Chris\n\nThis is command:\npython3 -m testtools.run glance.tests.unit.test_quota.TestQuotaImageTagsProxy.test_tags_deepcopy\n\nThis is code:\n  167     def __getattr__(self, name):\n  168         # Use __getattribute__ for \u0027tags\u0027 in case tags itself\n  169         # is request, which may happen during a deepcopy() and\n  170         # similar operations.\n  171         if name \u003d\u003d \u0027tags\u0027:\n  172             # try:\nCC173             import pdb; pdb.set_trace()\n  174             return self.__getattribute__(\u0027tags\u0027)\n  175             # except AttributeError:\n  176             #     return None\n  177         return getattr(self.tags, name)\n  178\n\nThis is some output:\n  /usr/local/lib/python3.5/dist-packages/testtools/testcase.py(719)_run_test_method()\n-\u003e return self._get_test_method()()\n  /opt/stack/glance/glance/tests/unit/test_quota.py(606)test_tags_deepcopy()\n-\u003e proxy_copy \u003d copy.deepcopy(proxy)\n  /usr/lib/python3.5/copy.py(182)deepcopy()\n-\u003e y \u003d _reconstruct(x, rv, 1, memo)\n  /usr/lib/python3.5/copy.py(298)_reconstruct()\n-\u003e if hasattr(y, \u0027__setstate__\u0027):\n  /opt/stack/glance/glance/quota/__init__.py(177)__getattr__()\n-\u003e return getattr(self.tags, name)\n\u003e /opt/stack/glance/glance/quota/__init__.py(174)__getattr__()\n-\u003e return self.__getattribute__(\u0027tags\u0027)\n(Pdb) n\nAttributeError: \u0027QuotaImageTagsProxy\u0027 object has no attribute \u0027tags\u0027\n\u003e /opt/stack/glance/glance/quota/__init__.py(174)__getattr__()\n-\u003e return self.__getattribute__(\u0027tags\u0027)\n(Pdb) n\n--Return--\n\u003e /opt/stack/glance/glance/quota/__init__.py(174)__getattr__()-\u003eNone\n-\u003e return self.__getattribute__(\u0027tags\u0027)\n(Pdb) n\nAttributeError: \u0027QuotaImageTagsProxy\u0027 object has no attribute \u0027tags\u0027\n\u003e /opt/stack/glance/glance/quota/__init__.py(177)__getattr__()\n-\u003e return getattr(self.tags, name)\n(Pdb) p name\n\u0027__setstate__\u0027\n(Pdb)\n\n\nYou can see line 174 entry twice, and before the second time there\u0027s an exception AttributeError which is caused by __getattribute__\n\nmy env is ubuntu16.04, and /usr/bin/python3 -\u003e python3.5","accounts_in_message":[],"_revision_number":4},{"id":"16e122c567a2be928e207a6a76cb85415e3f98fc","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 14:30:48.000000000","message":"Patch Set 4: Workflow-1\n\nOkay digging around in this has presented a problem not exactly like Liang Fang has pointed out, but related.\n\nEssentially the implementation of __getattr__ is entirely wrong, and it\u0027s only during deepcopy that it gets tickled. I have a new version in progress.","accounts_in_message":[],"_revision_number":4},{"id":"4c869a66c0e64678d0bf52d6f46372e0e660badd","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 17:49:13.000000000","message":"Patch Set 4:\n\nThe main \"wrongness\" here is that this is bad python:\n\n    \u003e\u003e\u003e getattr(set([\u0027a\u0027, \u0027b\u0027]), \u0027b\u0027)\n    Traceback (most recent call last):   \n    File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n    AttributeError: \u0027set\u0027 object has no attribute \u0027b\u0027\n\nBut that\u0027s exactly what this code is claiming to do. The reason we don\u0027t see it as a problem is because the tags are generally accessed via the __iter__ and __contains___ methods","accounts_in_message":[],"_revision_number":4},{"id":"38d5e6a16200eb34e5d1d87f643fbe5a07f93ec0","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 17:50:11.000000000","message":"Uploaded patch set 5.","accounts_in_message":[],"_revision_number":5},{"id":"315b655e5901f1f7691e0c0616f7dc87b7ab6af8","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 17:59:03.000000000","message":"Patch Set 5:\n\nOh crikey, I see. After removing the __getattr__ method and seeing what failed, I think I get it now: we\u0027re after the attributes on the set object.\n\nThat\u0027s a hell of a thing to do...\n\nAnyway, that explains why the failing tests are as they are. I guess the right thing to do here is the minimal change. I\u0027m still not certain that returning None is the right thing, but since the methods that are called on the set (add and remove) also return None, I guess we\u0027ll go with that.\n\nI don\u0027t recommend keeping this implementation.","accounts_in_message":[],"_revision_number":5},{"id":"b707de816944277f0e05e5790845149b7105b8ef","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 18:14:31.000000000","message":"Uploaded patch set 6.","accounts_in_message":[],"_revision_number":6},{"id":"5d7fd62706c6930f1639380c2e860fee0f948fb9","author":{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},"date":"2018-12-18 18:48:13.000000000","message":"Patch Set 6:\n\nBuild failed\n\n- dsvm-glance http://207.189.188.190/logs/14/625114/6/check-not-vote/ext-glance-zuul/bd74bb8 : FAILURE in 33m 22s","accounts_in_message":[],"_revision_number":6},{"id":"6bc7bba74f5384dbfac5980cb2b2e9fd21003142","author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"date":"2018-12-18 20:44:57.000000000","message":"Patch Set 6:\n\nI still have the question I brought up in IRC, namely, do we need to implement __deepcopy__ on this thing if it\u0027s going to be deep copied?  My understanding of these proxy classes is that they\u0027re supposed to be transparent--that\u0027s why all the dunder methods are implemented with respect to the \u0027tags\u0027 member, because for all intents and purposes, this is supposed to \"look\" like a set to other code interacting with it.  I think the problem is that when you call deepcopy() on it, the copy module recognizes this proxy class as what it really is (not as what it\u0027s a proxy for), and it tries to make a deep copy of a quota proxy object, not a deep copy of a set, and madcap hijinks ensue.\n\nWe have these proxy objects all over the place (don\u0027t blame me, I didn\u0027t do it!), so I think it\u0027s important to try to get this as \"right\" as we can (or, at least get it clear enough so we all understand what\u0027s happening).","accounts_in_message":[],"_revision_number":6},{"id":"88ea341c513c71f4869e24128f1ec13bdd3c9899","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 21:13:15.000000000","message":"Patch Set 6:\n\nBrian, I think if I expand the tests a bit to make sure that the deepcopies object still has working add and remove methods we\u0027ll see if we need __deepcopy__ or not.","accounts_in_message":[],"_revision_number":6},{"id":"264902e83638e0f4ac32bcac386bc7e292084ef2","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-18 21:16:41.000000000","message":"Uploaded patch set 7.","accounts_in_message":[],"_revision_number":7},{"id":"39633cc7112d258a7343cfd0491e3bd964d272ba","author":{"_account_id":9008,"name":"VMware NSX CI","username":"vmwareminesweeper","tags":["SERVICE_USER"]},"date":"2018-12-18 21:48:49.000000000","message":"Patch Set 7:\n\nBuild failed\n\n- dsvm-glance http://207.189.188.190/logs/14/625114/7/check-not-vote/ext-glance-zuul/213f59a : FAILURE in 31m 48s","accounts_in_message":[],"_revision_number":7},{"id":"831e6d606c2794b5dcff9dec0da2db0e0649a1d5","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2018-12-18 23:22:43.000000000","message":"Patch Set 7: Verified+1\n\nBuild succeeded (check pipeline).\n\n- tempest-full http://logs.openstack.org/14/625114/7/check/tempest-full/d77ef31/ : SUCCESS in 1h 25m 24s\n- neutron-grenade http://logs.openstack.org/14/625114/7/check/neutron-grenade/b00c7de/ : SUCCESS in 49m 42s\n- grenade-py3 http://logs.openstack.org/14/625114/7/check/grenade-py3/f17e8a0/ : SUCCESS in 52m 40s\n- tempest-full-py3 http://logs.openstack.org/14/625114/7/check/tempest-full-py3/57ed942/ : SUCCESS in 1h 15m 04s\n- openstack-tox-lower-constraints http://logs.openstack.org/14/625114/7/check/openstack-tox-lower-constraints/ec3e6c3/ : SUCCESS in 3m 39s\n- openstack-tox-pep8 http://logs.openstack.org/14/625114/7/check/openstack-tox-pep8/de76d70/ : SUCCESS in 4m 57s\n- openstack-tox-py27 http://logs.openstack.org/14/625114/7/check/openstack-tox-py27/afbf945/ : SUCCESS in 4m 43s\n- openstack-tox-py35 http://logs.openstack.org/14/625114/7/check/openstack-tox-py35/7d6cb78/ : SUCCESS in 4m 56s\n- openstack-tox-py36 http://logs.openstack.org/14/625114/7/check/openstack-tox-py36/a073a5c/ : SUCCESS in 3m 50s\n- openstack-tox-docs http://logs.openstack.org/14/625114/7/check/openstack-tox-docs/bd1d80c/html/ : SUCCESS in 4m 43s\n- openstack-tox-functional http://logs.openstack.org/14/625114/7/check/openstack-tox-functional/6039fd2/ : SUCCESS in 8m 05s\n- openstack-tox-functional-py35 http://logs.openstack.org/14/625114/7/check/openstack-tox-functional-py35/c67d18d/ : SUCCESS in 7m 41s\n- glance-eventlet-ssl-handshake-broken-py35 http://logs.openstack.org/14/625114/7/check/glance-eventlet-ssl-handshake-broken-py35/0c783fc/ : FAILURE in 4m 23s (non-voting)\n- devstack-plugin-ceph-tempest http://logs.openstack.org/14/625114/7/check/devstack-plugin-ceph-tempest/7a1936e/ : SUCCESS in 1h 38m 17s (non-voting)","accounts_in_message":[],"_revision_number":7},{"id":"5767496169228a238f1c9b6984979006a9f39f16","author":{"_account_id":28948,"name":"Liang Fang","email":"liang.a.fang@intel.com","username":"liang"},"date":"2018-12-20 01:38:11.000000000","message":"Patch Set 7: Code-Review+1\n\nLGTM","accounts_in_message":[],"_revision_number":7},{"id":"68acf0d9561dd6f73be7adab9a832f1a9c5551d9","author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"date":"2018-12-21 19:27:18.000000000","message":"Patch Set 7:\n\n(2 comments)","accounts_in_message":[],"_revision_number":7},{"id":"f94cbdc3dfd9be71f7c96c1359b4d3a575b2370e","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2018-12-21 20:58:13.000000000","message":"Patch Set 7:\n\n(1 comment)","accounts_in_message":[],"_revision_number":7},{"id":"5831c3e7b40a65f4712efc05e707f52177d8b4e3","author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"date":"2018-12-21 21:49:08.000000000","message":"Patch Set 7: Code-Review+1\n\n(1 comment)","accounts_in_message":[],"_revision_number":7},{"id":"ce90a81407d9ecf782604a09a2bba2a307b23f86","author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"date":"2018-12-22 00:20:51.000000000","message":"Patch Set 7: Code-Review+2\n\nLooks good, thank you","accounts_in_message":[],"_revision_number":7},{"id":"1269a73a13001c58b2c5f31cc964632cf1f5487a","author":{"_account_id":5202,"name":"Erno Kuvaja","email":"jokke@usr.fi","username":"jokke"},"date":"2019-01-09 11:46:49.000000000","message":"Patch Set 7: Code-Review+2 Workflow+1\n\nThanks for working on this guys! Happy to see the code reinforced.","accounts_in_message":[],"_revision_number":7},{"id":"62134b9ec7e7e0975548e5035a0944889353927e","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2019-01-09 11:47:06.000000000","message":"Patch Set 7: -Verified\n\nStarting gate jobs.","accounts_in_message":[],"_revision_number":7},{"id":"6b4c164f96875685eb678466f48cfe0fa27d4fef","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2019-01-09 13:17:20.000000000","message":"Change has been successfully merged by Zuul","accounts_in_message":[],"_revision_number":7},{"id":"966df59bd494eb12f245bc780268f2338da9886f","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2019-01-09 13:17:20.000000000","message":"Patch Set 7: Verified+2\n\nBuild succeeded (gate pipeline).\n\n- tempest-full http://logs.openstack.org/14/625114/7/gate/tempest-full/6cc6400/ : SUCCESS in 1h 24m 30s\n- neutron-grenade http://logs.openstack.org/14/625114/7/gate/neutron-grenade/75c8df3/ : SUCCESS in 1h 02m 28s\n- grenade-py3 http://logs.openstack.org/14/625114/7/gate/grenade-py3/6a60d83/ : SUCCESS in 57m 53s\n- tempest-full-py3 http://logs.openstack.org/14/625114/7/gate/tempest-full-py3/4776e44/ : SUCCESS in 1h 09m 37s\n- openstack-tox-lower-constraints http://logs.openstack.org/14/625114/7/gate/openstack-tox-lower-constraints/0162c6d/ : SUCCESS in 4m 16s\n- openstack-tox-pep8 http://logs.openstack.org/14/625114/7/gate/openstack-tox-pep8/f04cee9/ : SUCCESS in 5m 23s\n- openstack-tox-py27 http://logs.openstack.org/14/625114/7/gate/openstack-tox-py27/87e26a3/ : SUCCESS in 4m 32s\n- openstack-tox-py35 http://logs.openstack.org/14/625114/7/gate/openstack-tox-py35/61c6b45/ : SUCCESS in 4m 42s\n- openstack-tox-py36 http://logs.openstack.org/14/625114/7/gate/openstack-tox-py36/ea5ce8e/ : SUCCESS in 3m 36s\n- openstack-tox-docs http://logs.openstack.org/14/625114/7/gate/openstack-tox-docs/0fc7a27/html/ : SUCCESS in 4m 40s\n- openstack-tox-functional http://logs.openstack.org/14/625114/7/gate/openstack-tox-functional/b81add7/ : SUCCESS in 7m 49s\n- openstack-tox-functional-py35 http://logs.openstack.org/14/625114/7/gate/openstack-tox-functional-py35/2930ccf/ : SUCCESS in 7m 56s","accounts_in_message":[],"_revision_number":7},{"id":"71ca053c26f314ef001cb56795eae47c08c1fa2d","author":{"_account_id":5314,"name":"Brian Rosmaita","email":"rosmaita.fossdev@gmail.com","username":"brian-rosmaita"},"date":"2019-01-09 13:49:25.000000000","message":"Patch Set 7:\n\nJust want to add my belated thanks to Chris for sticking with this!","accounts_in_message":[],"_revision_number":7}],"current_revision_number":7,"current_revision":"deffb09871c9460497929c57bd82ca78d1c3177f","revisions":{"a1e49fc2e06d2643e63827bb5bdaf036e1dcd490":{"kind":"REWORK","_number":1,"created":"2018-12-13 20:59:19.000000000","uploader":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"ref":"refs/changes/14/625114/1","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/glance","ref":"refs/changes/14/625114/1","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/1 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/1 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/1 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/glance refs/changes/14/625114/1"}}},"commit":{"parents":[{"commit":"8d1beed2a890ddba174b226e7e117068caaf9d56","subject":"Merge \"Implement scaffolding for upgrade checks\"","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/8d1beed2a890ddba174b226e7e117068caaf9d56"}]}],"author":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 20:56:39.000000000","tz":0},"committer":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 20:56:39.000000000","tz":0},"subject":"Make QuotaImageTagsProxy deep-copyable","message":"Make QuotaImageTagsProxy deep-copyable\n\nInfinite recursion is possible if you try to deepcopy a\nQuotaImageTagsProxy object, which is something that happens when using\noslo.policy 1.41.3 and beyond.\n\nBy adding a __gettattribute__ within the __getattr__ method we can break\nthe loop when the name of the attribute is \u0027tags\u0027.\n\nChange-Id: Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af\nRelated-Bug: #1808063\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/a1e49fc2e06d2643e63827bb5bdaf036e1dcd490"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/a1e49fc2e06d2643e63827bb5bdaf036e1dcd490"}]},"branch":"refs/heads/master"},"d1b126de9ec11b5b2358d5f19e24c911191504f1":{"kind":"NO_CODE_CHANGE","_number":2,"created":"2018-12-13 21:25:30.000000000","uploader":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"ref":"refs/changes/14/625114/2","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/glance","ref":"refs/changes/14/625114/2","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/2 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/2 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/2 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/glance refs/changes/14/625114/2"}}},"commit":{"parents":[{"commit":"8d1beed2a890ddba174b226e7e117068caaf9d56","subject":"Merge \"Implement scaffolding for upgrade checks\"","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/8d1beed2a890ddba174b226e7e117068caaf9d56"}]}],"author":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 20:56:39.000000000","tz":0},"committer":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 21:25:13.000000000","tz":0},"subject":"Make QuotaImageTagsProxy deep-copyable","message":"Make QuotaImageTagsProxy deep-copyable\n\nInfinite recursion is possible if you try to deepcopy a\nQuotaImageTagsProxy object, which is something that happens when using\noslo.policy 1.41.1 and beyond.\n\nBy adding a __gettattribute__ within the __getattr__ method we can break\nthe loop when the name of the attribute is \u0027tags\u0027.\n\nChange-Id: Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af\nRelated-Bug: #1808063\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/d1b126de9ec11b5b2358d5f19e24c911191504f1"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/d1b126de9ec11b5b2358d5f19e24c911191504f1"}]},"branch":"refs/heads/master"},"5a3cba43619af59ab763a5871a68ff1f439facc9":{"kind":"NO_CODE_CHANGE","_number":3,"created":"2018-12-13 21:25:48.000000000","uploader":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"ref":"refs/changes/14/625114/3","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/glance","ref":"refs/changes/14/625114/3","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/3 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/3 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/3 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/glance refs/changes/14/625114/3"}}},"commit":{"parents":[{"commit":"8d1beed2a890ddba174b226e7e117068caaf9d56","subject":"Merge \"Implement scaffolding for upgrade checks\"","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/8d1beed2a890ddba174b226e7e117068caaf9d56"}]}],"author":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 20:56:39.000000000","tz":0},"committer":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 21:25:36.000000000","tz":0},"subject":"Make QuotaImageTagsProxy deep-copyable","message":"Make QuotaImageTagsProxy deep-copyable\n\nInfinite recursion is possible if you try to deepcopy a\nQuotaImageTagsProxy object, which is something that happens when using\noslo.policy 1.43.1 and beyond.\n\nBy adding a __gettattribute__ within the __getattr__ method we can break\nthe loop when the name of the attribute is \u0027tags\u0027.\n\nChange-Id: Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af\nRelated-Bug: #1808063\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/5a3cba43619af59ab763a5871a68ff1f439facc9"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/5a3cba43619af59ab763a5871a68ff1f439facc9"}]},"branch":"refs/heads/master"},"c9a0904cf216a094892970624c2f7e2d4d490647":{"kind":"REWORK","_number":4,"created":"2018-12-14 08:57:59.000000000","uploader":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"ref":"refs/changes/14/625114/4","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/glance","ref":"refs/changes/14/625114/4","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/4 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/4 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/4 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/glance refs/changes/14/625114/4"}}},"commit":{"parents":[{"commit":"044d6b45f98238f4a5745922ef93223d05771d4c","subject":"Guard __getattr__ on QuotaImageTagsProxy","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/044d6b45f98238f4a5745922ef93223d05771d4c"}]}],"author":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 20:56:39.000000000","tz":0},"committer":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-14 08:57:58.000000000","tz":0},"subject":"Make QuotaImageTagsProxy deep-copyable","message":"Make QuotaImageTagsProxy deep-copyable\n\nInfinite recursion is possible if you try to deepcopy a\nQuotaImageTagsProxy object, which is something that happens when using\noslo.policy 1.43.1 and beyond.\n\nBy adding a __gettattribute__ within the __getattr__ method we can break\nthe loop when the name of the attribute is \u0027tags\u0027.\n\nThe added test will fail (with infinite recursion) if the new code is\nremoved.\n\nChange-Id: Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af\nRelated-Bug: #1808063\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/c9a0904cf216a094892970624c2f7e2d4d490647"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/c9a0904cf216a094892970624c2f7e2d4d490647"}]},"branch":"refs/heads/master"},"31f34a16e07787f39d5711880e6822a48e3077c4":{"kind":"REWORK","_number":5,"created":"2018-12-18 17:50:11.000000000","uploader":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"ref":"refs/changes/14/625114/5","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/glance","ref":"refs/changes/14/625114/5","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/5 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/5 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/5 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/glance refs/changes/14/625114/5"}}},"commit":{"parents":[{"commit":"044d6b45f98238f4a5745922ef93223d05771d4c","subject":"Guard __getattr__ on QuotaImageTagsProxy","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/044d6b45f98238f4a5745922ef93223d05771d4c"}]}],"author":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 20:56:39.000000000","tz":0},"committer":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-18 17:47:32.000000000","tz":0},"subject":"WIP: Make QuotaImageTagsProxy deep-copyable","message":"WIP: Make QuotaImageTagsProxy deep-copyable\n\nInfinite recursion is possible if you try to deepcopy a\nQuotaImageTagsProxy object, which is something that happens when using\noslo.policy 1.43.1 and beyond.\n\nBy adding a __gettattribute__ within the __getattr__ method we can break\nthe loop when the name of the attribute is \u0027tags\u0027.\n\nThe added test will fail (with infinite recursion) if the new code is\nremoved.\n\nHowever, during the discussion surrounding this bug it was determined\nthat the implementation of __getattr__ is incorrect. Some tests,\ncurrently failing, have been added to demonstrate the problem. This\nsuggests that something is weird, so I thought I better share.\n\nChange-Id: Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af\nRelated-Bug: #1808063\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/31f34a16e07787f39d5711880e6822a48e3077c4"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/31f34a16e07787f39d5711880e6822a48e3077c4"}]},"branch":"refs/heads/master"},"f80f298cddfaf5814178584cacf3c90df4ae96e7":{"kind":"REWORK","_number":6,"created":"2018-12-18 18:14:31.000000000","uploader":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"ref":"refs/changes/14/625114/6","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/glance","ref":"refs/changes/14/625114/6","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/6 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/6 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/6 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/glance refs/changes/14/625114/6"}}},"commit":{"parents":[{"commit":"044d6b45f98238f4a5745922ef93223d05771d4c","subject":"Guard __getattr__ on QuotaImageTagsProxy","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/044d6b45f98238f4a5745922ef93223d05771d4c"}]}],"author":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 20:56:39.000000000","tz":0},"committer":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-18 18:13:59.000000000","tz":0},"subject":"Make QuotaImageTagsProxy deep-copyable","message":"Make QuotaImageTagsProxy deep-copyable\n\nInfinite recursion is possible if you try to deepcopy a\nQuotaImageTagsProxy object, which is something that happens when using\noslo.policy 1.43.1 and beyond.\n\nBy adding a __gettattribute__ within the __getattr__ method we can break\nthe loop when the name of the attribute is \u0027tags\u0027.\n\nThe added test will fail (with infinite recursion) if the new code is\nremoved.\n\nFor completeness a test is added checking what happens when the tags\nattribute is removed.\n\nThe thing that is not immediately clear from the __getattr__ code is\nthat it is not for getting at the tags themselves, it is for getting\nat the methods on the set object at self.tags. The non-obviousness\nof this led to rather a lot of confusion while trying to get this\ncode right. It isn\u0027t really \"right\" now, but rather: safe in the\ncontext of its use.\n\nChange-Id: Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af\nRelated-Bug: #1808063\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/f80f298cddfaf5814178584cacf3c90df4ae96e7"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/f80f298cddfaf5814178584cacf3c90df4ae96e7"}]},"branch":"refs/heads/master"},"deffb09871c9460497929c57bd82ca78d1c3177f":{"kind":"REWORK","_number":7,"created":"2018-12-18 21:16:41.000000000","uploader":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"ref":"refs/changes/14/625114/7","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/glance","ref":"refs/changes/14/625114/7","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/7 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/7 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/glance refs/changes/14/625114/7 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/glance refs/changes/14/625114/7"}}},"commit":{"parents":[{"commit":"044d6b45f98238f4a5745922ef93223d05771d4c","subject":"Guard __getattr__ on QuotaImageTagsProxy","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/044d6b45f98238f4a5745922ef93223d05771d4c"}]}],"author":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-13 20:56:39.000000000","tz":0},"committer":{"name":"Chris Dent","email":"cdent@anticdent.org","date":"2018-12-18 21:16:19.000000000","tz":0},"subject":"Make QuotaImageTagsProxy deep-copyable","message":"Make QuotaImageTagsProxy deep-copyable\n\nInfinite recursion is possible if you try to deepcopy a\nQuotaImageTagsProxy object, which is something that happens when using\noslo.policy 1.43.1 and beyond.\n\nBy adding a __gettattribute__ within the __getattr__ method we can break\nthe loop when the name of the attribute is \u0027tags\u0027.\n\nThe added test will fail (with infinite recursion) if the new code is\nremoved.\n\nFor completeness a test is added checking what happens when the tags\nattribute is removed.\n\nThe thing that is not immediately clear from the __getattr__ code is\nthat it is not for getting at the tags themselves, it is for getting\nat the methods on the set object at self.tags. The non-obviousness\nof this led to rather a lot of confusion while trying to get this\ncode right. It isn\u0027t really \"right\" now, but rather: safe in the\ncontext of its use.\n\nChange-Id: Ic47c9bf8e9b97de5a5a49a35f631753c54e0e2af\nRelated-Bug: #1808063\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/deffb09871c9460497929c57bd82ca78d1c3177f"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/glance/commit/deffb09871c9460497929c57bd82ca78d1c3177f"}]},"branch":"refs/heads/master"}},"requirements":[],"submit_records":[],"submit_requirements":[]}
