)]}'
{"neutron_lib/tests/unit/utils/test_helpers.py":[{"author":{"_account_id":15554,"name":"Bence Romsics","email":"bence.romsics@gmail.com","username":"ebenrom","status":"inactive contributor"},"change_message_id":"e24a520a328cc6ece831dacf8d67bbe858552712","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    def test_compare(self):"},{"line_number":96,"context_line":"        self.assertTrue(helpers.compare_dict({\u0027a\u0027: 2}, {\u0027a\u0027: 2}))"},{"line_number":97,"context_line":"        self.assertFalse(helpers.compare_dict({\u0027a\u0027: 2}, {\u0027a\u0027: 3}))"},{"line_number":98,"context_line":"        self.assertTrue(helpers.compare_dict({\u0027a\u0027: [1, 2]}, {\u0027a\u0027: [2, 1]}))"},{"line_number":99,"context_line":"        self.assertFalse(helpers.compare_dict({\u0027a\u0027: [1, 2]}, {\u0027a\u0027: [1]}))"},{"line_number":100,"context_line":"        self.assertTrue(helpers.compare_dict({\u0027a\u0027: \u0027value1\u0027}, {\u0027a\u0027: \u0027value1\u0027}))"},{"line_number":101,"context_line":"        self.assertFalse(helpers.compare_dict({\u0027a\u0027: \u0027value\u0027}, {\u0027a\u0027: \u0027value1\u0027}))"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f79a3b5_f46ae24e","line":98,"range":{"start_line":98,"start_character":8,"end_line":98,"end_character":75},"updated":"2018-12-20 14:59:24.000000000","message":"I see two problems here:\n\n1) This is horribly surprising behavior for a method called \u0027compare_dict\u0027. Neither the method name nor the docstring tells the user what behavior to expect.\n\n2) The need for this method at all probably stems from an earlier bad choice of a data structure. If the data structure compared would contain sets instead of lists then ordinary python comparison (the \u003d\u003d operator) would work out of the box.\n\n $ python3\n \u003e\u003e\u003e {1: set([2, 3])} \u003d\u003d {1: set([3, 2])}\n True","commit_id":"34910dc0745a26d8f5a7cbc01dc4ac84aa61c211"}],"neutron_lib/utils/helpers.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"861997188660499bf9517119007efea3d3102dec","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        elif value !\u003d b[key]:"},{"line_number":92,"context_line":"            return False"},{"line_number":93,"context_line":"    return True"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"def safe_sort_key(value):"},{"line_number":96,"context_line":"    \"\"\"Return value hash or build one for dictionaries."},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_b646847d","line":94,"updated":"2018-11-27 19:45:04.000000000","message":"pep8 will complain about only one blank line :(","commit_id":"800d39cca7ac270652df2cc553b77f2865596172"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"1d76f0f890dbca6f7fc9ae4716cfbaaff7d3d834","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        elif value !\u003d b[key]:"},{"line_number":92,"context_line":"            return False"},{"line_number":93,"context_line":"    return True"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"def safe_sort_key(value):"},{"line_number":96,"context_line":"    \"\"\"Return value hash or build one for dictionaries."},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_42dde00f","line":94,"in_reply_to":"3f79a3b5_b646847d","updated":"2018-11-28 11:09:01.000000000","message":"ups!","commit_id":"800d39cca7ac270652df2cc553b77f2865596172"},{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"984f3e0fb8e767370de9fed448b714547418aab8","unresolved":false,"context_lines":[{"line_number":77,"context_line":"def compare_dict(a, b):"},{"line_number":78,"context_line":"    \"\"\"Compare two dicts, including keys and elements."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    Dict comparison removed in Python 3.0.1."},{"line_number":81,"context_line":"    \"\"\""},{"line_number":82,"context_line":"    if sorted(list(a.keys())) !\u003d sorted(list(b.keys())):"},{"line_number":83,"context_line":"        return False"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_d4e671dc","line":80,"updated":"2018-11-29 13:12:45.000000000","message":"Why not add the docstrings? e.g. param/returns","commit_id":"92cac00a4e01618105b0362a8d2f6520b28cbf0d"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"7dd9532866bba58eb3a9d8a395f116bd48df460c","unresolved":false,"context_lines":[{"line_number":77,"context_line":"def compare_dict(a, b):"},{"line_number":78,"context_line":"    \"\"\"Compare two dicts, including keys and elements."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    Dict comparison removed in Python 3.0.1."},{"line_number":81,"context_line":"    \"\"\""},{"line_number":82,"context_line":"    if sorted(list(a.keys())) !\u003d sorted(list(b.keys())):"},{"line_number":83,"context_line":"        return False"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f79a3b5_a685c804","line":80,"in_reply_to":"3f79a3b5_d4e671dc","updated":"2018-11-29 17:09:45.000000000","message":"Done","commit_id":"92cac00a4e01618105b0362a8d2f6520b28cbf0d"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"6b96e5754aae67e493407c81e7827016fdf139cb","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def compare_dict(a, b):"},{"line_number":78,"context_line":"    \"\"\"Compare two dicts, including keys and elements."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    Dict comparison removed in Python 3.0.1."},{"line_number":81,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_acf7d75b","line":78,"range":{"start_line":78,"start_character":45,"end_line":78,"end_character":53},"updated":"2018-11-30 14:39:44.000000000","message":"nit: s/values - to match L84","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"901cb7152d74e0448cbddc7eb6216aae4143f4ea","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def compare_dict(a, b):"},{"line_number":78,"context_line":"    \"\"\"Compare two dicts, including keys and elements."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    Dict comparison removed in Python 3.0.1."},{"line_number":81,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_64d9c425","line":78,"range":{"start_line":78,"start_character":45,"end_line":78,"end_character":53},"in_reply_to":"3f79a3b5_acf7d75b","updated":"2018-12-01 17:49:05.000000000","message":"Done","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"6b96e5754aae67e493407c81e7827016fdf139cb","unresolved":false,"context_lines":[{"line_number":77,"context_line":"def compare_dict(a, b):"},{"line_number":78,"context_line":"    \"\"\"Compare two dicts, including keys and elements."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    Dict comparison removed in Python 3.0.1."},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    :param a: The first dict to compare."},{"line_number":83,"context_line":"    :param b: The second dict to compare."}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_2cbae76f","line":80,"range":{"start_line":80,"start_character":4,"end_line":80,"end_character":27},"updated":"2018-11-30 14:39:44.000000000","message":"nit: s/Useful because dict comparison was removed","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"901cb7152d74e0448cbddc7eb6216aae4143f4ea","unresolved":false,"context_lines":[{"line_number":77,"context_line":"def compare_dict(a, b):"},{"line_number":78,"context_line":"    \"\"\"Compare two dicts, including keys and elements."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    Dict comparison removed in Python 3.0.1."},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    :param a: The first dict to compare."},{"line_number":83,"context_line":"    :param b: The second dict to compare."}],"source_content_type":"text/x-python","patch_set":5,"id":"3f79a3b5_e4c4f43b","line":80,"range":{"start_line":80,"start_character":4,"end_line":80,"end_character":27},"in_reply_to":"3f79a3b5_2cbae76f","updated":"2018-12-01 17:49:05.000000000","message":"Done","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":15554,"name":"Bence Romsics","email":"bence.romsics@gmail.com","username":"ebenrom","status":"inactive contributor"},"change_message_id":"e24a520a328cc6ece831dacf8d67bbe858552712","unresolved":false,"context_lines":[{"line_number":77,"context_line":"def compare_dict(a, b):"},{"line_number":78,"context_line":"    \"\"\"Compare two dicts, including keys and values."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    Useful because dict comparison was removed in Python 3.0.1."},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    :param a: The first dict to compare."},{"line_number":83,"context_line":"    :param b: The second dict to compare."}],"source_content_type":"text/x-python","patch_set":7,"id":"3f79a3b5_f4cd025c","line":80,"range":{"start_line":80,"start_character":4,"end_line":80,"end_character":63},"updated":"2018-12-20 14:59:24.000000000","message":"There must be some misunderstanding here, because this isn\u0027t true. What I suspect to be the source of confusion is that comparison for order was actually removed in pyhton3. But comparison for equality was not.\n\n $ python2\n \u003e\u003e\u003e {} \u003d\u003d {}\n True\n \u003e\u003e\u003e {} \u003c {}\n False\n\n $ python3\n \u003e\u003e\u003e {} \u003d\u003d {}\n True\n \u003e\u003e\u003e {} \u003c {}\n Traceback (most recent call last):\n   File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n TypeError: unorderable types: dict() \u003c dict()","commit_id":"34910dc0745a26d8f5a7cbc01dc4ac84aa61c211"},{"author":{"_account_id":15554,"name":"Bence Romsics","email":"bence.romsics@gmail.com","username":"ebenrom","status":"inactive contributor"},"change_message_id":"e24a520a328cc6ece831dacf8d67bbe858552712","unresolved":false,"context_lines":[{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    :param a: The first dict to compare."},{"line_number":83,"context_line":"    :param b: The second dict to compare."},{"line_number":84,"context_line":"    :returns: True if a and b have the same keys and values, False otherwise."},{"line_number":85,"context_line":"    \"\"\""},{"line_number":86,"context_line":"    if sorted(list(a.keys())) !\u003d sorted(list(b.keys())):"},{"line_number":87,"context_line":"        return False"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f79a3b5_d4c32604","line":84,"range":{"start_line":84,"start_character":14,"end_line":84,"end_character":77},"updated":"2018-12-20 14:59:24.000000000","message":"This is a false description of what this method does. This method sorts the list values before comparing them. [1, 2] and [2, 1] is not the same.","commit_id":"34910dc0745a26d8f5a7cbc01dc4ac84aa61c211"}],"releasenotes/notes/add-compare-dict-315a66a65cbce6fd.yaml":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"6b96e5754aae67e493407c81e7827016fdf139cb","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add function ``compare_dict`` in ``util.helpers``. This function allows to"},{"line_number":5,"context_line":"    compare two dictionaries, checking both the keys and the values contained."}],"source_content_type":"text/x-yaml","patch_set":5,"id":"3f79a3b5_cc79f3fa","line":4,"range":{"start_line":4,"start_character":39,"end_line":4,"end_character":51},"updated":"2018-11-30 14:39:44.000000000","message":"Looking at other release notes they mostly use ``neutron_lib.utils.helpers`` - also s/util/utils","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"6b96e5754aae67e493407c81e7827016fdf139cb","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add function ``compare_dict`` in ``util.helpers``. This function allows to"},{"line_number":5,"context_line":"    compare two dictionaries, checking both the keys and the values contained."}],"source_content_type":"text/x-yaml","patch_set":5,"id":"3f79a3b5_6c43ff98","line":4,"range":{"start_line":4,"start_character":4,"end_line":4,"end_character":33},"updated":"2018-11-30 14:39:44.000000000","message":"s/Introduced ``compare_dict`` function","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"6b96e5754aae67e493407c81e7827016fdf139cb","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add function ``compare_dict`` in ``util.helpers``. This function allows to"},{"line_number":5,"context_line":"    compare two dictionaries, checking both the keys and the values contained."}],"source_content_type":"text/x-yaml","patch_set":5,"id":"3f79a3b5_ccc7b310","line":4,"range":{"start_line":4,"start_character":55,"end_line":4,"end_character":68},"updated":"2018-11-30 14:39:44.000000000","message":"s/It","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"6b96e5754aae67e493407c81e7827016fdf139cb","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add function ``compare_dict`` in ``util.helpers``. This function allows to"},{"line_number":5,"context_line":"    compare two dictionaries, checking both the keys and the values contained."}],"source_content_type":"text/x-yaml","patch_set":5,"id":"3f79a3b5_ecccef34","line":4,"range":{"start_line":4,"start_character":76,"end_line":4,"end_character":78},"updated":"2018-11-30 14:39:44.000000000","message":"s/you to","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"6b96e5754aae67e493407c81e7827016fdf139cb","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add function ``compare_dict`` in ``util.helpers``. This function allows to"},{"line_number":5,"context_line":"    compare two dictionaries, checking both the keys and the values contained."}],"source_content_type":"text/x-yaml","patch_set":5,"id":"3f79a3b5_4cdba3ea","line":5,"range":{"start_line":5,"start_character":68,"end_line":5,"end_character":78},"updated":"2018-11-30 14:39:44.000000000","message":"s/it contains.","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"901cb7152d74e0448cbddc7eb6216aae4143f4ea","unresolved":false,"context_lines":[{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add function ``compare_dict`` in ``util.helpers``. This function allows to"},{"line_number":5,"context_line":"    compare two dictionaries, checking both the keys and the values contained."}],"source_content_type":"text/x-yaml","patch_set":5,"id":"3f79a3b5_44fda86e","line":5,"range":{"start_line":5,"start_character":68,"end_line":5,"end_character":78},"in_reply_to":"3f79a3b5_4cdba3ea","updated":"2018-12-01 17:49:05.000000000","message":"I need to continue my English lessons...","commit_id":"a535469c88c0c9b7f729e4011e7bca72edddb2c1"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"19a1e292f5890e3a8a3255380deb457faffc92df","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Introduced ``compare_dict`` function in ``neutron_lib.util.helpers``. It"},{"line_number":5,"context_line":"    allows you to compare two dictionaries, checking both the keys and the"},{"line_number":6,"context_line":"    values it contains."}],"source_content_type":"text/x-yaml","patch_set":6,"id":"3f79a3b5_9c78e27d","line":4,"range":{"start_line":4,"start_character":58,"end_line":4,"end_character":62},"updated":"2018-12-03 16:38:32.000000000","message":"s/utils","commit_id":"d64363fc93cdcb704314298f45f6c8de335e2701"}]}
