)]}'
{"keystone/common/resource_options.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"1609c89013de21c7475708b73b633217c7a55abd","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    def option_ids(self):"},{"line_number":39,"context_line":"        return set(self._registered_options.keys())"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def get_option_by_fourcc(self, fourcc):"},{"line_number":42,"context_line":"        return self._registered_options.get(fourcc, None)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    def get_option_by_name(self, name):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_844881b4","line":41,"range":{"start_line":41,"start_character":8,"end_line":41,"end_character":28},"updated":"2017-01-24 16:28:26.000000000","message":"maybe should rename to get_option_by_id, fourcc is not used anywhere else (since it is not intuative what a FourCC is -\u003e 4 character code id)","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"49e54ca262ded3621e0b495d53fa02f2101b1269","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    def option_ids(self):"},{"line_number":39,"context_line":"        return set(self._registered_options.keys())"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def get_option_by_fourcc(self, fourcc):"},{"line_number":42,"context_line":"        return self._registered_options.get(fourcc, None)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    def get_option_by_name(self, name):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_b329408c","line":41,"range":{"start_line":41,"start_character":8,"end_line":41,"end_character":28},"in_reply_to":"5a3905b3_844881b4","updated":"2017-01-24 17:53:45.000000000","message":"++","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    return"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"def ref_mapper_to_dict_options(ref):"},{"line_number":25,"context_line":"    \"\"\"Convert the values in _resource_option_mapper to options dict."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    NOTE: this is to be called from the relevant `to_dict` methods or"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_a83e16b6","line":24,"updated":"2017-01-25 21:39:42.000000000","message":"Couldn\u0027t this be a method of ref so is doesn\u0027t have to reach into it\u0027s internals? Seems like it fits right along side {to,from}_dict.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    return"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"def ref_mapper_to_dict_options(ref):"},{"line_number":25,"context_line":"    \"\"\"Convert the values in _resource_option_mapper to options dict."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    NOTE: this is to be called from the relevant `to_dict` methods or"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_be1d6c68","line":24,"in_reply_to":"3a461143_a83e16b6","updated":"2017-01-25 21:59:06.000000000","message":"This was moved here because we have a lot of cases we override to_dict. I expect this to be re-used and copy/pasting code is icky.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"344e0963303ce320c921025ee0748c71a8ec8afa","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    return"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"def ref_mapper_to_dict_options(ref):"},{"line_number":25,"context_line":"    \"\"\"Convert the values in _resource_option_mapper to options dict."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    NOTE: this is to be called from the relevant `to_dict` methods or"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_190a1ad3","line":24,"in_reply_to":"3a461143_be1d6c68","updated":"2017-01-25 22:28:56.000000000","message":"ah, that\u0027s a bummer, but it\u0027s the bed we made.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        # _resource_options didn\u0027t exist. Work from an empty set."},{"line_number":70,"context_line":"        options \u003d {}"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    set_options \u003d set(ref._resource_option_mapper.keys())"},{"line_number":73,"context_line":"    # Get any options that are not registered and slate them for removal from"},{"line_number":74,"context_line":"    # the DB. This will delete unregistered options."},{"line_number":75,"context_line":"    clear_options \u003d set_options.difference("}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_e8465ebe","line":72,"updated":"2017-01-25 21:39:42.000000000","message":"(nit) .keys() is redundant","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"2a82130b6deab58e0b8c7f8a8c693cb78f63f593","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        # _resource_options didn\u0027t exist. Work from an empty set."},{"line_number":70,"context_line":"        options \u003d {}"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    set_options \u003d set(ref._resource_option_mapper.keys())"},{"line_number":73,"context_line":"    # Get any options that are not registered and slate them for removal from"},{"line_number":74,"context_line":"    # the DB. This will delete unregistered options."},{"line_number":75,"context_line":"    clear_options \u003d set_options.difference("}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_0aee3a22","line":72,"in_reply_to":"3a461143_9e37d0e2","updated":"2017-01-25 23:48:11.000000000","message":"Comment added for clarity.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        # _resource_options didn\u0027t exist. Work from an empty set."},{"line_number":70,"context_line":"        options \u003d {}"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    set_options \u003d set(ref._resource_option_mapper.keys())"},{"line_number":73,"context_line":"    # Get any options that are not registered and slate them for removal from"},{"line_number":74,"context_line":"    # the DB. This will delete unregistered options."},{"line_number":75,"context_line":"    clear_options \u003d set_options.difference("}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_9e37d0e2","line":72,"in_reply_to":"3a461143_e8465ebe","updated":"2017-01-25 21:59:06.000000000","message":"attribute mapper works slightly differently than normal dictionaries. I found this was required.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8ceb293059dc6f8dbd456c2759cdb9940377e0d5","unresolved":false,"context_lines":[{"line_number":79,"context_line":"    options.update({x: None for x in clear_options})"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    # Set the resource options for user in the Attribute Mapping."},{"line_number":82,"context_line":"    for r_opt_id, r_opt_value in options.items():"},{"line_number":83,"context_line":"        if r_opt_value is None:"},{"line_number":84,"context_line":"            # Delete any option set explicitly to None, ignore unset"},{"line_number":85,"context_line":"            # options."}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_b303c172","line":82,"updated":"2017-01-26 15:40:11.000000000","message":"Where is the option key handled?","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8ceb293059dc6f8dbd456c2759cdb9940377e0d5","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        elif len(option_id) !\u003d 4:"},{"line_number":172,"context_line":"            raise ValueError(_(\u0027`option_id` must be 4 characters in \u0027"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"                               \u0027length. Got %r\u0027) % option_id)"},{"line_number":175,"context_line":"        if not isinstance(option_name, six.string_types):"},{"line_number":176,"context_line":"            raise TypeError(_(\u0027`option_name` must be a string. \u0027"},{"line_number":177,"context_line":"                              \u0027Got %r\u0027) % option_name)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_13e655b4","line":174,"updated":"2017-01-26 15:40:11.000000000","message":"we could use:\n\n  % len(option_id))","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"3d03619b3898e20471f375ab2a67dd2a857cb566","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        elif len(option_id) !\u003d 4:"},{"line_number":172,"context_line":"            raise ValueError(_(\u0027`option_id` must be 4 characters in \u0027"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"                               \u0027length. Got %r\u0027) % option_id)"},{"line_number":175,"context_line":"        if not isinstance(option_name, six.string_types):"},{"line_number":176,"context_line":"            raise TypeError(_(\u0027`option_name` must be a string. \u0027"},{"line_number":177,"context_line":"                              \u0027Got %r\u0027) % option_name)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_1eb1f5e1","line":174,"in_reply_to":"3a461143_13e655b4","updated":"2017-01-26 17:28:53.000000000","message":"I wanted to be specific what was actually sent, not just the length.","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"d617e5a262e1d2e5b6f5e66295d99e3c0b3780cd","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        elif len(option_id) !\u003d 4:"},{"line_number":172,"context_line":"            raise ValueError(_(\u0027`option_id` must be 4 characters in \u0027"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"                               \u0027length. Got %r\u0027) % option_id)"},{"line_number":175,"context_line":"        if not isinstance(option_name, six.string_types):"},{"line_number":176,"context_line":"            raise TypeError(_(\u0027`option_name` must be a string. \u0027"},{"line_number":177,"context_line":"                              \u0027Got %r\u0027) % option_name)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_df1684f0","line":174,"in_reply_to":"3a461143_1eb1f5e1","updated":"2017-01-26 19:23:11.000000000","message":"That works, too.","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8ceb293059dc6f8dbd456c2759cdb9940377e0d5","unresolved":false,"context_lines":[{"line_number":174,"context_line":"                               \u0027length. Got %r\u0027) % option_id)"},{"line_number":175,"context_line":"        if not isinstance(option_name, six.string_types):"},{"line_number":176,"context_line":"            raise TypeError(_(\u0027`option_name` must be a string. \u0027"},{"line_number":177,"context_line":"                              \u0027Got %r\u0027) % option_name)"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"        self._option_id \u003d option_id"},{"line_number":180,"context_line":"        self._option_name \u003d option_name"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_f3ff0932","line":177,"updated":"2017-01-26 15:40:11.000000000","message":"We could also output the exact type here - which might make it easier to understand the message:\n\n  \u0027Got %r\u0027) % type(option_name))","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"d617e5a262e1d2e5b6f5e66295d99e3c0b3780cd","unresolved":false,"context_lines":[{"line_number":174,"context_line":"                               \u0027length. Got %r\u0027) % option_id)"},{"line_number":175,"context_line":"        if not isinstance(option_name, six.string_types):"},{"line_number":176,"context_line":"            raise TypeError(_(\u0027`option_name` must be a string. \u0027"},{"line_number":177,"context_line":"                              \u0027Got %r\u0027) % option_name)"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"        self._option_id \u003d option_id"},{"line_number":180,"context_line":"        self._option_name \u003d option_name"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_bf1b781a","line":177,"in_reply_to":"3a461143_9ec5e53d","updated":"2017-01-26 19:23:11.000000000","message":"Aha - nice!","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"3d03619b3898e20471f375ab2a67dd2a857cb566","unresolved":false,"context_lines":[{"line_number":174,"context_line":"                               \u0027length. Got %r\u0027) % option_id)"},{"line_number":175,"context_line":"        if not isinstance(option_name, six.string_types):"},{"line_number":176,"context_line":"            raise TypeError(_(\u0027`option_name` must be a string. \u0027"},{"line_number":177,"context_line":"                              \u0027Got %r\u0027) % option_name)"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"        self._option_id \u003d option_id"},{"line_number":180,"context_line":"        self._option_name \u003d option_name"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_9ec5e53d","line":177,"in_reply_to":"3a461143_f3ff0932","updated":"2017-01-26 17:28:53.000000000","message":"\u0027r\u0027 is repr and should include type.","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"0aca541087873742689ed540d6c677467b6a3d0c","unresolved":false,"context_lines":[{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    @property"},{"line_number":184,"context_line":"    def option_name(self):"},{"line_number":185,"context_line":"        # NOTE(notmorgan) Option IDs should never be set outside of definition"},{"line_number":186,"context_line":"        # time."},{"line_number":187,"context_line":"        return self._option_name"},{"line_number":188,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_d63cd831","line":185,"range":{"start_line":185,"start_character":26,"end_line":185,"end_character":36},"updated":"2017-01-26 01:56:29.000000000","message":"nit: Option names","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"9a74c9710045a5e5c1bf61f406b966b105f99139","unresolved":false,"context_lines":[{"line_number":182,"context_line":""},{"line_number":183,"context_line":"    @property"},{"line_number":184,"context_line":"    def option_name(self):"},{"line_number":185,"context_line":"        # NOTE(notmorgan) Option IDs should never be set outside of definition"},{"line_number":186,"context_line":"        # time."},{"line_number":187,"context_line":"        return self._option_name"},{"line_number":188,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_45266cbb","line":185,"range":{"start_line":185,"start_character":26,"end_line":185,"end_character":36},"in_reply_to":"3a461143_d63cd831","updated":"2017-01-26 04:48:24.000000000","message":"Ty.","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"}],"keystone/common/sql/expand_repo/versions/014_expand_add_user_options.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"e9e2729aa2b6f05150defd16d319055164ec3baf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"5a3905b3_2498ad77","updated":"2017-01-24 16:23:54.000000000","message":"Note to reviewers, the value is not indexed. For filtering on the value (long term future planning) it is assumed you\u0027re already narrowing the search to subsets of users with the option set, often times the option wont be set unless relevant settings (such as \"true\") is the value. A value mirroring the default behavior is not as likely to be set.","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"49e54ca262ded3621e0b495d53fa02f2101b1269","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    user_table \u003d sql.Table(\u0027user\u0027, meta, autoload\u003dTrue)"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    user_options \u003d sql.Table("},{"line_number":24,"context_line":"        \u0027user_options\u0027,"},{"line_number":25,"context_line":"        meta,"},{"line_number":26,"context_line":"        sql.Column(\u0027user_id\u0027, sql.String(64), sql.ForeignKey(user_table.c.id,"},{"line_number":27,"context_line":"                   ondelete\u003d\u0027CASCADE\u0027), nullable\u003dFalse, primary_key\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_cdcf0928","line":24,"range":{"start_line":24,"start_character":9,"end_line":24,"end_character":21},"updated":"2017-01-24 17:53:45.000000000","message":"nit: singular (user_option) would be more consistent with current tables","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"}],"keystone/identity/backends/identity_resource_options.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":2,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":3,"context_line":"# a copy of the License at"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_a8f616d5","line":1,"updated":"2017-01-25 21:39:42.000000000","message":"(nit) any reason to use identity_ in the filename? That seems redundant.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"344e0963303ce320c921025ee0748c71a8ec8afa","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":2,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":3,"context_line":"# a copy of the License at"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_79207e4a","line":1,"in_reply_to":"3a461143_5e5c8825","updated":"2017-01-25 22:28:56.000000000","message":"Your already doing absolute imports here or is it somewhere else you are worried about?","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"2a82130b6deab58e0b8c7f8a8c693cb78f63f593","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":2,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":3,"context_line":"# a copy of the License at"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_6a689ebb","line":1,"in_reply_to":"3a461143_79207e4a","updated":"2017-01-25 23:48:11.000000000","message":"Fixed in next.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":2,"context_line":"# not use this file except in compliance with the License. You may obtain"},{"line_number":3,"context_line":"# a copy of the License at"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_5e5c8825","line":1,"in_reply_to":"3a461143_a8f616d5","updated":"2017-01-25 21:59:06.000000000","message":"Mostly to avoid needing __absolute__ imports","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"b85dd3cd746fb65702be4c6a074184bdbaa7d62f","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"USER_OPTIONS_REGISTRY \u003d resource_options.ResourceOptionRegistry(\u0027USER\u0027)"},{"line_number":17,"context_line":"USER_OPTIONS_LIST \u003d ["},{"line_number":18,"context_line":"    resource_options.ResourceOption(\u0027_TST\u0027, \u0027__PLACEHOLDER__\u0027),"},{"line_number":19,"context_line":"]"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_25bb2fc6","line":17,"updated":"2017-01-25 20:54:17.000000000","message":"This is intentionally here. It ensures we iterate when option lists are evaluated. It is not expected to be used in practice but is important for the framework. We can delete it once we have a real options list (or leave it).\n\nThis has resulted in catching a number of errors in the base construct by forcing normal unit tests to iterate on options even if none are set.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"USER_OPTIONS_REGISTRY \u003d resource_options.ResourceOptionRegistry(\u0027USER\u0027)"},{"line_number":17,"context_line":"USER_OPTIONS_LIST \u003d ["},{"line_number":18,"context_line":"    resource_options.ResourceOption(\u0027_TST\u0027, \u0027__PLACEHOLDER__\u0027),"},{"line_number":19,"context_line":"]"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_28d86653","line":17,"in_reply_to":"3a461143_25bb2fc6","updated":"2017-01-25 21:39:42.000000000","message":"If you would possibly delete it then why not put it in the register function so that it is properly scoped?","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"USER_OPTIONS_REGISTRY \u003d resource_options.ResourceOptionRegistry(\u0027USER\u0027)"},{"line_number":17,"context_line":"USER_OPTIONS_LIST \u003d ["},{"line_number":18,"context_line":"    resource_options.ResourceOption(\u0027_TST\u0027, \u0027__PLACEHOLDER__\u0027),"},{"line_number":19,"context_line":"]"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_fe7374b2","line":17,"in_reply_to":"3a461143_28d86653","updated":"2017-01-25 21:59:06.000000000","message":"The option is what the comment was about, not the list itself.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"344e0963303ce320c921025ee0748c71a8ec8afa","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"USER_OPTIONS_REGISTRY \u003d resource_options.ResourceOptionRegistry(\u0027USER\u0027)"},{"line_number":17,"context_line":"USER_OPTIONS_LIST \u003d ["},{"line_number":18,"context_line":"    resource_options.ResourceOption(\u0027_TST\u0027, \u0027__PLACEHOLDER__\u0027),"},{"line_number":19,"context_line":"]"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_39b436f1","line":17,"in_reply_to":"3a461143_fe7374b2","updated":"2017-01-25 22:28:56.000000000","message":"Ah, i see.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"}],"keystone/identity/backends/resource_options.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"140b67e43d8bc4ef3ddaab328be0d4953c37c3a3","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"USER_OPTIONS_REGISTRY \u003d resource_options.ResourceOptionRegistry(\u0027USER\u0027)"},{"line_number":17,"context_line":"USER_OPTIONS_LIST \u003d ["},{"line_number":18,"context_line":"    # NOTE(notmorgan): This placeholder options can be removed once more"},{"line_number":19,"context_line":"    # options are populated. This forces iteration on possible options for"},{"line_number":20,"context_line":"    # complete test purposes in unit/functional/gate tests outside of the"},{"line_number":21,"context_line":"    # explicit test cases that test resource options. This option is never"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_706eccca","line":18,"range":{"start_line":18,"start_character":46,"end_line":18,"end_character":47},"updated":"2017-01-26 00:17:14.000000000","message":"nit: option","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"}],"keystone/identity/backends/sql.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"9a13d0ce5659814d9214d3a45446837d6106e033","unresolved":false,"context_lines":[{"line_number":175,"context_line":"                if r_opt.option_value is None:"},{"line_number":176,"context_line":"                    # Delete any option set explicitly to None, ignore unset"},{"line_number":177,"context_line":"                    # options."},{"line_number":178,"context_line":"                    user_ref.options.pop(r_opt_cc, None)"},{"line_number":179,"context_line":"                else:"},{"line_number":180,"context_line":"                    # Set any options on the user_ref itself."},{"line_number":181,"context_line":"                    user_ref.options[r_opt_cc] \u003d model.UserOptions("}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_27c3468c","line":178,"range":{"start_line":178,"start_character":20,"end_line":178,"end_character":56},"updated":"2017-01-24 19:21:12.000000000","message":"Any options not in the registry should be dropped here as well with a pop. (future patchset or followup enhancement)","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"49e54ca262ded3621e0b495d53fa02f2101b1269","unresolved":false,"context_lines":[{"line_number":169,"context_line":"                if attr not in model.User.readonly_attributes:"},{"line_number":170,"context_line":"                    setattr(user_ref, attr, getattr(new_user, attr))"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"            # Set the resource options for user in the Attribute Mapping."},{"line_number":173,"context_line":"            for r_opt_cc in new_user.options:"},{"line_number":174,"context_line":"                r_opt \u003d new_user.options[r_opt_cc]"},{"line_number":175,"context_line":"                if r_opt.option_value is None:"},{"line_number":176,"context_line":"                    # Delete any option set explicitly to None, ignore unset"},{"line_number":177,"context_line":"                    # options."},{"line_number":178,"context_line":"                    user_ref.options.pop(r_opt_cc, None)"},{"line_number":179,"context_line":"                else:"},{"line_number":180,"context_line":"                    # Set any options on the user_ref itself."},{"line_number":181,"context_line":"                    user_ref.options[r_opt_cc] \u003d model.UserOptions("},{"line_number":182,"context_line":"                        option_id\u003dr_opt.option_id,"},{"line_number":183,"context_line":"                        option_value\u003dr_opt.option_value)"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"            user_ref.extra \u003d new_user.extra"},{"line_number":186,"context_line":"            return base.filter_user("}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_1095aa87","line":183,"range":{"start_line":172,"start_character":11,"end_line":183,"end_character":56},"updated":"2017-01-24 17:53:45.000000000","message":"I think this would be better suited in the shadow users backend, as you could then apply these options to all users; not just local users. But okay here, as a start.","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"43f576faf0f5082ff5d5c9607fc7aa1d5cee52a4","unresolved":false,"context_lines":[{"line_number":169,"context_line":"                if attr not in model.User.readonly_attributes:"},{"line_number":170,"context_line":"                    setattr(user_ref, attr, getattr(new_user, attr))"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"            # Set the resource options for user in the Attribute Mapping."},{"line_number":173,"context_line":"            for r_opt_cc in new_user.options:"},{"line_number":174,"context_line":"                r_opt \u003d new_user.options[r_opt_cc]"},{"line_number":175,"context_line":"                if r_opt.option_value is None:"},{"line_number":176,"context_line":"                    # Delete any option set explicitly to None, ignore unset"},{"line_number":177,"context_line":"                    # options."},{"line_number":178,"context_line":"                    user_ref.options.pop(r_opt_cc, None)"},{"line_number":179,"context_line":"                else:"},{"line_number":180,"context_line":"                    # Set any options on the user_ref itself."},{"line_number":181,"context_line":"                    user_ref.options[r_opt_cc] \u003d model.UserOptions("},{"line_number":182,"context_line":"                        option_id\u003dr_opt.option_id,"},{"line_number":183,"context_line":"                        option_value\u003dr_opt.option_value)"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"            user_ref.extra \u003d new_user.extra"},{"line_number":186,"context_line":"            return base.filter_user("}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_1353f46d","line":183,"range":{"start_line":172,"start_character":11,"end_line":183,"end_character":56},"in_reply_to":"5a3905b3_1095aa87","updated":"2017-01-24 18:05:14.000000000","message":"Should be easy to shuffle around. as long as the FK constraints don\u0027t change it would be easy to just forklift the code.","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"af1a1c2d8ad4d5b37403b167f6d1b5da1cb3222f","unresolved":false,"context_lines":[{"line_number":169,"context_line":"                if attr not in model.User.readonly_attributes:"},{"line_number":170,"context_line":"                    setattr(user_ref, attr, getattr(new_user, attr))"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"            # Set the resource options for user in the Attribute Mapping."},{"line_number":173,"context_line":"            for r_opt_cc in new_user.options:"},{"line_number":174,"context_line":"                r_opt \u003d new_user.options[r_opt_cc]"},{"line_number":175,"context_line":"                if r_opt.option_value is None:"},{"line_number":176,"context_line":"                    # Delete any option set explicitly to None, ignore unset"},{"line_number":177,"context_line":"                    # options."},{"line_number":178,"context_line":"                    user_ref.options.pop(r_opt_cc, None)"},{"line_number":179,"context_line":"                else:"},{"line_number":180,"context_line":"                    # Set any options on the user_ref itself."},{"line_number":181,"context_line":"                    user_ref.options[r_opt_cc] \u003d model.UserOptions("},{"line_number":182,"context_line":"                        option_id\u003dr_opt.option_id,"},{"line_number":183,"context_line":"                        option_value\u003dr_opt.option_value)"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"            user_ref.extra \u003d new_user.extra"},{"line_number":186,"context_line":"            return base.filter_user("}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_53573c26","line":183,"range":{"start_line":172,"start_character":11,"end_line":183,"end_character":56},"in_reply_to":"5a3905b3_1353f46d","updated":"2017-01-24 18:06:45.000000000","message":"++","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8ceb293059dc6f8dbd456c2759cdb9940377e0d5","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"            # Move options into the proper attribute mapper construct"},{"line_number":202,"context_line":"            resource_options.resource_options_ref_to_mapper("},{"line_number":203,"context_line":"                user_ref, model.UserOption)"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"            user_ref.extra \u003d new_user.extra"},{"line_number":206,"context_line":"            return base.filter_user("}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_6ed5f241","line":203,"updated":"2017-01-26 15:40:11.000000000","message":"We are protected from cases where bad things happen between the two updates because we\u0027re operating from within a context manager, right?\n\nIf something updates the UserOption table, but doesn\u0027t properly update the User table, the context manager should roll things back?","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"3d03619b3898e20471f375ab2a67dd2a857cb566","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"            # Move options into the proper attribute mapper construct"},{"line_number":202,"context_line":"            resource_options.resource_options_ref_to_mapper("},{"line_number":203,"context_line":"                user_ref, model.UserOption)"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"            user_ref.extra \u003d new_user.extra"},{"line_number":206,"context_line":"            return base.filter_user("}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_9edc0514","line":203,"in_reply_to":"3a461143_6ed5f241","updated":"2017-01-26 17:28:53.000000000","message":"Ideally it should be all handled within a transaction afaik, that is the default behavior within the context","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"d617e5a262e1d2e5b6f5e66295d99e3c0b3780cd","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"            # Move options into the proper attribute mapper construct"},{"line_number":202,"context_line":"            resource_options.resource_options_ref_to_mapper("},{"line_number":203,"context_line":"                user_ref, model.UserOption)"},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"            user_ref.extra \u003d new_user.extra"},{"line_number":206,"context_line":"            return base.filter_user("}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_5fe1b4fd","line":203,"in_reply_to":"3a461143_9edc0514","updated":"2017-01-26 19:23:11.000000000","message":"Cool - wfm","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"}],"keystone/identity/backends/sql_model.py":[{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"49e54ca262ded3621e0b495d53fa02f2101b1269","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027name\u0027, \u0027domain_id\u0027, \u0027password\u0027, \u0027enabled\u0027,"},{"line_number":33,"context_line":"                  \u0027default_project_id\u0027, \u0027password_expires_at\u0027]"},{"line_number":34,"context_line":"    readonly_attributes \u003d [\u0027id\u0027, \u0027password_expires_at\u0027]"},{"line_number":35,"context_line":"    resource_options_registry \u003d iro.USER_OPTIONS_REGISTRY"},{"line_number":36,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":37,"context_line":"    _enabled \u003d sql.Column(\u0027enabled\u0027, sql.Boolean)"},{"line_number":38,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_1094ca42","line":35,"range":{"start_line":35,"start_character":4,"end_line":35,"end_character":57},"updated":"2017-01-24 17:53:45.000000000","message":"Why is this part of the User class? I would think the registry would be defined above this class.","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"43f576faf0f5082ff5d5c9607fc7aa1d5cee52a4","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027name\u0027, \u0027domain_id\u0027, \u0027password\u0027, \u0027enabled\u0027,"},{"line_number":33,"context_line":"                  \u0027default_project_id\u0027, \u0027password_expires_at\u0027]"},{"line_number":34,"context_line":"    readonly_attributes \u003d [\u0027id\u0027, \u0027password_expires_at\u0027]"},{"line_number":35,"context_line":"    resource_options_registry \u003d iro.USER_OPTIONS_REGISTRY"},{"line_number":36,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":37,"context_line":"    _enabled \u003d sql.Column(\u0027enabled\u0027, sql.Boolean)"},{"line_number":38,"context_line":"    extra \u003d sql.Column(sql.JsonBlob())"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_5392dcf7","line":35,"range":{"start_line":35,"start_character":4,"end_line":35,"end_character":57},"in_reply_to":"5a3905b3_1094ca42","updated":"2017-01-24 18:05:14.000000000","message":"It is implicitly part of the class itself and should be consumed as such. Similar the group would have it\u0027s own registry. If you pass the class to another function you should see the option registry for it not have to import sql_model to find it.","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"49e54ca262ded3621e0b495d53fa02f2101b1269","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        d \u003d super(User, self).to_dict(include_extra_dict\u003dinclude_extra_dict)"},{"line_number":215,"context_line":"        if \u0027default_project_id\u0027 in d and d[\u0027default_project_id\u0027] is None:"},{"line_number":216,"context_line":"            del d[\u0027default_project_id\u0027]"},{"line_number":217,"context_line":"        for opt in self.resource_options_registry.options:"},{"line_number":218,"context_line":"            if opt.option_id in self.options.keys():"},{"line_number":219,"context_line":"                d[opt.option_name] \u003d self.options[opt.option_id].option_value"},{"line_number":220,"context_line":"        return d"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_d3a32cff","line":217,"range":{"start_line":217,"start_character":8,"end_line":217,"end_character":58},"updated":"2017-01-24 17:53:45.000000000","message":"Do we need to filter out these attributes from v2?","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"7eadab335fe6a316b50261d5bd8cf927382c3d52","unresolved":false,"context_lines":[{"line_number":242,"context_line":"                opt.validator(opt_value)"},{"line_number":243,"context_line":"                resource_options[opt.option_id] \u003d opt_value"},{"line_number":244,"context_line":"        user_obj \u003d super(User, cls).from_dict(new_dict)"},{"line_number":245,"context_line":"        for opt_cc, opt_value in resource_options.items():"},{"line_number":246,"context_line":"            user_obj.options[opt_cc] \u003d UserOptions(opt_cc, opt_value)"},{"line_number":247,"context_line":"        return user_obj"},{"line_number":248,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_2c7b262b","line":245,"range":{"start_line":245,"start_character":16,"end_line":245,"end_character":18},"updated":"2017-01-24 21:17:00.000000000","message":"nit: following your comment about not using cc, opt_id should be used here.","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":16465,"name":"Kristi Nikolla","email":"knikolla@bu.edu","username":"knikolla"},"change_message_id":"7eadab335fe6a316b50261d5bd8cf927382c3d52","unresolved":false,"context_lines":[{"line_number":338,"context_line":"                          primary_key\u003dTrue)"},{"line_number":339,"context_line":""},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"class UserOptions(sql.ModelBase):"},{"line_number":342,"context_line":"    __tablename__ \u003d \u0027user_options\u0027"},{"line_number":343,"context_line":"    user_id \u003d sql.Column(sql.String(64), sql.ForeignKey(\u0027user.id\u0027,"},{"line_number":344,"context_line":"                         ondelete\u003d\u0027CASCADE\u0027), nullable\u003dFalse,"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_ec7afe76","line":341,"range":{"start_line":341,"start_character":6,"end_line":341,"end_character":17},"updated":"2017-01-24 21:17:00.000000000","message":"As rderose pointed out, table name and class name should be in singular.","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":244,"context_line":"                opt.validator(opt_value)"},{"line_number":245,"context_line":"                resource_options[opt.option_id] \u003d opt_value"},{"line_number":246,"context_line":"        user_obj \u003d super(User, cls).from_dict(new_dict)"},{"line_number":247,"context_line":"        setattr(user_obj, \u0027_resource_options\u0027, resource_options)"},{"line_number":248,"context_line":"        return user_obj"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_289a2615","line":247,"updated":"2017-01-25 21:39:42.000000000","message":"Was setattr needed here instead of explicitly setting the attribute?","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":244,"context_line":"                opt.validator(opt_value)"},{"line_number":245,"context_line":"                resource_options[opt.option_id] \u003d opt_value"},{"line_number":246,"context_line":"        user_obj \u003d super(User, cls).from_dict(new_dict)"},{"line_number":247,"context_line":"        setattr(user_obj, \u0027_resource_options\u0027, resource_options)"},{"line_number":248,"context_line":"        return user_obj"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_7eaf84e3","line":247,"in_reply_to":"3a461143_289a2615","updated":"2017-01-25 21:59:06.000000000","message":"I tend to use setattr when dealing with the models, we do similar things in the actual update methods rather than just doing:\n\u003cobj_ref\u003e.\u003cattr\u003e \u003d \u003cvalue\u003e\n\nI am following similar suit.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"344e0963303ce320c921025ee0748c71a8ec8afa","unresolved":false,"context_lines":[{"line_number":244,"context_line":"                opt.validator(opt_value)"},{"line_number":245,"context_line":"                resource_options[opt.option_id] \u003d opt_value"},{"line_number":246,"context_line":"        user_obj \u003d super(User, cls).from_dict(new_dict)"},{"line_number":247,"context_line":"        setattr(user_obj, \u0027_resource_options\u0027, resource_options)"},{"line_number":248,"context_line":"        return user_obj"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_f9870e10","line":247,"in_reply_to":"3a461143_7eaf84e3","updated":"2017-01-25 22:28:56.000000000","message":"fair enough. i don\u0027t feel strong either way. it was just unclear if you were doing some magic or not","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"}],"keystone/tests/unit/common/test_resource_options_common.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":9,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":10,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"# under the License."},{"line_number":12,"context_line":"import uuid"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"from keystone.common import resource_options"},{"line_number":15,"context_line":"from keystone.tests import unit"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_3b098e2d","line":12,"updated":"2017-01-25 21:39:42.000000000","message":"(nit) newline","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":9,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":10,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"# under the License."},{"line_number":12,"context_line":"import uuid"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"from keystone.common import resource_options"},{"line_number":15,"context_line":"from keystone.tests import unit"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_9e9350a3","line":12,"in_reply_to":"3a461143_3b098e2d","updated":"2017-01-25 21:59:06.000000000","message":"If we are enforcing a new line here, it should be part of flake8 checks. Can be fixed in next (or followup)","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        self.assertRaises(ValueError, registry.register_option, option_dup_id)"},{"line_number":48,"context_line":"        self.assertRaises(ValueError, registry.register_option,"},{"line_number":49,"context_line":"                          option_dup_name)"},{"line_number":50,"context_line":"        self.assertIs(1, len(registry._registered_options))"},{"line_number":51,"context_line":"        registry.register_option(option)"},{"line_number":52,"context_line":"        self.assertIs(1, len(registry._registered_options))"},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_1b877262","line":50,"updated":"2017-01-25 21:39:42.000000000","message":"You could just use the public `options` property.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        self.assertRaises(ValueError, registry.register_option, option_dup_id)"},{"line_number":48,"context_line":"        self.assertRaises(ValueError, registry.register_option,"},{"line_number":49,"context_line":"                          option_dup_name)"},{"line_number":50,"context_line":"        self.assertIs(1, len(registry._registered_options))"},{"line_number":51,"context_line":"        registry.register_option(option)"},{"line_number":52,"context_line":"        self.assertIs(1, len(registry._registered_options))"},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_fe81b44e","line":50,"in_reply_to":"3a461143_1b877262","updated":"2017-01-25 21:59:06.000000000","message":"True. Fixed in next (or in followup)","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8ceb293059dc6f8dbd456c2759cdb9940377e0d5","unresolved":false,"context_lines":[{"line_number":29,"context_line":"                          resource_options.ResourceOption,"},{"line_number":30,"context_line":"                          \u0027testing\u0027,"},{"line_number":31,"context_line":"                          \u0027testing\u0027)"},{"line_number":32,"context_line":"        resource_options.ResourceOption(\u0027test\u0027, \u0027testing\u0027)"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def test_duplicate_option_cases(self):"},{"line_number":35,"context_line":"        option_id_str_valid \u003d \u0027test\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_0ea0ee9e","line":32,"updated":"2017-01-26 15:40:11.000000000","message":"OH! The option_id is the actual key... For some reason I was thinking option_id was an ID assigned by keystone, not the actual property key.","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"3d03619b3898e20471f375ab2a67dd2a857cb566","unresolved":false,"context_lines":[{"line_number":29,"context_line":"                          resource_options.ResourceOption,"},{"line_number":30,"context_line":"                          \u0027testing\u0027,"},{"line_number":31,"context_line":"                          \u0027testing\u0027)"},{"line_number":32,"context_line":"        resource_options.ResourceOption(\u0027test\u0027, \u0027testing\u0027)"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def test_duplicate_option_cases(self):"},{"line_number":35,"context_line":"        option_id_str_valid \u003d \u0027test\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_de2bede9","line":32,"in_reply_to":"3a461143_0ea0ee9e","updated":"2017-01-26 17:28:53.000000000","message":"Yep!","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"}],"keystone/tests/unit/core.py":[{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"aed08c617b39944aa0d4d3761100fd9cd62606fe","unresolved":false,"context_lines":[{"line_number":848,"context_line":"                excName \u003d str(expected_exception)"},{"line_number":849,"context_line":"            raise self.failureException(\"%s not raised\" % excName)"},{"line_number":850,"context_line":""},{"line_number":851,"context_line":"    def assertUserDictEqual(self, expected, observed, message\u003d\u0027\u0027):"},{"line_number":852,"context_line":"        \"\"\"Assert that a user dict is equal to another user dict."},{"line_number":853,"context_line":""},{"line_number":854,"context_line":"        User dictionaries have some variable values that should be ignored in"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_df4bf629","line":851,"updated":"2017-01-26 13:51:58.000000000","message":"nice","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"}],"keystone/tests/unit/identity/test_backend_sql.py":[{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"708634505c4625a102109416f6f6aa5c7493f591","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        new_ref \u003d self.identity_api.update_user(user[\u0027id\u0027], user)"},{"line_number":78,"context_line":"        self.assertNotIn(self.option1.option_name, new_ref)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_user_add_option_leaves_existing_option_values(self):"},{"line_number":81,"context_line":"        user \u003d self._create_user(self._get_user_dict())"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"        opt_value \u003d uuid.uuid4().hex"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a3905b3_c46369af","line":80,"range":{"start_line":80,"start_character":18,"end_line":80,"end_character":21},"updated":"2017-01-24 16:21:11.000000000","message":"add / delete","commit_id":"d0b3428170888fae1b6f18b6985ee8b806a2f9b0"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":30,"context_line":"CONF \u003d keystone.conf.CONF"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class UserResourceOptionTests(test_backend_sql.SqlTests):"},{"line_number":34,"context_line":"    def setUp(self):"},{"line_number":35,"context_line":"        super(UserResourceOptionTests, self).setUp()"},{"line_number":36,"context_line":"        # RESET STATE OF REGISTRY OPTIONS"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_bb1ade15","line":33,"updated":"2017-01-25 21:39:42.000000000","message":"None of these tests use get_user to see what comes back. Should we ensure that is also working properly?","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":30,"context_line":"CONF \u003d keystone.conf.CONF"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class UserResourceOptionTests(test_backend_sql.SqlTests):"},{"line_number":34,"context_line":"    def setUp(self):"},{"line_number":35,"context_line":"        super(UserResourceOptionTests, self).setUp()"},{"line_number":36,"context_line":"        # RESET STATE OF REGISTRY OPTIONS"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_fecff4b0","line":33,"in_reply_to":"3a461143_bb1ade15","updated":"2017-01-25 21:59:06.000000000","message":"Will be added in next patch or followup.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"b2af822989dd16535196262f0f249552f354a98d","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        self.option2 \u003d resource_options.ResourceOption(\u0027opt2\u0027, \u0027option2\u0027)"},{"line_number":42,"context_line":"        self.cleanup_instance(\u0027option1\u0027, \u0027option2\u0027)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"        iro.USER_OPTIONS_REGISTRY._clear_registered_options()"},{"line_number":45,"context_line":"        iro.USER_OPTIONS_REGISTRY.register_option(self.option1)"},{"line_number":46,"context_line":"        iro.USER_OPTIONS_REGISTRY.register_option(self.option2)"},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_7b4b162c","line":44,"updated":"2017-01-25 21:39:42.000000000","message":"(nit) Couldn\u0027t you just create a new registry here instead of clearing the existing one?","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"344e0963303ce320c921025ee0748c71a8ec8afa","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        self.option2 \u003d resource_options.ResourceOption(\u0027opt2\u0027, \u0027option2\u0027)"},{"line_number":42,"context_line":"        self.cleanup_instance(\u0027option1\u0027, \u0027option2\u0027)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"        iro.USER_OPTIONS_REGISTRY._clear_registered_options()"},{"line_number":45,"context_line":"        iro.USER_OPTIONS_REGISTRY.register_option(self.option1)"},{"line_number":46,"context_line":"        iro.USER_OPTIONS_REGISTRY.register_option(self.option2)"},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_59b582cb","line":44,"in_reply_to":"3a461143_1ed5a042","updated":"2017-01-25 22:28:56.000000000","message":"I was just thinking about the extra code that shouldn\u0027t be used in production. I typically like code that is only used in tests to be in the test code.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"2a82130b6deab58e0b8c7f8a8c693cb78f63f593","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        self.option2 \u003d resource_options.ResourceOption(\u0027opt2\u0027, \u0027option2\u0027)"},{"line_number":42,"context_line":"        self.cleanup_instance(\u0027option1\u0027, \u0027option2\u0027)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"        iro.USER_OPTIONS_REGISTRY._clear_registered_options()"},{"line_number":45,"context_line":"        iro.USER_OPTIONS_REGISTRY.register_option(self.option1)"},{"line_number":46,"context_line":"        iro.USER_OPTIONS_REGISTRY.register_option(self.option2)"},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_8ac14a83","line":44,"in_reply_to":"3a461143_59b582cb","updated":"2017-01-25 23:48:11.000000000","message":"I guess tests could just muck with the private object, it\u0027s a bit more fair game on that front.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"5815962547a1e61a1c358b12a5a4e70fb4679a18","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        self.option2 \u003d resource_options.ResourceOption(\u0027opt2\u0027, \u0027option2\u0027)"},{"line_number":42,"context_line":"        self.cleanup_instance(\u0027option1\u0027, \u0027option2\u0027)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"        iro.USER_OPTIONS_REGISTRY._clear_registered_options()"},{"line_number":45,"context_line":"        iro.USER_OPTIONS_REGISTRY.register_option(self.option1)"},{"line_number":46,"context_line":"        iro.USER_OPTIONS_REGISTRY.register_option(self.option2)"},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3a461143_1ed5a042","line":44,"in_reply_to":"3a461143_7b4b162c","updated":"2017-01-25 21:59:06.000000000","message":"Registry is a class-attribute for the model, we could replace it, but I opted to keep the same object and offer a clear instead. Not opposed.","commit_id":"155b16e34bb334983a3cd71572a0bcab6858900e"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"8ceb293059dc6f8dbd456c2759cdb9940377e0d5","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        self.addCleanup(iro.register_user_options)"},{"line_number":38,"context_line":"        self.addCleanup(iro.USER_OPTIONS_REGISTRY._registered_options.clear)"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"        self.option1 \u003d resource_options.ResourceOption(\u0027opt1\u0027, \u0027option1\u0027)"},{"line_number":41,"context_line":"        self.option2 \u003d resource_options.ResourceOption(\u0027opt2\u0027, \u0027option2\u0027)"},{"line_number":42,"context_line":"        self.cleanup_instance(\u0027option1\u0027, \u0027option2\u0027)"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_2ee3eaa4","line":40,"updated":"2017-01-26 15:40:11.000000000","message":"Why do we limit option keys to only being 4 characters in length? Can we guarantee that gives us enough uniqueness?","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"3d03619b3898e20471f375ab2a67dd2a857cb566","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        self.addCleanup(iro.register_user_options)"},{"line_number":38,"context_line":"        self.addCleanup(iro.USER_OPTIONS_REGISTRY._registered_options.clear)"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"        self.option1 \u003d resource_options.ResourceOption(\u0027opt1\u0027, \u0027option1\u0027)"},{"line_number":41,"context_line":"        self.option2 \u003d resource_options.ResourceOption(\u0027opt2\u0027, \u0027option2\u0027)"},{"line_number":42,"context_line":"        self.cleanup_instance(\u0027option1\u0027, \u0027option2\u0027)"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3a461143_9e7885f4","line":40,"in_reply_to":"3a461143_2ee3eaa4","updated":"2017-01-26 17:28:53.000000000","message":"This should make for 81450625 combinations [some will suck] assuming only printing ascii characters for each resource type.","commit_id":"1896d1ba0d24d3780ce8c7652fa4c4378a02255d"}]}
