)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":13,"context_line":"Using Credentials, it becomes transparent for client managers"},{"line_number":14,"context_line":"and tests which auth version is being used."},{"line_number":15,"context_line":"Defines a get_default_credentials utils, which is the overall"},{"line_number":16,"context_line":"sole responsible for reading credentials from CONF."},{"line_number":17,"context_line":"Defines a get_credentials, which buils V2 credentials"},{"line_number":18,"context_line":"based on configuration."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"AAAAWH%2F%2BQ%2BA%3D","line":16,"updated":"2014-03-28 01:07:11.000000000","message":"change \"overall sole responsible\" to \"solely responsible\"","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":14,"context_line":"and tests which auth version is being used."},{"line_number":15,"context_line":"Defines a get_default_credentials utils, which is the overall"},{"line_number":16,"context_line":"sole responsible for reading credentials from CONF."},{"line_number":17,"context_line":"Defines a get_credentials, which buils V2 credentials"},{"line_number":18,"context_line":"based on configuration."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Credentials are not used in tests yet, only by AuthProvider."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"AAAAWH%2F%2BQ98%3D","line":17,"updated":"2014-03-28 01:07:11.000000000","message":"change \"buils\" to \"builds\"","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Credentials are not used in tests yet, only by AuthProvider."},{"line_number":21,"context_line":"AuthProvider supports dict credentials in this patch for"},{"line_number":22,"context_line":"backward compatibility. Credentials are verified via unit test."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"Partially implements: bp multi-keystone-api-version-tests"},{"line_number":25,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"AAAAWH%2F%2BQ9w%3D","line":22,"updated":"2014-03-28 01:07:11.000000000","message":"change \"backward\" to \"backwards\"","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"}],"tempest/auth.py":[{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        \"\"\""},{"line_number":46,"context_line":"        # In this patch support dict credentials for backward compatibility"},{"line_number":47,"context_line":"        if isinstance(credentials, dict):"},{"line_number":48,"context_line":"            credentials \u003d get_credentials(**credentials)"},{"line_number":49,"context_line":"        if self.check_credentials(credentials):"},{"line_number":50,"context_line":"            self.credentials \u003d credentials"},{"line_number":51,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F6Ts%3D","line":48,"updated":"2014-03-03 16:55:37.000000000","message":"I guess we can remove this new piece since check_credentials (called on the if bellow) does the same.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        \"\"\""},{"line_number":46,"context_line":"        # In this patch support dict credentials for backward compatibility"},{"line_number":47,"context_line":"        if isinstance(credentials, dict):"},{"line_number":48,"context_line":"            credentials \u003d get_credentials(**credentials)"},{"line_number":49,"context_line":"        if self.check_credentials(credentials):"},{"line_number":50,"context_line":"            self.credentials \u003d credentials"},{"line_number":51,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F0P4%3D","line":48,"in_reply_to":"AAAAVn%2F%2F6Ts%3D","updated":"2014-03-04 10:13:48.000000000","message":"Well it doesn\u0027t do the same exactly. Check is only verifying, this is building a Credentials object out of the dict.\nBut agreed - there is space for improvement here.\n\nI made check_credentials only work with Credentials now, there\u0027s no need to support dict in there.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def fill_credentials(self):"},{"line_number":82,"context_line":"        # trigger auth will fill credentials"},{"line_number":83,"context_line":"        self.auth_data"},{"line_number":84,"context_line":"        return self.credentials"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F6Gs%3D","line":83,"updated":"2014-03-03 16:55:37.000000000","message":"IMHO It\u0027s really weird to have this alone in the line, I would prefer something like getattr(self.auth_data) than this, it would be more clear... ***but it\u0027s just me and this is not a reason to the -1, just a suggestion.*** \u003d)","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def fill_credentials(self):"},{"line_number":82,"context_line":"        # trigger auth will fill credentials"},{"line_number":83,"context_line":"        self.auth_data"},{"line_number":84,"context_line":"        return self.credentials"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F1H4%3D","line":83,"in_reply_to":"AAAAVn%2F%2F6Gs%3D","updated":"2014-03-04 10:13:48.000000000","message":"I agree, it\u0027s not clear. I shall call an helper method instead.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        return self.credentials"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @classmethod"},{"line_number":87,"context_line":"    def check_credentials(cls, credentials):"},{"line_number":88,"context_line":"        \"\"\""},{"line_number":89,"context_line":"        Verify credentials are valid."},{"line_number":90,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F6QI%3D","line":87,"updated":"2014-03-03 16:55:37.000000000","message":"this is really a nit, but I would be more comfortable if this is called validate_credentials or something like that, the check word doesn\u0027t imply the transformation that is done with the dict here.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        return self.credentials"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @classmethod"},{"line_number":87,"context_line":"    def check_credentials(cls, credentials):"},{"line_number":88,"context_line":"        \"\"\""},{"line_number":89,"context_line":"        Verify credentials are valid."},{"line_number":90,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F1Hc%3D","line":87,"in_reply_to":"AAAAVn%2F%2F6QI%3D","updated":"2014-03-04 10:13:48.000000000","message":"This is not really changing the credentials. I removed L92 and L93 now anyways.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        will fetch a new token and base_url."},{"line_number":111,"context_line":"        \"\"\""},{"line_number":112,"context_line":"        self.cache \u003d None"},{"line_number":113,"context_line":"        self.credentials.reset()"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    def is_expired(self, auth_data):"},{"line_number":116,"context_line":"        raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F5w8%3D","line":113,"updated":"2014-03-03 16:55:37.000000000","message":"So I guess I found a problem here, supposing the follow scenario:\n1 - Instantiate a Auth Provider, like version 2 for example.\n2 - clear the auth (will call credentials.reset).\n3 - doing a request the auth_data property will be called (for example during decorate_request) and it will notice that self.cache is none, get a new auth token and everything else, so far so good.\n4 - but then it will call _fill_credentials which checks if attribute is none before set it (which I don\u0027t know a good reason for, but I suspect there is something).\n5 - It will not fill the credential attributes with the new information cause the credentials.reset (called in step 2) reapplies the initial credential setup (line 548), and the _fill_credentials only applies it for None values.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        will fetch a new token and base_url."},{"line_number":111,"context_line":"        \"\"\""},{"line_number":112,"context_line":"        self.cache \u003d None"},{"line_number":113,"context_line":"        self.credentials.reset()"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    def is_expired(self, auth_data):"},{"line_number":116,"context_line":"        raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2Fwv8%3D","line":113,"in_reply_to":"AAAAVn%2F%2F5w8%3D","updated":"2014-03-04 10:13:48.000000000","message":"I\u0027m not sure I get the issue.\nThe purpose of fill credentials is to add the missing (but redundant) attributes to the Credentials class. E.g. if Credentials are created with username, password and tenant_name, fill_credentials will add user_id and tenant_id.\n\nSo in your example:\n1) auth provider is created with credentials with names only\n2) clear auth is called. the reset will delete all credentials and reapply the initial ones, i.e. names only\n3) a request triggers auth, cache is None so token is obtained \n4) fills credentials is also invoked, it will not touch the names, but it will add the IDs","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":253,"context_line":"    def _fill_credentials(self, auth_data_body):"},{"line_number":254,"context_line":"        tenant \u003d auth_data_body[\u0027token\u0027][\u0027tenant\u0027]"},{"line_number":255,"context_line":"        user \u003d auth_data_body[\u0027user\u0027]"},{"line_number":256,"context_line":"        if self.credentials.tenant_name is None:"},{"line_number":257,"context_line":"            self.credentials.tenant_name \u003d tenant[\u0027name\u0027]"},{"line_number":258,"context_line":"        if self.credentials.tenant_id is None:"},{"line_number":259,"context_line":"            self.credentials.tenant_id \u003d tenant[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F5O8%3D","line":256,"updated":"2014-03-03 16:55:37.000000000","message":"what about the scoped flag for set tenant_name that we had in the removed check_credentials? it doesn\u0027t make sense anymore? (same for v3)","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":253,"context_line":"    def _fill_credentials(self, auth_data_body):"},{"line_number":254,"context_line":"        tenant \u003d auth_data_body[\u0027token\u0027][\u0027tenant\u0027]"},{"line_number":255,"context_line":"        user \u003d auth_data_body[\u0027user\u0027]"},{"line_number":256,"context_line":"        if self.credentials.tenant_name is None:"},{"line_number":257,"context_line":"            self.credentials.tenant_name \u003d tenant[\u0027name\u0027]"},{"line_number":258,"context_line":"        if self.credentials.tenant_id is None:"},{"line_number":259,"context_line":"            self.credentials.tenant_id \u003d tenant[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2FwvI%3D","line":256,"in_reply_to":"AAAAVn%2F%2F5O8%3D","updated":"2014-03-04 10:13:48.000000000","message":"I\u0027ll restore it back. It\u0027s never used by tests, but it may be (or should be :)","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":453,"context_line":"        auth_provider_class \u003d KeystoneV2AuthProvider"},{"line_number":454,"context_line":"    elif CONF.identity.auth_version \u003d\u003d \u0027v3\u0027:"},{"line_number":455,"context_line":"        credential_class \u003d KeystoneV3Credentials"},{"line_number":456,"context_line":"        auth_provider_class \u003d KeystoneV3AuthProvider"},{"line_number":457,"context_line":"    if credential_type is not None:"},{"line_number":458,"context_line":"        creds \u003d credential_class.get_default(credential_type)"},{"line_number":459,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F6Wc%3D","line":456,"updated":"2014-03-03 16:55:37.000000000","message":"what do you think about raise an exception here to prevent any invalid version? or this check is somewhere else?","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":453,"context_line":"        auth_provider_class \u003d KeystoneV2AuthProvider"},{"line_number":454,"context_line":"    elif CONF.identity.auth_version \u003d\u003d \u0027v3\u0027:"},{"line_number":455,"context_line":"        credential_class \u003d KeystoneV3Credentials"},{"line_number":456,"context_line":"        auth_provider_class \u003d KeystoneV3AuthProvider"},{"line_number":457,"context_line":"    if credential_type is not None:"},{"line_number":458,"context_line":"        creds \u003d credential_class.get_default(credential_type)"},{"line_number":459,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2Fwt0%3D","line":456,"in_reply_to":"AAAAVn%2F%2F6Wc%3D","updated":"2014-03-04 10:13:48.000000000","message":"ok, done","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":672,"context_line":"        return not ((None in (self.username, self.password)) or"},{"line_number":673,"context_line":"                    (self.domain_name is None and self.project_name is None) or"},{"line_number":674,"context_line":"                    (self.project_name is not None and"},{"line_number":675,"context_line":"                     self.project_domain_name is None))"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F4lI%3D","line":675,"updated":"2014-03-03 16:55:37.000000000","message":"I\u0027m really not sure and confused about this, by the docstring the fields user and pass are mandatory, ok... project_domain also if token is defined but I don\u0027t see anyhing about tokens here, am I missing something?\n\nAnd second one of project_name or project_domain_name must be defined. looking at the condition, we accept self.project_name !\u003d None  and project_domain \u003d\u003dNone but we don\u0027t check the opposite. again, am I missing something?\n\nAlso can we use te attribute names on the docstring?? it\u0027s not easy to figureout that tenant on L669  refers to project.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":672,"context_line":"        return not ((None in (self.username, self.password)) or"},{"line_number":673,"context_line":"                    (self.domain_name is None and self.project_name is None) or"},{"line_number":674,"context_line":"                    (self.project_name is not None and"},{"line_number":675,"context_line":"                     self.project_domain_name is None))"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2FwtA%3D","line":675,"in_reply_to":"AAAAVn%2F%2F4lI%3D","updated":"2014-03-04 10:13:48.000000000","message":"The docstring is wrong, good catch, I\u0027ll fix it.\n\nIt will be now based on http://api.openstack.org/api-ref-identity.html\n\nProvide one of the following sets of credentials to authenticate: User ID and password, user name and password scoped by domain ID or name, user ID and password scoped by project ID or name with or without domain scope, or token.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":43,"context_line":"        :param client_type: \u0027tempest\u0027 or \u0027official\u0027"},{"line_number":44,"context_line":"        :param interface: \u0027json\u0027 or \u0027xml\u0027. Applicable for tempest client only"},{"line_number":45,"context_line":"        \"\"\""},{"line_number":46,"context_line":"        # Support dict credentials for backward compatibility"},{"line_number":47,"context_line":"        credentials \u003d self._convert_credentials(credentials)"},{"line_number":48,"context_line":"        if self.check_credentials(credentials):"},{"line_number":49,"context_line":"            self.credentials \u003d credentials"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ9k%3D","line":46,"updated":"2014-03-28 01:07:11.000000000","message":"change \"backward\" to \"backwards\".\n\nsuggest remove this comment because it\u0027s duplicated at line 61.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"629212bca88a47d2fd15ce9ecd0853ecbc23b528","unresolved":false,"context_lines":[{"line_number":240,"context_line":"            return dict("},{"line_number":241,"context_line":"                user\u003dself.credentials.username,"},{"line_number":242,"context_line":"                password\u003dself.credentials.password,"},{"line_number":243,"context_line":"                tenant\u003dgetattr(self.credentials, \u0027tenant_name\u0027, None),"},{"line_number":244,"context_line":"                auth_data\u003dTrue)"},{"line_number":245,"context_line":"        else:"},{"line_number":246,"context_line":"            raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2Bbyk%3D","line":243,"updated":"2014-03-26 19:53:44.000000000","message":"I don\u0027t like the fact that we have to do this to get around the exception. What\u0027s the rationale for not making tenant_name safe if we always want to use it like this?","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"3753e3a90307e0ae9f9a381375b277b0f0f62e8f","unresolved":false,"context_lines":[{"line_number":240,"context_line":"            return dict("},{"line_number":241,"context_line":"                user\u003dself.credentials.username,"},{"line_number":242,"context_line":"                password\u003dself.credentials.password,"},{"line_number":243,"context_line":"                tenant\u003dgetattr(self.credentials, \u0027tenant_name\u0027, None),"},{"line_number":244,"context_line":"                auth_data\u003dTrue)"},{"line_number":245,"context_line":"        else:"},{"line_number":246,"context_line":"            raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BTsw%3D","line":243,"in_reply_to":"AAAAWH%2F%2BbDg%3D","updated":"2014-03-27 17:55:34.000000000","message":"right, but then why not just return None on self.credentials.tenant_name","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":240,"context_line":"            return dict("},{"line_number":241,"context_line":"                user\u003dself.credentials.username,"},{"line_number":242,"context_line":"                password\u003dself.credentials.password,"},{"line_number":243,"context_line":"                tenant\u003dgetattr(self.credentials, \u0027tenant_name\u0027, None),"},{"line_number":244,"context_line":"                auth_data\u003dTrue)"},{"line_number":245,"context_line":"        else:"},{"line_number":246,"context_line":"            raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ3o%3D","line":243,"in_reply_to":"AAAAWH%2F%2BbDg%3D","updated":"2014-03-28 01:07:11.000000000","message":"typically the user has a default project, in which case you\u0027ll get a scoped token even if there\u0027s no project on the auth request.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3d1ecc8b29d39f381bc823460c9299285ac7cf8b","unresolved":false,"context_lines":[{"line_number":240,"context_line":"            return dict("},{"line_number":241,"context_line":"                user\u003dself.credentials.username,"},{"line_number":242,"context_line":"                password\u003dself.credentials.password,"},{"line_number":243,"context_line":"                tenant\u003dgetattr(self.credentials, \u0027tenant_name\u0027, None),"},{"line_number":244,"context_line":"                auth_data\u003dTrue)"},{"line_number":245,"context_line":"        else:"},{"line_number":246,"context_line":"            raise NotImplementedError"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BbDg%3D","line":243,"in_reply_to":"AAAAWH%2F%2Bbyk%3D","updated":"2014-03-26 21:37:51.000000000","message":"tenant_name is not mandatory. keystone v2 allows for an unscoped token, so I didn\u0027t want to assume here that a tenant will always be provided.\n\nthis is reflected in the validation method L526 as well.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":403,"context_line":""},{"line_number":404,"context_line":"def get_credentials(credential_type\u003dNone, **kwargs):"},{"line_number":405,"context_line":"    \"\"\""},{"line_number":406,"context_line":"    Builds a credentials object based on the configured auth_version"},{"line_number":407,"context_line":"    \"\"\""},{"line_number":408,"context_line":"    if CONF.identity.auth_version \u003d\u003d \u0027v2\u0027:"},{"line_number":409,"context_line":"        credential_class \u003d KeystoneV2Credentials"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ8k%3D","line":406,"updated":"2014-03-28 01:07:11.000000000","message":"it would be great if this docstring said how this function is supposed to work... kwargs is supposed to be ignored if credential_type is set?","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":422,"context_line":"    \"\"\""},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"    ATTRIBUTES \u003d []"},{"line_number":425,"context_line":"    TYPES \u003d [\u0027identity_admin\u0027, \u0027compute_admin\u0027, \u0027user\u0027, \u0027alt_user\u0027]"},{"line_number":426,"context_line":""},{"line_number":427,"context_line":"    def __init__(self, **kwargs):"},{"line_number":428,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ6Y%3D","line":425,"updated":"2014-03-28 01:07:11.000000000","message":"why do we need to hardcode this list? Also, where does this come from?","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":426,"context_line":""},{"line_number":427,"context_line":"    def __init__(self, **kwargs):"},{"line_number":428,"context_line":"        \"\"\""},{"line_number":429,"context_line":"        Enforcing the list of available attributes at init time (only)"},{"line_number":430,"context_line":"        Additional attributes can still be set afterwards it tests need"},{"line_number":431,"context_line":"        to do so."},{"line_number":432,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ64%3D","line":429,"updated":"2014-03-28 01:07:11.000000000","message":"change \"Enforcing\" to \"Enforce\"\n\nremove \"list of\" since that\u0027s an implementation detail.\n\nAdd a . at end of sentence.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":427,"context_line":"    def __init__(self, **kwargs):"},{"line_number":428,"context_line":"        \"\"\""},{"line_number":429,"context_line":"        Enforcing the list of available attributes at init time (only)"},{"line_number":430,"context_line":"        Additional attributes can still be set afterwards it tests need"},{"line_number":431,"context_line":"        to do so."},{"line_number":432,"context_line":"        \"\"\""},{"line_number":433,"context_line":"        self._initial \u003d kwargs"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ6k%3D","line":430,"updated":"2014-03-28 01:07:11.000000000","message":"change \"it tests\" to \"if tests\"","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":430,"context_line":"        Additional attributes can still be set afterwards it tests need"},{"line_number":431,"context_line":"        to do so."},{"line_number":432,"context_line":"        \"\"\""},{"line_number":433,"context_line":"        self._initial \u003d kwargs"},{"line_number":434,"context_line":"        self._apply_credentials(kwargs)"},{"line_number":435,"context_line":""},{"line_number":436,"context_line":"    def _apply_credentials(self, attr):"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ30%3D","line":433,"updated":"2014-03-28 01:07:11.000000000","message":"nothing uses _initial, suggest remove it.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":454,"context_line":"        return str(self) \u003d\u003d str(other)"},{"line_number":455,"context_line":""},{"line_number":456,"context_line":"    def __getattr__(self, key):"},{"line_number":457,"context_line":"        # For know attributes, return None while they are not set"},{"line_number":458,"context_line":"        if key in self.ATTRIBUTES:"},{"line_number":459,"context_line":"            return None"},{"line_number":460,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ6I%3D","line":457,"updated":"2014-03-28 01:07:11.000000000","message":"change \"know\" to \"known\"\n\nchange \"while\" to \"if\"","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":461,"context_line":"            raise AttributeError"},{"line_number":462,"context_line":""},{"line_number":463,"context_line":"    def __delitem__(self, key):"},{"line_number":464,"context_line":"        # For backward compatibility, support dict behaviour"},{"line_number":465,"context_line":"        if key in self.ATTRIBUTES:"},{"line_number":466,"context_line":"            delattr(self, key)"},{"line_number":467,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ6A%3D","line":464,"updated":"2014-03-28 01:07:11.000000000","message":"change \"backward\" to \"backwards\"","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":475,"context_line":"            return default"},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"    @classmethod"},{"line_number":478,"context_line":"    def get_default(cls, ctype):"},{"line_number":479,"context_line":"        if ctype not in cls.TYPES:"},{"line_number":480,"context_line":"            raise exceptions.InvalidCredentials()"},{"line_number":481,"context_line":"        creds \u003d cls._get_default(ctype)"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ5c%3D","line":478,"updated":"2014-03-28 01:07:11.000000000","message":"suggest use a more descriptive name than ctype. credential_type","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":487,"context_line":"    def _get_default(cls, ctype):"},{"line_number":488,"context_line":"        raise NotImplementedError"},{"line_number":489,"context_line":""},{"line_number":490,"context_line":"    def is_valid(self):"},{"line_number":491,"context_line":"        raise NotImplementedError"},{"line_number":492,"context_line":""},{"line_number":493,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ5w%3D","line":490,"updated":"2014-03-28 01:07:11.000000000","message":"suggest use http://docs.python.org/2/library/abc.html for an abstract class.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":516,"context_line":"                password\u003dCONF.identity.admin_password,"},{"line_number":517,"context_line":"                tenant_name\u003dCONF.identity.admin_tenant_name"},{"line_number":518,"context_line":"            )"},{"line_number":519,"context_line":"        elif ctype \u003d\u003d \u0027compute_admin\u0027:"},{"line_number":520,"context_line":"            return KeystoneV2Credentials("},{"line_number":521,"context_line":"                username\u003dCONF.compute_admin.username,"},{"line_number":522,"context_line":"                password\u003dCONF.compute_admin.password,"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ5A%3D","line":519,"updated":"2014-03-28 01:07:11.000000000","message":"the values allowed for ctype in this function are duplicating the list at line 425 ... how about have this function return an error if the ctype isn\u0027t recognized then wouldn\u0027t have to duplicate.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":525,"context_line":""},{"line_number":526,"context_line":"    def is_valid(self):"},{"line_number":527,"context_line":"        \"\"\""},{"line_number":528,"context_line":"        Minimum set of valid credentials, excluding a token,"},{"line_number":529,"context_line":"        are username and password. Tenant is optional."},{"line_number":530,"context_line":"        \"\"\""},{"line_number":531,"context_line":"        return None not in (self.username, self.password)"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ7M%3D","line":528,"updated":"2014-03-28 01:07:11.000000000","message":"what does \"excluding a token\" mean?","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"85065eeaccef594c8d66dec1e5c4be7ef4b7594d","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        # Support dict credentials for backwards compatibility"},{"line_number":61,"context_line":"        if isinstance(credentials, dict):"},{"line_number":62,"context_line":"            return get_credentials(**credentials)"},{"line_number":63,"context_line":"        else:"},{"line_number":64,"context_line":"            return credentials"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def __str__(self):"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F3Bg%3D","line":63,"updated":"2014-04-09 22:08:01.000000000","message":"A valid check here might be to verify it\u0027s a credential class and raise an exception if it isn\u0027t. It\u0027s probably also valid to let it blow up further down the call stack too.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"a4b4213fdabeb190498ffe32c39da2528ffe07ab","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        # Support dict credentials for backwards compatibility"},{"line_number":61,"context_line":"        if isinstance(credentials, dict):"},{"line_number":62,"context_line":"            return get_credentials(**credentials)"},{"line_number":63,"context_line":"        else:"},{"line_number":64,"context_line":"            return credentials"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def __str__(self):"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F0TU%3D","line":63,"in_reply_to":"AAAAW3%2F%2F3Bg%3D","updated":"2014-04-17 07:56:29.000000000","message":"This is just a temporary measure that allows me to first introduce credentials in auth.py and still not change any other class. It is needed to split the introduction of Credentials in changes with a reasonable amount of line changes.\nThe check_credentials method below already check if credentials provided to the AuthProvider are of Credentials class.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7eaa2b593f1f888453a9ea5da863517d096ccece","unresolved":false,"context_lines":[{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    :param credential_type (string): requests credentials from tempest"},{"line_number":408,"context_line":"           configuration file. Valid values are defined in"},{"line_number":409,"context_line":"           Credentials.TYPE."},{"line_number":410,"context_line":"    :param kwargs (dict): take in account only if credential_type is"},{"line_number":411,"context_line":"           not specified or None. Dict of credential key/value pairs"},{"line_number":412,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAWH%2F9NYk%3D","line":409,"updated":"2014-04-07 23:01:11.000000000","message":"this makes me think that this function should be in the Credentials class.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"d0e65a54652ad9d0f939c4f15cc62f11605bd298","unresolved":false,"context_lines":[{"line_number":406,"context_line":""},{"line_number":407,"context_line":"    :param credential_type (string): requests credentials from tempest"},{"line_number":408,"context_line":"           configuration file. Valid values are defined in"},{"line_number":409,"context_line":"           Credentials.TYPE."},{"line_number":410,"context_line":"    :param kwargs (dict): take in account only if credential_type is"},{"line_number":411,"context_line":"           not specified or None. Dict of credential key/value pairs"},{"line_number":412,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAWn%2F%2F9co%3D","line":409,"in_reply_to":"AAAAWH%2F9NYk%3D","updated":"2014-04-08 22:17:08.000000000","message":"the reason why I put this outside of Credentials is that it needs to know about the different versions of Credentials.\nHere it\u0027s just KeystoneV2Credentials, in next patch it will be KeystoneV3Credentials as well. \nI don\u0027t think any of the Credentials class shall depend on the hierarchy of Credentials objects.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7eaa2b593f1f888453a9ea5da863517d096ccece","unresolved":false,"context_lines":[{"line_number":407,"context_line":"    :param credential_type (string): requests credentials from tempest"},{"line_number":408,"context_line":"           configuration file. Valid values are defined in"},{"line_number":409,"context_line":"           Credentials.TYPE."},{"line_number":410,"context_line":"    :param kwargs (dict): take in account only if credential_type is"},{"line_number":411,"context_line":"           not specified or None. Dict of credential key/value pairs"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    Examples:"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAWH%2F9Nb4%3D","line":410,"updated":"2014-04-07 23:01:11.000000000","message":"change \"in account\" to \"into account\u0027","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c48aaf39fb686552b9f6e93c28b6add54712f16d","unresolved":false,"context_lines":[{"line_number":407,"context_line":"    :param credential_type (string): requests credentials from tempest"},{"line_number":408,"context_line":"           configuration file. Valid values are defined in"},{"line_number":409,"context_line":"           Credentials.TYPE."},{"line_number":410,"context_line":"    :param kwargs (dict): take in account only if credential_type is"},{"line_number":411,"context_line":"           not specified or None. Dict of credential key/value pairs"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    Examples:"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAXH%2F%2FO1Q%3D","line":410,"in_reply_to":"AAAAWH%2F9Nb4%3D","updated":"2014-04-23 06:43:00.000000000","message":"Done","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7eaa2b593f1f888453a9ea5da863517d096ccece","unresolved":false,"context_lines":[{"line_number":410,"context_line":"    :param kwargs (dict): take in account only if credential_type is"},{"line_number":411,"context_line":"           not specified or None. Dict of credential key/value pairs"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    Examples:"},{"line_number":414,"context_line":"        Returns credentials from the provided parameters:"},{"line_number":415,"context_line":"        \u003e\u003e\u003e get_credentials(username\u003d\u0027foo\u0027, password\u003d\u0027bar\u0027)"},{"line_number":416,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAWH%2F9NbM%3D","line":413,"updated":"2014-04-07 23:01:11.000000000","message":"add a blank line after this one for rst.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c48aaf39fb686552b9f6e93c28b6add54712f16d","unresolved":false,"context_lines":[{"line_number":410,"context_line":"    :param kwargs (dict): take in account only if credential_type is"},{"line_number":411,"context_line":"           not specified or None. Dict of credential key/value pairs"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    Examples:"},{"line_number":414,"context_line":"        Returns credentials from the provided parameters:"},{"line_number":415,"context_line":"        \u003e\u003e\u003e get_credentials(username\u003d\u0027foo\u0027, password\u003d\u0027bar\u0027)"},{"line_number":416,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAXH%2F%2FO1M%3D","line":413,"in_reply_to":"AAAAWH%2F9NbM%3D","updated":"2014-04-23 06:43:00.000000000","message":"Done","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7eaa2b593f1f888453a9ea5da863517d096ccece","unresolved":false,"context_lines":[{"line_number":441,"context_line":""},{"line_number":442,"context_line":"    ATTRIBUTES \u003d []"},{"line_number":443,"context_line":"    TYPES \u003d {"},{"line_number":444,"context_line":"        \u0027identity_admin\u0027: (\u0027identity\u0027, \u0027admin\u0027),"},{"line_number":445,"context_line":"        \u0027compute_admin\u0027: (\u0027compute_admin\u0027, None),"},{"line_number":446,"context_line":"        \u0027user\u0027: (\u0027identity\u0027, None),"},{"line_number":447,"context_line":"        \u0027alt_user\u0027: (\u0027identity\u0027, \u0027alt\u0027)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAWH%2F9NUE%3D","line":444,"updated":"2014-04-07 23:01:11.000000000","message":"if only python had an enumeration type.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"85065eeaccef594c8d66dec1e5c4be7ef4b7594d","unresolved":false,"context_lines":[{"line_number":441,"context_line":""},{"line_number":442,"context_line":"    ATTRIBUTES \u003d []"},{"line_number":443,"context_line":"    TYPES \u003d {"},{"line_number":444,"context_line":"        \u0027identity_admin\u0027: (\u0027identity\u0027, \u0027admin\u0027),"},{"line_number":445,"context_line":"        \u0027compute_admin\u0027: (\u0027compute_admin\u0027, None),"},{"line_number":446,"context_line":"        \u0027user\u0027: (\u0027identity\u0027, None),"},{"line_number":447,"context_line":"        \u0027alt_user\u0027: (\u0027identity\u0027, \u0027alt\u0027)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F4sk%3D","line":444,"in_reply_to":"AAAAWH%2F9NUE%3D","updated":"2014-04-09 22:08:01.000000000","message":"It was added in python 3.4, not that it helps here.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7eaa2b593f1f888453a9ea5da863517d096ccece","unresolved":false,"context_lines":[{"line_number":478,"context_line":"    def __getattr__(self, key):"},{"line_number":479,"context_line":"        # For known attributes, return None if they are not set"},{"line_number":480,"context_line":"        if key in self.ATTRIBUTES:"},{"line_number":481,"context_line":"            return None"},{"line_number":482,"context_line":"        else:"},{"line_number":483,"context_line":"            raise AttributeError"},{"line_number":484,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAWH%2F9NSo%3D","line":481,"updated":"2014-04-07 23:01:11.000000000","message":"this method returns None for all known attributes, not just the ones that aren\u0027t set.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c48aaf39fb686552b9f6e93c28b6add54712f16d","unresolved":false,"context_lines":[{"line_number":478,"context_line":"    def __getattr__(self, key):"},{"line_number":479,"context_line":"        # For known attributes, return None if they are not set"},{"line_number":480,"context_line":"        if key in self.ATTRIBUTES:"},{"line_number":481,"context_line":"            return None"},{"line_number":482,"context_line":"        else:"},{"line_number":483,"context_line":"            raise AttributeError"},{"line_number":484,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAXH%2F%2FO1I%3D","line":481,"in_reply_to":"AAAAW3%2F%2F2FM%3D","updated":"2014-04-23 06:43:00.000000000","message":"Done","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"d0e65a54652ad9d0f939c4f15cc62f11605bd298","unresolved":false,"context_lines":[{"line_number":478,"context_line":"    def __getattr__(self, key):"},{"line_number":479,"context_line":"        # For known attributes, return None if they are not set"},{"line_number":480,"context_line":"        if key in self.ATTRIBUTES:"},{"line_number":481,"context_line":"            return None"},{"line_number":482,"context_line":"        else:"},{"line_number":483,"context_line":"            raise AttributeError"},{"line_number":484,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAWn%2F%2F9fg%3D","line":481,"in_reply_to":"AAAAWH%2F9NSo%3D","updated":"2014-04-08 22:17:08.000000000","message":"__getattr__ won\u0027t be invoked is the attribute is already set to anything (None included).","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"3ef7fa00c67565c7f9737d0094977d25f25be2ad","unresolved":false,"context_lines":[{"line_number":478,"context_line":"    def __getattr__(self, key):"},{"line_number":479,"context_line":"        # For known attributes, return None if they are not set"},{"line_number":480,"context_line":"        if key in self.ATTRIBUTES:"},{"line_number":481,"context_line":"            return None"},{"line_number":482,"context_line":"        else:"},{"line_number":483,"context_line":"            raise AttributeError"},{"line_number":484,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F2FM%3D","line":481,"in_reply_to":"AAAAWn%2F%2F9fg%3D","updated":"2014-04-10 00:43:53.000000000","message":"Please add a comment to the code to explain this.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"}],"tempest/tests/fake_config.py":[{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        return type.__new__(cls, name, bases, dct)"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"class FakeConfig(object):"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    class fake_compute(object):"},{"line_number":37,"context_line":"        build_interval \u003d 10"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F4dY%3D","line":34,"updated":"2014-03-03 16:55:37.000000000","message":"can you rename this to FakeConfigIdentityV2? so both class follow the same standard","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":31,"context_line":"        return type.__new__(cls, name, bases, dct)"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"class FakeConfig(object):"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    class fake_compute(object):"},{"line_number":37,"context_line":"        build_interval \u003d 10"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2Fv88%3D","line":34,"in_reply_to":"AAAAVn%2F%2F4dY%3D","updated":"2014-03-04 10:13:48.000000000","message":"Done. I have FakeConfig now which is still used by tests which do not need auth_version. FakeConfigIdentityV2 and FakeConfigIdentityV3 both inherit from it.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    compute \u003d FakeConfig.fake_compute()"},{"line_number":102,"context_line":"    identity \u003d fake_identity()"},{"line_number":103,"context_line":"    compute_admin \u003d FakeConfig.fake_compute_admin()"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"class FakeTempestConfigProxy(object):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F4ec%3D","line":103,"updated":"2014-03-03 16:55:37.000000000","message":"Can\u0027t you just inherit from FakeConfig and set auth_version \u003d \u0027v3\u0027? Not sure if I\u0027m missing something else which justifies this whole new class.","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"3ab8d5dbedcd235779bac1b8a11052daefcfbb34","unresolved":false,"context_lines":[{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    compute \u003d FakeConfig.fake_compute()"},{"line_number":102,"context_line":"    identity \u003d fake_identity()"},{"line_number":103,"context_line":"    compute_admin \u003d FakeConfig.fake_compute_admin()"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"class FakeTempestConfigProxy(object):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2Fwks%3D","line":103,"in_reply_to":"AAAAVn%2F%2F4ec%3D","updated":"2014-03-04 10:13:48.000000000","message":"Done","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"7eaa2b593f1f888453a9ea5da863517d096ccece","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                              str(os.environ.get(\u0027OS_TEST_LOCK_PATH\u0027)))"},{"line_number":48,"context_line":"        self.conf.set_default(\u0027auth_version\u0027, \u0027v2\u0027, group\u003d\u0027identity\u0027)"},{"line_number":49,"context_line":"        for item in [\u0027username\u0027, \u0027password\u0027, \u0027tenant_name\u0027]:"},{"line_number":50,"context_line":"            # Identity group items"},{"line_number":51,"context_line":"            for prefix in [\u0027\u0027, \u0027alt_\u0027, \u0027admin_\u0027]:"},{"line_number":52,"context_line":"                self.conf.set_default(prefix + item, \u0027fake_\u0027 + item,"},{"line_number":53,"context_line":"                                      group\u003d\u0027identity\u0027)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAWH%2F9NQU%3D","line":50,"updated":"2014-04-07 23:01:11.000000000","message":"change the variable name to identity_group_item then can get rid of this comment.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c48aaf39fb686552b9f6e93c28b6add54712f16d","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                              str(os.environ.get(\u0027OS_TEST_LOCK_PATH\u0027)))"},{"line_number":48,"context_line":"        self.conf.set_default(\u0027auth_version\u0027, \u0027v2\u0027, group\u003d\u0027identity\u0027)"},{"line_number":49,"context_line":"        for item in [\u0027username\u0027, \u0027password\u0027, \u0027tenant_name\u0027]:"},{"line_number":50,"context_line":"            # Identity group items"},{"line_number":51,"context_line":"            for prefix in [\u0027\u0027, \u0027alt_\u0027, \u0027admin_\u0027]:"},{"line_number":52,"context_line":"                self.conf.set_default(prefix + item, \u0027fake_\u0027 + item,"},{"line_number":53,"context_line":"                                      group\u003d\u0027identity\u0027)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAXH%2F%2FO8s%3D","line":50,"in_reply_to":"AAAAWH%2F9NQU%3D","updated":"2014-04-23 06:43:00.000000000","message":"This comment does not explain \"item\" above, so item is not \"identity_group_item\".\nFor all items in the list I act first on identity group items and then on compute admin group items.\nRenaming item to config_option to avoid confusion.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"}],"tempest/tests/test_auth.py":[{"author":{"_account_id":5174,"name":"Mauro Sergio Martins Rodrigues","email":"maurosr@linux.vnet.ibm.com","username":"maurosr"},"change_message_id":"d542754e4e59e18865373f1e80c510276b79169d","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def test_fill_credentials(self):"},{"line_number":110,"context_line":"        self.assertRaises(NotImplementedError,"},{"line_number":111,"context_line":"                          self.auth_provider.fill_credentials)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"class TestKeystoneV2AuthProvider(BaseAuthTestsSetUp):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAVn%2F%2F4bM%3D","line":111,"updated":"2014-03-03 16:55:37.000000000","message":"imho I don\u0027t really feel like we need to test not implemented stuff, to me this kind of stuff is just like an abstract method. but that is just a suggestion","commit_id":"41cc1b621318eb3cc0a65503d337b06f7aa1829f"}],"tempest/tests/test_credentials.py":[{"author":{"_account_id":7227,"name":"Timur Nurlygayanov","email":"tnurlygayanov@mirantis.com","username":"tnurlygayanov"},"change_message_id":"0dda6aea76f9d4a508e463d2815894e771b7ed92","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            self.assertIsInstance(creds, klass)"},{"line_number":50,"context_line":"            # Check the id attributes are filled in"},{"line_number":51,"context_line":"            for attr in [x for x in creds.ATTRIBUTES if (\u0027_id\u0027 in x and"},{"line_number":52,"context_line":"                                                         x !\u003d \u0027domain_id\u0027)]:"},{"line_number":53,"context_line":"                self.assertIsNone(getattr(creds, attr))"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def test_get_credentials_v2(self):"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAWH%2F%2BqjI%3D","line":52,"updated":"2014-03-25 07:38:44.000000000","message":"I suggest to write this loop in two strings like:\n\nattributes \u003d [x for x in creds.ATTRIBUTES if (\u0027_id\u0027 in x and x !\u003d \u0027domain_id\u0027)]\n\nfor attr in attributes:","commit_id":"3487a69ac30bb495d1560e020c2e6deab58c0039"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def setUp(self):"},{"line_number":73,"context_line":"        super(CredentialsTests, self).setUp()"},{"line_number":74,"context_line":"        # FIXME(andreaf) Do we need those below?"},{"line_number":75,"context_line":"        self.fake_http \u003d fake_http.fake_httplib2(return_type\u003d200)"},{"line_number":76,"context_line":"        self.stubs.Set(http.ClosingHttp, \u0027request\u0027, self.fake_http.request)"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQ0Y%3D","line":74,"updated":"2014-03-28 01:07:11.000000000","message":"fix this.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"b2799b2dac5497f3d4797e6643f852a901900d19","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        creds \u003d self._get_credentials()"},{"line_number":121,"context_line":"        for attr in self.attributes.keys():"},{"line_number":122,"context_line":"            delattr(creds, attr)"},{"line_number":123,"context_line":"            self.assertFalse(creds.is_valid())"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def test_default(self):"},{"line_number":126,"context_line":"        for ctype in self.credentials_class.TYPES:"}],"source_content_type":"text/x-python","patch_set":17,"id":"AAAAWH%2F%2BQzw%3D","line":123,"updated":"2014-03-28 01:07:11.000000000","message":"failure message should have the attr name otherwise there will be no indication which attr was the problem.","commit_id":"06ce46a98d01f6e0e57d75537389ff17f4e89e9b"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"85065eeaccef594c8d66dec1e5c4be7ef4b7594d","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        self.stubs.Set(http.ClosingHttp, \u0027request\u0027, self.identity_response)"},{"line_number":78,"context_line":"        self.stubs.Set(config, \u0027TempestConfigPrivate\u0027, fake_config.FakePrivate)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def _verify_credentials(self, klass, creds_dict):"},{"line_number":81,"context_line":"        creds \u003d auth.get_credentials(**creds_dict)"},{"line_number":82,"context_line":"        # Check the right version of credentials has been returned"},{"line_number":83,"context_line":"        self.assertIsInstance(creds, klass)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F298%3D","line":80,"updated":"2014-04-09 22:08:01.000000000","message":"I\u0027d be inclined to call this credentials_class","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c48aaf39fb686552b9f6e93c28b6add54712f16d","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        self.stubs.Set(http.ClosingHttp, \u0027request\u0027, self.identity_response)"},{"line_number":78,"context_line":"        self.stubs.Set(config, \u0027TempestConfigPrivate\u0027, fake_config.FakePrivate)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def _verify_credentials(self, klass, creds_dict):"},{"line_number":81,"context_line":"        creds \u003d auth.get_credentials(**creds_dict)"},{"line_number":82,"context_line":"        # Check the right version of credentials has been returned"},{"line_number":83,"context_line":"        self.assertIsInstance(creds, klass)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAXH%2F%2FO3g%3D","line":80,"in_reply_to":"AAAAW3%2F%2F298%3D","updated":"2014-04-23 06:43:00.000000000","message":"Done","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"85065eeaccef594c8d66dec1e5c4be7ef4b7594d","unresolved":false,"context_lines":[{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def test_get_credentials(self):"},{"line_number":91,"context_line":"        self.useFixture(fixtures.LockFixture(\u0027auth_version\u0027))"},{"line_number":92,"context_line":"        self._verify_credentials(klass\u003dself.credentials_class,"},{"line_number":93,"context_line":"                                 creds_dict\u003dself.attributes)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def test_is_valid(self):"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F2%2BQ%3D","line":92,"updated":"2014-04-09 22:08:01.000000000","message":"Why use kwargs here?","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c48aaf39fb686552b9f6e93c28b6add54712f16d","unresolved":false,"context_lines":[{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def test_get_credentials(self):"},{"line_number":91,"context_line":"        self.useFixture(fixtures.LockFixture(\u0027auth_version\u0027))"},{"line_number":92,"context_line":"        self._verify_credentials(klass\u003dself.credentials_class,"},{"line_number":93,"context_line":"                                 creds_dict\u003dself.attributes)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def test_is_valid(self):"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAXH%2F%2FO3c%3D","line":92,"in_reply_to":"AAAAW3%2F%2F2%2BQ%3D","updated":"2014-04-23 06:43:00.000000000","message":"Done","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"85065eeaccef594c8d66dec1e5c4be7ef4b7594d","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        for attr in self.attributes.keys():"},{"line_number":102,"context_line":"            delattr(creds, attr)"},{"line_number":103,"context_line":"            self.assertFalse(creds.is_valid(),"},{"line_number":104,"context_line":"                             \"Credentials are valid without %s\" % attr)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def test_default(self):"},{"line_number":107,"context_line":"        self.useFixture(fixtures.LockFixture(\u0027auth_version\u0027))"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F28E%3D","line":104,"updated":"2014-04-09 22:08:01.000000000","message":"I think this message could be a bit clearer. Shouldn\u0027t the credential be invalid without attr? Maybe something like \"Credentials should be invalid without %s\" instead of just stating what happened.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c48aaf39fb686552b9f6e93c28b6add54712f16d","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        for attr in self.attributes.keys():"},{"line_number":102,"context_line":"            delattr(creds, attr)"},{"line_number":103,"context_line":"            self.assertFalse(creds.is_valid(),"},{"line_number":104,"context_line":"                             \"Credentials are valid without %s\" % attr)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def test_default(self):"},{"line_number":107,"context_line":"        self.useFixture(fixtures.LockFixture(\u0027auth_version\u0027))"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAXH%2F%2FO3Y%3D","line":104,"in_reply_to":"AAAAW3%2F%2F28E%3D","updated":"2014-04-23 06:43:00.000000000","message":"Done","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"85065eeaccef594c8d66dec1e5c4be7ef4b7594d","unresolved":false,"context_lines":[{"line_number":104,"context_line":"                             \"Credentials are valid without %s\" % attr)"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    def test_default(self):"},{"line_number":107,"context_line":"        self.useFixture(fixtures.LockFixture(\u0027auth_version\u0027))"},{"line_number":108,"context_line":"        for ctype in self.credentials_class.TYPES:"},{"line_number":109,"context_line":"            creds \u003d self.credentials_class.get_default(credentials_type\u003dctype)"},{"line_number":110,"context_line":"            for attr in self.attributes.keys():"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F27s%3D","line":107,"updated":"2014-04-09 22:08:01.000000000","message":"Things are getting real...","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"85065eeaccef594c8d66dec1e5c4be7ef4b7594d","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        for ctype in self.credentials_class.TYPES:"},{"line_number":109,"context_line":"            creds \u003d self.credentials_class.get_default(credentials_type\u003dctype)"},{"line_number":110,"context_line":"            for attr in self.attributes.keys():"},{"line_number":111,"context_line":"                self.assertEqual(getattr(creds, attr), \u0027fake_\u0027 + attr)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAW3%2F%2F258%3D","line":111,"updated":"2014-04-09 22:08:01.000000000","message":"It might be a bit clearer to do the set_default calls here instead of in the config fixture definition. (or use slightly different ones for this test) It\u0027s a little unclear where the values are coming from here.","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"c48aaf39fb686552b9f6e93c28b6add54712f16d","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        for ctype in self.credentials_class.TYPES:"},{"line_number":109,"context_line":"            creds \u003d self.credentials_class.get_default(credentials_type\u003dctype)"},{"line_number":110,"context_line":"            for attr in self.attributes.keys():"},{"line_number":111,"context_line":"                self.assertEqual(getattr(creds, attr), \u0027fake_\u0027 + attr)"}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAAXH%2F%2FO2E%3D","line":111,"in_reply_to":"AAAAW3%2F%2F258%3D","updated":"2014-04-23 06:43:00.000000000","message":"The defaults in fake_config.py can be used by other tests (they are in later patches). I think a comment here to explain where these values come from could be enough?","commit_id":"d9e2041ae3b07411ed0609cd03bfca2af4fd6a7e"}]}
