)]}'
{"oslo_utils/strutils.py":[{"author":{"_account_id":9796,"name":"ChangBo Guo","email":"glongwave@gmail.com","username":"gcb"},"change_message_id":"2a267bd8c8c2ba7625fdeb9daf83cf4b5c6146f8","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    \u003e\u003e\u003e                     \u0027user\u0027: \u0027admin\u0027,"},{"line_number":300,"context_line":"    \u003e\u003e\u003e                     \u0027home-dir\u0027: \u0027/home/admin\u0027},"},{"line_number":301,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":302,"context_line":"    {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home-dir\u0027: \u0027/home/admin\u0027}"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    .. versionadded:: 3.2.1"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_ba953a41","line":302,"updated":"2015-12-15 03:52:29.000000000","message":"Hmm, you want to support two case here  1)  key in  _SANITIZE_KEYS,  2)  value matches some regexp pattern, and mask the value.\n\nneed  another example  to show  case 2 here.","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"bb54e887ff3a640b9bada961a65d722bcb38a516","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    \u003e\u003e\u003e                     \u0027user\u0027: \u0027admin\u0027,"},{"line_number":300,"context_line":"    \u003e\u003e\u003e                     \u0027home-dir\u0027: \u0027/home/admin\u0027},"},{"line_number":301,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":302,"context_line":"    {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home-dir\u0027: \u0027/home/admin\u0027}"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    .. versionadded:: 3.2.1"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_bfc75511","line":302,"in_reply_to":"5a710552_ba953a41","updated":"2015-12-15 12:24:02.000000000","message":"I do? I actually don\u0027t ... Why would a key in a dictionary be something other than just a simple word?","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"0831b72d55b978876807024f5fa9b3b1c8104a21","unresolved":false,"context_lines":[{"line_number":300,"context_line":"    \u003e\u003e\u003e                     \u0027home-dir\u0027: \u0027/home/admin\u0027},"},{"line_number":301,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":302,"context_line":"    {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home-dir\u0027: \u0027/home/admin\u0027}"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    .. versionadded:: 3.2.1"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_8de7abe3","line":303,"updated":"2015-12-16 00:11:20.000000000","message":"Another way of doing this btw:\n\n\n    def mask_dictionary_password(dictionary, secret\u003d\"***\"):\n        if not isinstance(dictionary, dict):\n            raise TypeError(\"Dictionary expected got %s instead\" % type(dictionary))\n        new_dictionary \u003d dictionary.__class__()\n        for k, v in six.iteritems(dictionary):\n           if k in _SANITIZE_KEYS:\n               v \u003d secret\n           elif isinstance(v, six.string_types):\n               v \u003d mask_password(v, secret\u003dsecret)\n           elif isinstance(v, dict):\n               v \u003d mask_dictionary_password(v, secret\u003dsecret)\n           new_dictionary[k] \u003d v\n        return new_dictionary\n\nFeel free to use that (it handles dicts inside dicts...)","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"989b4bcabcb216bcfc1b3b98a1bd838f76bb3e43","unresolved":false,"context_lines":[{"line_number":300,"context_line":"    \u003e\u003e\u003e                     \u0027home-dir\u0027: \u0027/home/admin\u0027},"},{"line_number":301,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":302,"context_line":"    {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home-dir\u0027: \u0027/home/admin\u0027}"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    .. versionadded:: 3.2.1"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"1a7b0d38_a8e6cb12","line":303,"in_reply_to":"5a710552_8de7abe3","updated":"2015-12-28 20:09:33.000000000","message":"Done","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9796,"name":"ChangBo Guo","email":"glongwave@gmail.com","username":"gcb"},"change_message_id":"2a267bd8c8c2ba7625fdeb9daf83cf4b5c6146f8","unresolved":false,"context_lines":[{"line_number":301,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":302,"context_line":"    {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home-dir\u0027: \u0027/home/admin\u0027}"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    .. versionadded:: 3.2.1"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    \"\"\""},{"line_number":307,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_3a886a22","line":304,"updated":"2015-12-15 03:52:29.000000000","message":"I don\u0027t think we will release with 3.2.1 , maybe 3.3","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"989b4bcabcb216bcfc1b3b98a1bd838f76bb3e43","unresolved":false,"context_lines":[{"line_number":301,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":302,"context_line":"    {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home-dir\u0027: \u0027/home/admin\u0027}"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    .. versionadded:: 3.2.1"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    \"\"\""},{"line_number":307,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"1a7b0d38_48ef27e9","line":304,"in_reply_to":"5a710552_3a886a22","updated":"2015-12-28 20:09:33.000000000","message":"Done","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9796,"name":"ChangBo Guo","email":"glongwave@gmail.com","username":"gcb"},"change_message_id":"2a267bd8c8c2ba7625fdeb9daf83cf4b5c6146f8","unresolved":false,"context_lines":[{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    out \u003d {}"},{"line_number":309,"context_line":""},{"line_number":310,"context_line":"    for k, v in dictionary.iteritems():"},{"line_number":311,"context_line":"        for key in _SANITIZE_KEYS:"},{"line_number":312,"context_line":"            if key \u003d\u003d k:"},{"line_number":313,"context_line":"                v \u003d secret"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_47955fe2","line":310,"updated":"2015-12-15 03:52:29.000000000","message":"use six.iteritems(dictionary)\n\nhttps://pythonhosted.org/six/#six.iteritems","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"989b4bcabcb216bcfc1b3b98a1bd838f76bb3e43","unresolved":false,"context_lines":[{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    out \u003d {}"},{"line_number":309,"context_line":""},{"line_number":310,"context_line":"    for k, v in dictionary.iteritems():"},{"line_number":311,"context_line":"        for key in _SANITIZE_KEYS:"},{"line_number":312,"context_line":"            if key \u003d\u003d k:"},{"line_number":313,"context_line":"                v \u003d secret"}],"source_content_type":"text/x-python","patch_set":1,"id":"1a7b0d38_68ec63f3","line":310,"in_reply_to":"5a710552_080e363b","updated":"2015-12-28 20:09:33.000000000","message":"Done","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b754a4a621bf5e982d5eb3033b10b6cd0d8b59b1","unresolved":false,"context_lines":[{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    out \u003d {}"},{"line_number":309,"context_line":""},{"line_number":310,"context_line":"    for k, v in dictionary.iteritems():"},{"line_number":311,"context_line":"        for key in _SANITIZE_KEYS:"},{"line_number":312,"context_line":"            if key \u003d\u003d k:"},{"line_number":313,"context_line":"                v \u003d secret"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_080e363b","line":310,"in_reply_to":"5a710552_47955fe2","updated":"2015-12-16 09:58:14.000000000","message":"Nope, just use dictionary.items() :-)\n\nhttps://wiki.openstack.org/wiki/Python3#Common_patterns","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b754a4a621bf5e982d5eb3033b10b6cd0d8b59b1","unresolved":false,"context_lines":[{"line_number":309,"context_line":""},{"line_number":310,"context_line":"    for k, v in dictionary.iteritems():"},{"line_number":311,"context_line":"        for key in _SANITIZE_KEYS:"},{"line_number":312,"context_line":"            if key \u003d\u003d k:"},{"line_number":313,"context_line":"                v \u003d secret"},{"line_number":314,"context_line":"            else:"},{"line_number":315,"context_line":"                v \u003d mask_password(v, secret)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_cb04a8c1","line":312,"updated":"2015-12-16 09:58:14.000000000","message":"I agree that a regex should be used here to mask also {\u0027--password\u0027: \u0027s3cr3t\u0027}","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9796,"name":"ChangBo Guo","email":"glongwave@gmail.com","username":"gcb"},"change_message_id":"2a267bd8c8c2ba7625fdeb9daf83cf4b5c6146f8","unresolved":false,"context_lines":[{"line_number":312,"context_line":"            if key \u003d\u003d k:"},{"line_number":313,"context_line":"                v \u003d secret"},{"line_number":314,"context_line":"            else:"},{"line_number":315,"context_line":"                v \u003d mask_password(v, secret)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"        out[k] \u003d v"},{"line_number":318,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_5a945636","line":315,"updated":"2015-12-15 03:52:29.000000000","message":"How about :\n\nif  k in  _SANITIZE_KEYS:\n    v \u003d secret\nelse:\n    v \u003d mask_password(v, secret)","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b754a4a621bf5e982d5eb3033b10b6cd0d8b59b1","unresolved":false,"context_lines":[{"line_number":312,"context_line":"            if key \u003d\u003d k:"},{"line_number":313,"context_line":"                v \u003d secret"},{"line_number":314,"context_line":"            else:"},{"line_number":315,"context_line":"                v \u003d mask_password(v, secret)"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"        out[k] \u003d v"},{"line_number":318,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5a710552_cb91089b","line":315,"in_reply_to":"5a710552_5a945636","updated":"2015-12-16 09:58:14.000000000","message":"I don\u0027t think that you should call mask_password() on the *value*.\n\nIf you want to mask value, use a dict comprehension:\n\n{key: mask_password(value) for key, value in dict.items()}\n\nYou should explain in the docstring that only the keys are used to decide if the value is masked or not, value content is not tested. You may even give the example of the dict comprehension to be cristal clear.","commit_id":"c036b0459eb47f5c08b8a7f1bff2a140d959cc93"},{"author":{"_account_id":9796,"name":"ChangBo Guo","email":"glongwave@gmail.com","username":"gcb"},"change_message_id":"1f967be8acff7320bfe6aba0a2b5a45cfabda642","unresolved":false,"context_lines":[{"line_number":315,"context_line":"        elif isinstance(v, six.string_types):"},{"line_number":316,"context_line":"            v \u003d mask_password(v, secret\u003dsecret)"},{"line_number":317,"context_line":"        elif isinstance(v, dict):"},{"line_number":318,"context_line":"            v \u003d mask_dictionary_password(dict, secret\u003dsecret)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        out[k] \u003d v"},{"line_number":321,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a7b0d38_e84b6e85","line":318,"range":{"start_line":318,"start_character":60,"end_line":318,"end_character":61},"updated":"2015-12-29 04:59:17.000000000","message":"s/dict,/v,\n\nI think we need a test for nested dictionary.","commit_id":"fc82876f74e98f793080f84ab0154b55edd590f4"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"262480fd4ed9d5762f10495a49e89ec0257c6bb1","unresolved":false,"context_lines":[{"line_number":315,"context_line":"        elif isinstance(v, six.string_types):"},{"line_number":316,"context_line":"            v \u003d mask_password(v, secret\u003dsecret)"},{"line_number":317,"context_line":"        elif isinstance(v, dict):"},{"line_number":318,"context_line":"            v \u003d mask_dictionary_password(dict, secret\u003dsecret)"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        out[k] \u003d v"},{"line_number":321,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a7b0d38_b42a988e","line":318,"range":{"start_line":318,"start_character":60,"end_line":318,"end_character":61},"in_reply_to":"1a7b0d38_e84b6e85","updated":"2015-12-29 11:40:37.000000000","message":"clearly ;(","commit_id":"fc82876f74e98f793080f84ab0154b55edd590f4"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":287,"context_line":"    return message"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"def mask_dictionary_password(dictionary, secret\u003d\"***\"):  # nosec"},{"line_number":291,"context_line":"    \"\"\"Replace password with *secret* in a dictionary recursively."},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"    :param dictionary: The dictionary which includes security information."}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_4ec76745","line":290,"range":{"start_line":290,"start_character":4,"end_line":290,"end_character":28},"updated":"2016-01-04 09:51:10.000000000","message":"The Python type is called \"dict\", so I suggest to rename the function to mask_dict_password() to get a shorter name.","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":287,"context_line":"    return message"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"def mask_dictionary_password(dictionary, secret\u003d\"***\"):  # nosec"},{"line_number":291,"context_line":"    \"\"\"Replace password with *secret* in a dictionary recursively."},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"    :param dictionary: The dictionary which includes security information."}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_6ee82bb5","line":290,"range":{"start_line":290,"start_character":62,"end_line":290,"end_character":63},"updated":"2016-01-04 09:51:10.000000000","message":"Why do you need a #nosec comment here?","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"1d3e28b6f32b2504376a7de3fc2165b0f872a79b","unresolved":false,"context_lines":[{"line_number":287,"context_line":"    return message"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"def mask_dictionary_password(dictionary, secret\u003d\"***\"):  # nosec"},{"line_number":291,"context_line":"    \"\"\"Replace password with *secret* in a dictionary recursively."},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"    :param dictionary: The dictionary which includes security information."}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_7586b314","line":290,"range":{"start_line":290,"start_character":4,"end_line":290,"end_character":28},"in_reply_to":"fa69d971_4ec76745","updated":"2016-01-04 13:22:25.000000000","message":"You mean, like the example below shows ;)","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"1d3e28b6f32b2504376a7de3fc2165b0f872a79b","unresolved":false,"context_lines":[{"line_number":287,"context_line":"    return message"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"def mask_dictionary_password(dictionary, secret\u003d\"***\"):  # nosec"},{"line_number":291,"context_line":"    \"\"\"Replace password with *secret* in a dictionary recursively."},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"    :param dictionary: The dictionary which includes security information."}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_559a8f64","line":290,"range":{"start_line":290,"start_character":62,"end_line":290,"end_character":63},"in_reply_to":"fa69d971_6ee82bb5","updated":"2016-01-04 13:22:25.000000000","message":"Done","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":288,"context_line":""},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"def mask_dictionary_password(dictionary, secret\u003d\"***\"):  # nosec"},{"line_number":291,"context_line":"    \"\"\"Replace password with *secret* in a dictionary recursively."},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"    :param dictionary: The dictionary which includes security information."},{"line_number":294,"context_line":"    :param secret: value with which to replace passwords."}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_4e1d270e","line":291,"range":{"start_line":291,"start_character":30,"end_line":291,"end_character":36},"updated":"2016-01-04 09:51:10.000000000","message":"I dislike the current documentation. It\u0027s unclear if keys and/or values are modified. Even worse, it doesn\u0027t explain that dict values are only replaced depending on the dict keys, which is non obvious.\n\nYou should also mention that nested dictionaries are also supported.","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"1d3e28b6f32b2504376a7de3fc2165b0f872a79b","unresolved":false,"context_lines":[{"line_number":288,"context_line":""},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"def mask_dictionary_password(dictionary, secret\u003d\"***\"):  # nosec"},{"line_number":291,"context_line":"    \"\"\"Replace password with *secret* in a dictionary recursively."},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"    :param dictionary: The dictionary which includes security information."},{"line_number":294,"context_line":"    :param secret: value with which to replace passwords."}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_755eb377","line":291,"range":{"start_line":291,"start_character":30,"end_line":291,"end_character":36},"in_reply_to":"fa69d971_4e1d270e","updated":"2016-01-04 13:22:25.000000000","message":"Done","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":294,"context_line":"    :param secret: value with which to replace passwords."},{"line_number":295,"context_line":"    :returns: The dictionary with string substitutions."},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"    For example:"},{"line_number":298,"context_line":"    \u003e\u003e\u003e mask_dict_password({\u0027password\u0027: \u0027d81juxmEW_\u0027,"},{"line_number":299,"context_line":"    \u003e\u003e\u003e                     \u0027user\u0027: \u0027admin\u0027,"},{"line_number":300,"context_line":"    \u003e\u003e\u003e                     \u0027home-dir\u0027: \u0027/home/admin\u0027},"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_ae2dc347","line":297,"range":{"start_line":297,"start_character":8,"end_line":297,"end_character":15},"updated":"2016-01-04 09:51:10.000000000","message":"add an empty line for readability","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"1d3e28b6f32b2504376a7de3fc2165b0f872a79b","unresolved":false,"context_lines":[{"line_number":294,"context_line":"    :param secret: value with which to replace passwords."},{"line_number":295,"context_line":"    :returns: The dictionary with string substitutions."},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"    For example:"},{"line_number":298,"context_line":"    \u003e\u003e\u003e mask_dict_password({\u0027password\u0027: \u0027d81juxmEW_\u0027,"},{"line_number":299,"context_line":"    \u003e\u003e\u003e                     \u0027user\u0027: \u0027admin\u0027,"},{"line_number":300,"context_line":"    \u003e\u003e\u003e                     \u0027home-dir\u0027: \u0027/home/admin\u0027},"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_75ec738f","line":297,"range":{"start_line":297,"start_character":8,"end_line":297,"end_character":15},"in_reply_to":"fa69d971_ae2dc347","updated":"2016-01-04 13:22:25.000000000","message":"Done","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":301,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":302,"context_line":"    {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home-dir\u0027: \u0027/home/admin\u0027}"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    For example:"},{"line_number":305,"context_line":"    \u003e\u003e\u003e mask_dict_password({\"nested\": {\u0027password\u0027: \u0027d81juxmEW_\u0027,"},{"line_number":306,"context_line":"    \u003e\u003e\u003e                     \u0027user\u0027: \u0027admin\u0027,"},{"line_number":307,"context_line":"    \u003e\u003e\u003e                     \u0027home\u0027: \u0027/home/admin\u0027}},"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_6e27cb64","line":304,"range":{"start_line":304,"start_character":8,"end_line":304,"end_character":15},"updated":"2016-01-04 09:51:10.000000000","message":"ditto","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"1d3e28b6f32b2504376a7de3fc2165b0f872a79b","unresolved":false,"context_lines":[{"line_number":301,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":302,"context_line":"    {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home-dir\u0027: \u0027/home/admin\u0027}"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    For example:"},{"line_number":305,"context_line":"    \u003e\u003e\u003e mask_dict_password({\"nested\": {\u0027password\u0027: \u0027d81juxmEW_\u0027,"},{"line_number":306,"context_line":"    \u003e\u003e\u003e                     \u0027user\u0027: \u0027admin\u0027,"},{"line_number":307,"context_line":"    \u003e\u003e\u003e                     \u0027home\u0027: \u0027/home/admin\u0027}},"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_15041748","line":304,"range":{"start_line":304,"start_character":8,"end_line":304,"end_character":15},"in_reply_to":"fa69d971_6e27cb64","updated":"2016-01-04 13:22:25.000000000","message":"Done","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":319,"context_line":"    for k, v in dictionary.items():"},{"line_number":320,"context_line":"        if k in _SANITIZE_KEYS:"},{"line_number":321,"context_line":"            v \u003d secret"},{"line_number":322,"context_line":"        elif isinstance(v, six.string_types):"},{"line_number":323,"context_line":"            v \u003d mask_password(v, secret\u003dsecret)"},{"line_number":324,"context_line":"        elif isinstance(v, dict):"},{"line_number":325,"context_line":"            v \u003d mask_dictionary_password(v, secret\u003dsecret)"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_0eef2fb1","line":322,"range":{"start_line":322,"start_character":31,"end_line":322,"end_character":43},"updated":"2016-01-04 09:51:10.000000000","message":"mask_password() doesn\u0027t not support bytes on Python 3: it uses six.text_type(value). For example, b\u0027hello\u0027 is replaced with \"b\u0027hello\u0027\" (b\u0027...\u0027 is not really expected).\n\nI would prefer to have a stronger API in this new function and only isinstance(v, six.string_types): accept str (bytes) and unicode on Python 2, but only str (unicode) on Python 3.\n\nMaybe we should enhance mask_password() to have a better support for bytes/unicode on py2/py3. (For example, explicitly reject bytes on Python 3?)","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"1d3e28b6f32b2504376a7de3fc2165b0f872a79b","unresolved":false,"context_lines":[{"line_number":319,"context_line":"    for k, v in dictionary.items():"},{"line_number":320,"context_line":"        if k in _SANITIZE_KEYS:"},{"line_number":321,"context_line":"            v \u003d secret"},{"line_number":322,"context_line":"        elif isinstance(v, six.string_types):"},{"line_number":323,"context_line":"            v \u003d mask_password(v, secret\u003dsecret)"},{"line_number":324,"context_line":"        elif isinstance(v, dict):"},{"line_number":325,"context_line":"            v \u003d mask_dictionary_password(v, secret\u003dsecret)"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_55136f66","line":322,"range":{"start_line":322,"start_character":31,"end_line":322,"end_character":43},"in_reply_to":"fa69d971_0eef2fb1","updated":"2016-01-04 13:22:25.000000000","message":"I\u0027ll catch you on IRC to understand this more.","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":321,"context_line":"            v \u003d secret"},{"line_number":322,"context_line":"        elif isinstance(v, six.string_types):"},{"line_number":323,"context_line":"            v \u003d mask_password(v, secret\u003dsecret)"},{"line_number":324,"context_line":"        elif isinstance(v, dict):"},{"line_number":325,"context_line":"            v \u003d mask_dictionary_password(v, secret\u003dsecret)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"        out[k] \u003d v"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_4ea0c790","line":324,"range":{"start_line":324,"start_character":13,"end_line":324,"end_character":23},"updated":"2016-01-04 09:51:10.000000000","message":"IMHO this check must be the first one: see also my comment on tests.","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"1d3e28b6f32b2504376a7de3fc2165b0f872a79b","unresolved":false,"context_lines":[{"line_number":321,"context_line":"            v \u003d secret"},{"line_number":322,"context_line":"        elif isinstance(v, six.string_types):"},{"line_number":323,"context_line":"            v \u003d mask_password(v, secret\u003dsecret)"},{"line_number":324,"context_line":"        elif isinstance(v, dict):"},{"line_number":325,"context_line":"            v \u003d mask_dictionary_password(v, secret\u003dsecret)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"        out[k] \u003d v"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_7516b356","line":324,"range":{"start_line":324,"start_character":13,"end_line":324,"end_character":23},"in_reply_to":"fa69d971_4ea0c790","updated":"2016-01-04 13:22:25.000000000","message":"Done","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"a271954b2f2b2ca9fe370d7857e4f6337cd93c41","unresolved":false,"context_lines":[{"line_number":297,"context_line":"    :A dictionary (which may contain nested dictionaries) contains"},{"line_number":298,"context_line":"    :information (such as passwords) which should not be revealed, and"},{"line_number":299,"context_line":"    :this function helps detect and replace those with the \u0027secret\u0027"},{"line_number":300,"context_line":"    :provided (or \u0027***\u0027 if none is provided)."},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"    :Substitution is performed in one of three situations:"},{"line_number":303,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"fa69d971_1ad0be1e","line":300,"range":{"start_line":300,"start_character":5,"end_line":300,"end_character":13},"updated":"2016-01-04 15:34:47.000000000","message":"You must not use \":\" here, see the output:\n\nhttp://docs-draft.openstack.org/61/257561/4/check/gate-oslo.utils-docs/6c1924f//doc/build/html/api/strutils.html\n\n(click on the docs job on gerrit)","commit_id":"99addfc8ad929a1fff53a96bc905c90ecb3b4244"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"ff00381b30fe7fea73dfcf8e423f5051d7d46e88","unresolved":false,"context_lines":[{"line_number":297,"context_line":"    :A dictionary (which may contain nested dictionaries) contains"},{"line_number":298,"context_line":"    :information (such as passwords) which should not be revealed, and"},{"line_number":299,"context_line":"    :this function helps detect and replace those with the \u0027secret\u0027"},{"line_number":300,"context_line":"    :provided (or \u0027***\u0027 if none is provided)."},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"    :Substitution is performed in one of three situations:"},{"line_number":303,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"fa69d971_1f1d0d0f","line":300,"range":{"start_line":300,"start_character":5,"end_line":300,"end_character":13},"in_reply_to":"fa69d971_1ad0be1e","updated":"2016-01-04 16:23:25.000000000","message":"The issue was with the use of \":\" on each line. (I think)","commit_id":"99addfc8ad929a1fff53a96bc905c90ecb3b4244"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"a271954b2f2b2ca9fe370d7857e4f6337cd93c41","unresolved":false,"context_lines":[{"line_number":302,"context_line":"    :Substitution is performed in one of three situations:"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    :The same _SANITIZE_KEYS used by mask_password() are used here"},{"line_number":305,"context_line":"    :and if a dictionary contains a key that is in the _SANITIZE_KEYS,"},{"line_number":306,"context_line":"    :then the corresponding value is replaced with the \u0027secret\u0027."},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    :If a value in the dictionary is a string, then it is masked"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa69d971_3a926258","line":305,"range":{"start_line":305,"start_character":25,"end_line":305,"end_character":33},"updated":"2016-01-04 15:34:47.000000000","message":"You should not mention _SANITIZE_KEYS, since it\u0027s private.","commit_id":"99addfc8ad929a1fff53a96bc905c90ecb3b4244"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"a0a6431994869ab566d6b7f48840f5da3217c7c5","unresolved":false,"context_lines":[{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    If the key is something that is considered to be indicative of a"},{"line_number":305,"context_line":"    secret, then the corresponding value is replaced with the secret"},{"line_number":306,"context_line":"    provided (or \u0027***\u0027 if none is provided."},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    If a value in the dictionary is a string, then it is masked"},{"line_number":309,"context_line":"    using the mask_password() function."}],"source_content_type":"text/x-python","patch_set":5,"id":"fa69d971_39b3229a","line":306,"range":{"start_line":306,"start_character":42,"end_line":306,"end_character":43},"updated":"2016-01-05 13:34:49.000000000","message":"the parenthesis is not closed :-/","commit_id":"a163db5d27c044ac92cd93aa348b5fff7fa910fb"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"603eb5ba5946cf5f9ac1f069d920a49be72d3ada","unresolved":false,"context_lines":[{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    If the key is something that is considered to be indicative of a"},{"line_number":305,"context_line":"    secret, then the corresponding value is replaced with the secret"},{"line_number":306,"context_line":"    provided (or \u0027***\u0027 if none is provided."},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    If a value in the dictionary is a string, then it is masked"},{"line_number":309,"context_line":"    using the mask_password() function."}],"source_content_type":"text/x-python","patch_set":5,"id":"fa69d971_76044449","line":306,"range":{"start_line":306,"start_character":42,"end_line":306,"end_character":43},"in_reply_to":"fa69d971_39b3229a","updated":"2016-01-05 14:21:35.000000000","message":"oh, and there\u0027s no hacking rule to catch that ;)","commit_id":"a163db5d27c044ac92cd93aa348b5fff7fa910fb"},{"author":{"_account_id":8119,"name":"Eric Brown","email":"eric_wade_brown@yahoo.com","username":"ericwb"},"change_message_id":"63e66c3c15035bf1cb46c980d9156312d8d0864a","unresolved":false,"context_lines":[{"line_number":336,"context_line":"    \u003e\u003e\u003e                     \u0027home\u0027: \u0027/home/admin\u0027}},"},{"line_number":337,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":338,"context_line":"    {\"nested\": {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home\u0027: \u0027/home/admin\u0027}}"},{"line_number":339,"context_line":""},{"line_number":340,"context_line":"    \"\"\""},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    if not isinstance(dictionary, dict):"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa69d971_76d0b9f6","line":339,"updated":"2016-01-05 17:42:55.000000000","message":"Can you add versionadded for this new function?","commit_id":"c8833bad708c55ac5889744443a159f508682fe7"},{"author":{"_account_id":8119,"name":"Eric Brown","email":"eric_wade_brown@yahoo.com","username":"ericwb"},"change_message_id":"a2e983527ac419b0884da1f4f2614a9ec64a6073","unresolved":false,"context_lines":[{"line_number":336,"context_line":"    \u003e\u003e\u003e                     \u0027home\u0027: \u0027/home/admin\u0027}},"},{"line_number":337,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":338,"context_line":"    {\"nested\": {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home\u0027: \u0027/home/admin\u0027}}"},{"line_number":339,"context_line":""},{"line_number":340,"context_line":"    \"\"\""},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    if not isinstance(dictionary, dict):"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa69d971_a757d958","line":339,"in_reply_to":"fa69d971_11f067fd","updated":"2016-01-05 18:54:26.000000000","message":"Should be 3.4 currently.","commit_id":"c8833bad708c55ac5889744443a159f508682fe7"},{"author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"change_message_id":"081b2669581f5c4ee4eb1820cc0a1fe731181a0e","unresolved":false,"context_lines":[{"line_number":336,"context_line":"    \u003e\u003e\u003e                     \u0027home\u0027: \u0027/home/admin\u0027}},"},{"line_number":337,"context_line":"    \u003e\u003e\u003e                     \u0027???\u0027)"},{"line_number":338,"context_line":"    {\"nested\": {\u0027password\u0027: \u0027???\u0027, \u0027user\u0027: \u0027admin\u0027, \u0027home\u0027: \u0027/home/admin\u0027}}"},{"line_number":339,"context_line":""},{"line_number":340,"context_line":"    \"\"\""},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    if not isinstance(dictionary, dict):"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa69d971_11f067fd","line":339,"in_reply_to":"fa69d971_76d0b9f6","updated":"2016-01-05 17:49:29.000000000","message":"Sure, I had it in an earlier change set but removed it since I had no idea what to provide for a version.\n\nthoughts?","commit_id":"c8833bad708c55ac5889744443a159f508682fe7"}],"oslo_utils/tests/test_strutils.py":[{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":605,"context_line":"        expected \u003d {\u0027strval\u0027: \u0027somestring\u0027,"},{"line_number":606,"context_line":"                    \u0027dictval\u0027: {\u0027user\u0027: \u0027admin\u0027, \u0027password\u0027: \u0027***\u0027}}"},{"line_number":607,"context_line":"        self.assertEqual(expected,"},{"line_number":608,"context_line":"                         strutils.mask_dictionary_password(payload))"},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"    def test_do_no_harm(self):"},{"line_number":611,"context_line":"        payload \u003d {}"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_2ed0f31e","line":608,"range":{"start_line":608,"start_character":25,"end_line":608,"end_character":33},"updated":"2016-01-04 09:51:10.000000000","message":"please add a test with nested dict where the key is a password. Example:\n\n{\u0027password\u0027: {\u0027user\u0027: \u0027admin\u0027, \u0027admin_pass\u0027: \u0027secret\u0027}}\n\nI expect that only secret is replaced with ***.","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"791e33a3d3eaecc5fb24fd897753eaff1a475c58","unresolved":false,"context_lines":[{"line_number":625,"context_line":"        expected \u003d {\u0027somekey\u0027: \u0027test \u003d cmd --password ***\u0027}"},{"line_number":626,"context_line":"        self.assertEqual(expected,"},{"line_number":627,"context_line":"                         strutils.mask_dictionary_password(payload))"},{"line_number":628,"context_line":""},{"line_number":629,"context_line":""},{"line_number":630,"context_line":"class IsIntLikeTestCase(test_base.BaseTestCase):"},{"line_number":631,"context_line":"    def test_is_int_like_true(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa69d971_ce16f7a6","line":628,"updated":"2016-01-04 09:51:10.000000000","message":"You should add a test with byte strings. Example:\n\n{b\u0027password\u0027: b\u0027secret\u0027}\n\nI suggest to explicitly *not* replaced bytes strings on Python 3, see my comment on the function.","commit_id":"0854bcf7a0e2e6ea06ad9032a40dfa9a1ef3ae08"}]}
