)]}'
{"glance/common/utils.py":[{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"a7f01152d3df60dc528b6330ec6199fdab6ae54b","unresolved":false,"context_lines":[{"line_number":607,"context_line":"    return op, threshold"},{"line_number":608,"context_line":""},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"def split_filter_value_for_quotes(value):"},{"line_number":611,"context_line":"    ind_quote_start \u003d value.find(\u0027\\\\\"\u0027)"},{"line_number":612,"context_line":"    ind_quote_stop \u003d value.find(\u0027\\\\\"\u0027, ind_quote_start + 3)"},{"line_number":613,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5a5ae5dd_b79c676a","line":610,"range":{"start_line":610,"start_character":4,"end_line":610,"end_character":33},"updated":"2016-02-03 17:42:17.000000000","message":"First, I think you should write a docstring for this function.\n\nSecond, it\u0027s better to use csv module in your case:\n\nfrom csv import reader\n\ndef split_filter_value_for_quotes(value):\n\n    return reader([value])\n\nIt will split your string as you want.\n\n\u003e\u003e\u003e line \u003d \u0027a,\"b,c\",d\u0027\n\n\u003e\u003e\u003e for i in csv.reader([line]):\n\n...     print i\n\n... \n\n[\u0027a\u0027, \u0027b,c\u0027, \u0027d\u0027]","commit_id":"c3e72169e45ec3e12e673b49f786213184f2939f"},{"author":{"_account_id":16683,"name":"Alexey Galkin","email":"agalkin@mirantis.com","username":"agalkin"},"change_message_id":"8bdf8cce49c1957e601cbd3631f5ad8d663143a4","unresolved":false,"context_lines":[{"line_number":620,"context_line":"    while ind_quote_start !\u003d -1 and ind_quote_stop !\u003d -1:"},{"line_number":621,"context_line":"        threshold.append(value[ind_quote_start: ind_quote_stop])"},{"line_number":622,"context_line":""},{"line_number":623,"context_line":"        ind_quote_start \u003d ind_quote_stop + 1"},{"line_number":624,"context_line":"        ind_quote_stop \u003d value.find(\u0027\\\\\"\u0027, ind_quote_start + 1)"},{"line_number":625,"context_line":"        if ind_quote_stop !\u003d -1:"},{"line_number":626,"context_line":"            threshold.extend(value[ind_quote_start:ind_quote_start].split(\",\"))"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_b53ecad8","line":623,"updated":"2016-02-02 10:43:00.000000000","message":"ind_quote_start +\u003d 1","commit_id":"c3e72169e45ec3e12e673b49f786213184f2939f"},{"author":{"_account_id":16683,"name":"Alexey Galkin","email":"agalkin@mirantis.com","username":"agalkin"},"change_message_id":"202204e6eb88e0baa3d909f375de2157ec459b0a","unresolved":false,"context_lines":[{"line_number":620,"context_line":"    while ind_quote_start !\u003d -1 and ind_quote_stop !\u003d -1:"},{"line_number":621,"context_line":"        threshold.append(value[ind_quote_start: ind_quote_stop])"},{"line_number":622,"context_line":""},{"line_number":623,"context_line":"        ind_quote_start \u003d ind_quote_stop + 1"},{"line_number":624,"context_line":"        ind_quote_stop \u003d value.find(\u0027\\\\\"\u0027, ind_quote_start + 1)"},{"line_number":625,"context_line":"        if ind_quote_stop !\u003d -1:"},{"line_number":626,"context_line":"            threshold.extend(value[ind_quote_start:ind_quote_start].split(\",\"))"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a5de9d1_803d8abd","line":623,"in_reply_to":"7a5de9d1_b53ecad8","updated":"2016-02-02 10:44:53.000000000","message":"I was wrong, apologize for negligence","commit_id":"c3e72169e45ec3e12e673b49f786213184f2939f"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"449050349639b661a00386428d4235d13ba8684b","unresolved":false,"context_lines":[{"line_number":608,"context_line":""},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"def split_filter_value_for_quotes(value):"},{"line_number":611,"context_line":"    tmp \u003d re.compile(r\u0027\u0027\u0027 \"([^\\\"\\\\]*(?:\\\\.[^\\\"\\\\]*)*)\",?|([^,]+),?|,\u0027\u0027\u0027,"},{"line_number":612,"context_line":"                     re.VERBOSE)"},{"line_number":613,"context_line":"    return [val[0] or val[1] for val in re.findall(tmp, value)]"},{"line_number":614,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_1a40f4a4","line":611,"updated":"2016-02-10 17:10:02.000000000","message":"If we\u0027re using re.VERBOSE, can we split this across multiple lines and add comments in line so we know what\u0027s going on? (See https://docs.python.org/2/library/re.html#re.VERBOSE for an example)","commit_id":"d18ccbef60777636968466a54ce58e78cfea1d45"},{"author":{"_account_id":7575,"name":"Sabari","email":"smurugesan@vmware.com","username":"sabari"},"change_message_id":"002d4c5650f34e4035121d92097d2953a26d9a96","unresolved":false,"context_lines":[{"line_number":608,"context_line":""},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"def split_filter_value_for_quotes(value):"},{"line_number":611,"context_line":"    tmp \u003d re.compile(r\u0027\u0027\u0027 \"([^\\\"\\\\]*(?:\\\\.[^\\\"\\\\]*)*)\",?|([^,]+),?|,\u0027\u0027\u0027,"},{"line_number":612,"context_line":"                     re.VERBOSE)"},{"line_number":613,"context_line":"    return [val[0] or val[1] for val in re.findall(tmp, value)]"},{"line_number":614,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3a57f1b5_5bc98777","line":611,"in_reply_to":"3a57f1b5_1a40f4a4","updated":"2016-02-10 19:34:30.000000000","message":"+1","commit_id":"d18ccbef60777636968466a54ce58e78cfea1d45"},{"author":{"_account_id":14676,"name":"Kairat Kushaev","email":"kkushaev@mirantis.com","username":"kairat_kushaev"},"change_message_id":"56f8436e5214f2e89cfb7cb8aa276533bb15f52b","unresolved":false,"context_lines":[{"line_number":616,"context_line":"        \"(                 # if found a double-quote"},{"line_number":617,"context_line":"           [^\\\"\\\\]*        # take characters either non-quotes or backslashes"},{"line_number":618,"context_line":"           (?:\\\\.          # take backslashes and character after it"},{"line_number":619,"context_line":"            [^\\\"\\\\]*)*     # take characters either non-quotes or backslashes"},{"line_number":620,"context_line":"         )                 # before double-quote"},{"line_number":621,"context_line":"        \",?                # a double-quote with comma maybe"},{"line_number":622,"context_line":"        | ([^,]+),?        # if not found double-quote take any non-comma"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_3d7c41eb","line":619,"updated":"2016-02-18 09:32:50.000000000","message":"I think regex are cool but it is quite hard to understand and support.\nI also see that this regex interprets values like \n\"dsds\"\"dsds\" as \"dsds\", \"dsds\" and values like \"ws\\\"sd\",sd, \"sdd\" parsed as \n[(\u0027ws\u0027, \u0027\u0027), (\u0027\u0027, \u0027sd\"\u0027), (\u0027\u0027, \u0027sd\u0027), (\u0027\u0027, \u0027 \"sdd\"\u0027)]. Looks like you need to fix the reg exp.\nWhat about iteration approach:\n\nsplit\u003dtrue\nbegin \u003d 0\nresult \u003d []\nfor i in range(0, len(value)):\n   if value[i] \u003d\u003d \u0027,\u0027 and split:\n      result.append(value[begin:i])\n      begin \u003d i + 1\n   elif value[i] \u003d\u003d \u0027\"\u0027:\n       if i\u003d\u003d0 or value[i-1] \u003d\u003d \u0027\\\u0027:\n          split \u003d not split\n\nI know it not so Pythonic but it looks like more supportable for me. WDYT?","commit_id":"e35414f1611382ab3b2555184f9fdfca1b7a2ee8"},{"author":{"_account_id":14676,"name":"Kairat Kushaev","email":"kkushaev@mirantis.com","username":"kairat_kushaev"},"change_message_id":"126829fc620d56b3f24a69eb28c37bf3fd362c9c","unresolved":false,"context_lines":[{"line_number":620,"context_line":"            if open_quotes:"},{"line_number":621,"context_line":"                if i and value[i - 1] !\u003d \u0027,\u0027:"},{"line_number":622,"context_line":"                    msg \u003d _(\"Invalid filter value %s. There is no comma \""},{"line_number":623,"context_line":"                            \"after the closing quotation mark.\") % value"},{"line_number":624,"context_line":"                    raise exception.InvalidParameterValue(message\u003dmsg)"},{"line_number":625,"context_line":"            else:"},{"line_number":626,"context_line":"                if i + 1 !\u003d len(value) and value[i + 1] !\u003d \",\":"}],"source_content_type":"text/x-python","patch_set":16,"id":"bae84128_434c62c7","line":623,"updated":"2016-02-20 08:29:43.000000000","message":"I guess that should be \"before opening\"?","commit_id":"39bc15833ce9d7c08cf4ec99238ccbf7b8416a8a"},{"author":{"_account_id":14676,"name":"Kairat Kushaev","email":"kkushaev@mirantis.com","username":"kairat_kushaev"},"change_message_id":"126829fc620d56b3f24a69eb28c37bf3fd362c9c","unresolved":false,"context_lines":[{"line_number":624,"context_line":"                    raise exception.InvalidParameterValue(message\u003dmsg)"},{"line_number":625,"context_line":"            else:"},{"line_number":626,"context_line":"                if i + 1 !\u003d len(value) and value[i + 1] !\u003d \",\":"},{"line_number":627,"context_line":"                    msg \u003d _(\"Invalid filter value %s. There is no comma \""},{"line_number":628,"context_line":"                            \"after the openning quotation mark.\") % value"},{"line_number":629,"context_line":"                    raise exception.InvalidParameterValue(message\u003dmsg)"},{"line_number":630,"context_line":"            open_quotes \u003d not open_quotes"}],"source_content_type":"text/x-python","patch_set":16,"id":"bae84128_a3c72e11","line":627,"range":{"start_line":627,"start_character":29,"end_line":627,"end_character":30},"updated":"2016-02-20 08:29:43.000000000","message":"after closing?","commit_id":"39bc15833ce9d7c08cf4ec99238ccbf7b8416a8a"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"ce35b1c999d41c8e0f648d93620913f259ac117f","unresolved":false,"context_lines":[{"line_number":607,"context_line":"    return op, threshold"},{"line_number":608,"context_line":""},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"def validate_quotes(value):"},{"line_number":611,"context_line":"    \"\"\"Validate filter values"},{"line_number":612,"context_line":""},{"line_number":613,"context_line":"    Validation opening/closing quotes in the expression."}],"source_content_type":"text/x-python","patch_set":17,"id":"bae84128_d9d9fe58","line":610,"updated":"2016-02-23 19:03:09.000000000","message":"Have other projects adopted this spec? Did those project require these utilities?","commit_id":"600706194375168800c9879e05bc40cdb54b25d3"},{"author":{"_account_id":14676,"name":"Kairat Kushaev","email":"kkushaev@mirantis.com","username":"kairat_kushaev"},"change_message_id":"3b26fe99cb84e7ecd23c0984b6160767e885349b","unresolved":false,"context_lines":[{"line_number":607,"context_line":"    return op, threshold"},{"line_number":608,"context_line":""},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"def validate_quotes(value):"},{"line_number":611,"context_line":"    \"\"\"Validate filter values"},{"line_number":612,"context_line":""},{"line_number":613,"context_line":"    Validation opening/closing quotes in the expression."}],"source_content_type":"text/x-python","patch_set":17,"id":"bae84128_b88dedd4","line":610,"in_reply_to":"bae84128_d9d9fe58","updated":"2016-02-24 11:39:18.000000000","message":"I was wondering about the same question.\nUnfortunately, I wasn\u0027t able to found any info about that in https://github.com/openstack/api-wg/blob/master/guidelines/pagination_filter_sort.rst.\nLooks like we need to make some restriction here and apply update to api-wg spec.","commit_id":"600706194375168800c9879e05bc40cdb54b25d3"}],"glance/db/simple/api.py":[{"author":{"_account_id":14676,"name":"Kairat Kushaev","email":"kkushaev@mirantis.com","username":"kairat_kushaev"},"change_message_id":"618deb13b0e0d5f08c00ce594370763cfed0756a","unresolved":false,"context_lines":[{"line_number":310,"context_line":"                attr_value \u003d image.get(key)"},{"line_number":311,"context_line":"                operator, list_value \u003d utils.split_filter_op(value)"},{"line_number":312,"context_line":"                threshold \u003d list_value.split(\u0027,\u0027)"},{"line_number":313,"context_line":"                to_add \u003d attr_value in threshold"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"            elif k !\u003d \u0027is_public\u0027 and image.get(k) is not None:"},{"line_number":316,"context_line":"                to_add \u003d image.get(key) \u003d\u003d value"}],"source_content_type":"text/x-python","patch_set":6,"id":"da6ed579_be37ec4b","line":313,"range":{"start_line":313,"start_character":23,"end_line":313,"end_character":24},"updated":"2016-01-14 13:19:36.000000000","message":"I guess we need to check if operator is in or eq here?","commit_id":"96f310a2bdd07d0f84fb7bf195645df11d59ca7f"},{"author":{"_account_id":16658,"name":"Darja Shakhray","email":"damalyavkina@gmail.com","username":"dshakhray"},"change_message_id":"bc6866c24b2c069cd300f738d6acae127474cf97","unresolved":false,"context_lines":[{"line_number":310,"context_line":"                attr_value \u003d image.get(key)"},{"line_number":311,"context_line":"                operator, list_value \u003d utils.split_filter_op(value)"},{"line_number":312,"context_line":"                threshold \u003d list_value.split(\u0027,\u0027)"},{"line_number":313,"context_line":"                to_add \u003d attr_value in threshold"},{"line_number":314,"context_line":""},{"line_number":315,"context_line":"            elif k !\u003d \u0027is_public\u0027 and image.get(k) is not None:"},{"line_number":316,"context_line":"                to_add \u003d image.get(key) \u003d\u003d value"}],"source_content_type":"text/x-python","patch_set":6,"id":"da6ed579_5427b1c9","line":313,"range":{"start_line":313,"start_character":23,"end_line":313,"end_character":24},"in_reply_to":"da6ed579_be37ec4b","updated":"2016-01-14 13:51:31.000000000","message":"Done","commit_id":"96f310a2bdd07d0f84fb7bf195645df11d59ca7f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"d02cb0af336bbf1b8e0f0677bb934cc14f91214a","unresolved":false,"context_lines":[{"line_number":315,"context_line":"                elif operator \u003d\u003d \u0027eq\u0027:"},{"line_number":316,"context_line":"                    to_add \u003d (attr_value \u003d\u003d list_value)"},{"line_number":317,"context_line":"                else:"},{"line_number":318,"context_line":"                    msg \u003d _(\"Unable to filter on a unknown operator.\")"},{"line_number":319,"context_line":"                    raise exception.InvalidFilterOperatorValue(msg)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"            elif k !\u003d \u0027is_public\u0027 and image.get(k) is not None:"}],"source_content_type":"text/x-python","patch_set":7,"id":"da6ed579_f4288e35","line":318,"range":{"start_line":318,"start_character":46,"end_line":318,"end_character":48},"updated":"2016-01-18 12:23:03.000000000","message":"IMO, it is beneficial to provide attr_value in error message.","commit_id":"c61eb5827f52a5fbfca9fe14b2977597ec2c928f"},{"author":{"_account_id":16658,"name":"Darja Shakhray","email":"damalyavkina@gmail.com","username":"dshakhray"},"change_message_id":"cf4966aed5474489036c503ffbe5782340a2fb0f","unresolved":false,"context_lines":[{"line_number":315,"context_line":"                elif operator \u003d\u003d \u0027eq\u0027:"},{"line_number":316,"context_line":"                    to_add \u003d (attr_value \u003d\u003d list_value)"},{"line_number":317,"context_line":"                else:"},{"line_number":318,"context_line":"                    msg \u003d _(\"Unable to filter on a unknown operator.\")"},{"line_number":319,"context_line":"                    raise exception.InvalidFilterOperatorValue(msg)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"            elif k !\u003d \u0027is_public\u0027 and image.get(k) is not None:"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a68dd71_81cb4e72","line":318,"range":{"start_line":318,"start_character":46,"end_line":318,"end_character":48},"in_reply_to":"da6ed579_f4288e35","updated":"2016-01-20 13:51:14.000000000","message":"Done","commit_id":"c61eb5827f52a5fbfca9fe14b2977597ec2c928f"}],"glance/db/sqlalchemy/api.py":[{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"03ba7fb2ea5cc0b9b70fb2c0662f7beef7c4fcf2","unresolved":false,"context_lines":[{"line_number":489,"context_line":"            if operator \u003d\u003d \u0027in\u0027:"},{"line_number":490,"context_line":"                comparison \u003d attr_value.in_(threshold)"},{"line_number":491,"context_line":"                image_conditions.append(comparison)"},{"line_number":492,"context_line":"            else:"},{"line_number":493,"context_line":"                msg \u003d _(\"Unable to filter on a unknown operator.\")"},{"line_number":494,"context_line":"                raise exception.InvalidFilterOperatorValue(msg)"},{"line_number":495,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba8a016a_f3aac618","line":492,"updated":"2015-11-23 18:00:01.000000000","message":"it\u0027s not necessary to be only \u0027in\u0027, it could be \u0027eq\u0027 as well...\n\nfor example GET /v2/images?name\u003dlalala is absolutely valid request","commit_id":"39a8619d3a43d6267179d52245971197d40d3e73"},{"author":{"_account_id":14676,"name":"Kairat Kushaev","email":"kkushaev@mirantis.com","username":"kairat_kushaev"},"change_message_id":"ba35907f5c740f52c35a35b3ec6dbfcae6d39966","unresolved":false,"context_lines":[{"line_number":495,"context_line":"                threshold \u003d list_value.split(\u0027,\u0027)"},{"line_number":496,"context_line":"                comparison \u003d attr_value.in_(threshold)"},{"line_number":497,"context_line":"                image_conditions.append(comparison)"},{"line_number":498,"context_line":"            elif operator \u003d\u003d \u0027eq\u0027:"},{"line_number":499,"context_line":"                image_conditions.append(attr_value \u003d\u003d list_value)"},{"line_number":500,"context_line":"            else:"},{"line_number":501,"context_line":"                msg \u003d _(\"Unable to filter on a unknown operator.\")"}],"source_content_type":"text/x-python","patch_set":7,"id":"da6ed579_55407d07","line":498,"range":{"start_line":498,"start_character":17,"end_line":498,"end_character":25},"updated":"2016-01-18 10:27:46.000000000","message":"So we are accepting comparisons like:\nstatus\u003deq:active.\nNot sure it is sane but it seems ok for me.","commit_id":"c61eb5827f52a5fbfca9fe14b2977597ec2c928f"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"d02cb0af336bbf1b8e0f0677bb934cc14f91214a","unresolved":false,"context_lines":[{"line_number":498,"context_line":"            elif operator \u003d\u003d \u0027eq\u0027:"},{"line_number":499,"context_line":"                image_conditions.append(attr_value \u003d\u003d list_value)"},{"line_number":500,"context_line":"            else:"},{"line_number":501,"context_line":"                msg \u003d _(\"Unable to filter on a unknown operator.\")"},{"line_number":502,"context_line":"                raise exception.InvalidFilterOperatorValue(msg)"},{"line_number":503,"context_line":""},{"line_number":504,"context_line":"    for (k, value) in filters.items():"}],"source_content_type":"text/x-python","patch_set":7,"id":"da6ed579_f4df2e38","line":501,"range":{"start_line":501,"start_character":44,"end_line":501,"end_character":45},"updated":"2016-01-18 12:23:03.000000000","message":"ditto","commit_id":"c61eb5827f52a5fbfca9fe14b2977597ec2c928f"},{"author":{"_account_id":16658,"name":"Darja Shakhray","email":"damalyavkina@gmail.com","username":"dshakhray"},"change_message_id":"cf4966aed5474489036c503ffbe5782340a2fb0f","unresolved":false,"context_lines":[{"line_number":498,"context_line":"            elif operator \u003d\u003d \u0027eq\u0027:"},{"line_number":499,"context_line":"                image_conditions.append(attr_value \u003d\u003d list_value)"},{"line_number":500,"context_line":"            else:"},{"line_number":501,"context_line":"                msg \u003d _(\"Unable to filter on a unknown operator.\")"},{"line_number":502,"context_line":"                raise exception.InvalidFilterOperatorValue(msg)"},{"line_number":503,"context_line":""},{"line_number":504,"context_line":"    for (k, value) in filters.items():"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a68dd71_41c55659","line":501,"range":{"start_line":501,"start_character":44,"end_line":501,"end_character":45},"in_reply_to":"da6ed579_f4df2e38","updated":"2016-01-20 13:51:14.000000000","message":"Done","commit_id":"c61eb5827f52a5fbfca9fe14b2977597ec2c928f"},{"author":{"_account_id":7575,"name":"Sabari","email":"smurugesan@vmware.com","username":"sabari"},"change_message_id":"735152ea11a2e9e319bcf6dfc5f02f3f263ea051","unresolved":false,"context_lines":[{"line_number":492,"context_line":"            attr_value \u003d getattr(models.Image, key)"},{"line_number":493,"context_line":"            operator, list_value \u003d utils.split_filter_op(filters.pop(k))"},{"line_number":494,"context_line":"            if operator \u003d\u003d \u0027in\u0027:"},{"line_number":495,"context_line":"                threshold \u003d list_value.split(\u0027,\u0027)"},{"line_number":496,"context_line":"                comparison \u003d attr_value.in_(threshold)"},{"line_number":497,"context_line":"                image_conditions.append(comparison)"},{"line_number":498,"context_line":"            elif operator \u003d\u003d \u0027eq\u0027:"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a68dd71_d40441c1","line":495,"updated":"2016-01-22 00:34:38.000000000","message":"I don\u0027t think the naive split will work here if the image_name has \u0027,\u0027 in it (yes. that\u0027s allowed). If my request was to match an image with names tht contained a  \"blah,blah\", the value in the filters dict would be\n\n name: \u0027apple, pears, blah, blah\u0027","commit_id":"0841be9c65d79458074d1f1a9217803c291a9436"},{"author":{"_account_id":7575,"name":"Sabari","email":"smurugesan@vmware.com","username":"sabari"},"change_message_id":"3ac59922b7cd81bdbc79d89a65a39a052410a48b","unresolved":false,"context_lines":[{"line_number":492,"context_line":"            attr_value \u003d getattr(models.Image, key)"},{"line_number":493,"context_line":"            operator, list_value \u003d utils.split_filter_op(filters.pop(k))"},{"line_number":494,"context_line":"            if operator \u003d\u003d \u0027in\u0027:"},{"line_number":495,"context_line":"                threshold \u003d list_value.split(\u0027,\u0027)"},{"line_number":496,"context_line":"                comparison \u003d attr_value.in_(threshold)"},{"line_number":497,"context_line":"                image_conditions.append(comparison)"},{"line_number":498,"context_line":"            elif operator \u003d\u003d \u0027eq\u0027:"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a68dd71_369d6a66","line":495,"in_reply_to":"9a68dd71_10ac0f9f","updated":"2016-01-22 22:36:12.000000000","message":"IMO, It will be a bad user experience to do that. But you can give it a try.\n\nSome other suggestions :-\nchange your API to allow multiple params to be specified in query string with the same key and then implicitly do an \u0027IN\u0027 operation.\n\n http://localhost:9292/v2/images?name\u003dapple\u0026name\u003dblah%2Cblah\n\nor\ndrop \u0027name\u0027 from the allowed keys in \u0027IN\u0027 operator. \n\nSince the spec is approved I will just stop here :).","commit_id":"0841be9c65d79458074d1f1a9217803c291a9436"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"f720b98bc728403b937e1a32f27c47e9ead4d789","unresolved":false,"context_lines":[{"line_number":492,"context_line":"            attr_value \u003d getattr(models.Image, key)"},{"line_number":493,"context_line":"            operator, list_value \u003d utils.split_filter_op(filters.pop(k))"},{"line_number":494,"context_line":"            if operator \u003d\u003d \u0027in\u0027:"},{"line_number":495,"context_line":"                threshold \u003d list_value.split(\u0027,\u0027)"},{"line_number":496,"context_line":"                comparison \u003d attr_value.in_(threshold)"},{"line_number":497,"context_line":"                image_conditions.append(comparison)"},{"line_number":498,"context_line":"            elif operator \u003d\u003d \u0027eq\u0027:"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a68dd71_4b965af1","line":495,"in_reply_to":"9a68dd71_10ac0f9f","updated":"2016-01-25 15:40:19.000000000","message":"In your case request will be like:\n\n?name\u003din:\"blah,blah\",apple,pears\n\nlink: https://github.com/openstack/api-wg/blob/master/guidelines/pagination_filter_sort.rst","commit_id":"0841be9c65d79458074d1f1a9217803c291a9436"},{"author":{"_account_id":7575,"name":"Sabari","email":"smurugesan@vmware.com","username":"sabari"},"change_message_id":"0eec128333c8156004f6c8d37bf0da2900bf0b8b","unresolved":false,"context_lines":[{"line_number":492,"context_line":"            attr_value \u003d getattr(models.Image, key)"},{"line_number":493,"context_line":"            operator, list_value \u003d utils.split_filter_op(filters.pop(k))"},{"line_number":494,"context_line":"            if operator \u003d\u003d \u0027in\u0027:"},{"line_number":495,"context_line":"                threshold \u003d list_value.split(\u0027,\u0027)"},{"line_number":496,"context_line":"                comparison \u003d attr_value.in_(threshold)"},{"line_number":497,"context_line":"                image_conditions.append(comparison)"},{"line_number":498,"context_line":"            elif operator \u003d\u003d \u0027eq\u0027:"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a68dd71_aea696ab","line":495,"in_reply_to":"9a68dd71_4b965af1","updated":"2016-01-25 19:43:23.000000000","message":"Anyway, if we go with that, then just a reminder, we also need to handle backslashes inside the quoted string.\n\nThanks for the reference.","commit_id":"0841be9c65d79458074d1f1a9217803c291a9436"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"a5d9bb546bdecd37e96279dba6084339fddf6995","unresolved":false,"context_lines":[{"line_number":492,"context_line":"            attr_value \u003d getattr(models.Image, key)"},{"line_number":493,"context_line":"            operator, list_value \u003d utils.split_filter_op(filters.pop(k))"},{"line_number":494,"context_line":"            if operator \u003d\u003d \u0027in\u0027:"},{"line_number":495,"context_line":"                threshold \u003d list_value.split(\u0027,\u0027)"},{"line_number":496,"context_line":"                comparison \u003d attr_value.in_(threshold)"},{"line_number":497,"context_line":"                image_conditions.append(comparison)"},{"line_number":498,"context_line":"            elif operator \u003d\u003d \u0027eq\u0027:"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a68dd71_10ac0f9f","line":495,"in_reply_to":"9a68dd71_d40441c1","updated":"2016-01-22 10:57:18.000000000","message":"Wow! Thank you Sabari. Seems like we need an escape character in this case.","commit_id":"0841be9c65d79458074d1f1a9217803c291a9436"}],"glance/tests/functional/db/base.py":[{"author":{"_account_id":14676,"name":"Kairat Kushaev","email":"kkushaev@mirantis.com","username":"kairat_kushaev"},"change_message_id":"ba35907f5c740f52c35a35b3ec6dbfcae6d39966","unresolved":false,"context_lines":[{"line_number":504,"context_line":"                                           filters\u003d{\u0027updated_at\u0027: time_expr})"},{"line_number":505,"context_line":"        self.assertEqual(0, len(images))"},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"    def test_filter_image_by_invalid_operator(self):"},{"line_number":508,"context_line":"        self.assertRaises(exception.InvalidFilterOperatorValue,"},{"line_number":509,"context_line":"                          self.db_api.image_get_all,"},{"line_number":510,"context_line":"                          self.context, filters\u003d{\u0027status\u0027: \u0027lala:active\u0027})"}],"source_content_type":"text/x-python","patch_set":7,"id":"da6ed579_5211735c","line":507,"updated":"2016-01-18 10:27:46.000000000","message":"Does it worth to add a case when just \"status\u003dactive\" has been specified?","commit_id":"c61eb5827f52a5fbfca9fe14b2977597ec2c928f"},{"author":{"_account_id":16658,"name":"Darja Shakhray","email":"damalyavkina@gmail.com","username":"dshakhray"},"change_message_id":"cf4966aed5474489036c503ffbe5782340a2fb0f","unresolved":false,"context_lines":[{"line_number":504,"context_line":"                                           filters\u003d{\u0027updated_at\u0027: time_expr})"},{"line_number":505,"context_line":"        self.assertEqual(0, len(images))"},{"line_number":506,"context_line":""},{"line_number":507,"context_line":"    def test_filter_image_by_invalid_operator(self):"},{"line_number":508,"context_line":"        self.assertRaises(exception.InvalidFilterOperatorValue,"},{"line_number":509,"context_line":"                          self.db_api.image_get_all,"},{"line_number":510,"context_line":"                          self.context, filters\u003d{\u0027status\u0027: \u0027lala:active\u0027})"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a68dd71_019afe14","line":507,"in_reply_to":"da6ed579_5211735c","updated":"2016-01-20 13:51:14.000000000","message":"This example with valid value and invalid operator","commit_id":"c61eb5827f52a5fbfca9fe14b2977597ec2c928f"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"b454aba3a3a833309044f1e740fa86c4fef02ad9","unresolved":false,"context_lines":[{"line_number":541,"context_line":""},{"line_number":542,"context_line":"    def test_image_get_all_with_quotes(self):"},{"line_number":543,"context_line":"        fixture \u003d {\u0027name\u0027: \u0027fake\\\\\\\"name\u0027}"},{"line_number":544,"context_line":"        self.db_api.image_update(self.adm_context, UUID3, fixture)"},{"line_number":545,"context_line":""},{"line_number":546,"context_line":"        fixture \u003d {\u0027name\u0027: \u0027fake,name\u0027}"},{"line_number":547,"context_line":"        self.db_api.image_update(self.adm_context, UUID2, fixture)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a57f1b5_ef4bdf57","line":544,"range":{"start_line":544,"start_character":20,"end_line":544,"end_character":32},"updated":"2016-02-10 15:21:09.000000000","message":"You update the image here, not listing","commit_id":"2dd1781a57552d2ec1e797492e654b24b4dad760"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"5ad9104a7688e3f67de51eaee9b54db482c1def5","unresolved":false,"context_lines":[{"line_number":541,"context_line":""},{"line_number":542,"context_line":"    def test_image_get_all_with_quotes(self):"},{"line_number":543,"context_line":"        fixture \u003d {\u0027name\u0027: \u0027fake\\\\\\\"name\u0027}"},{"line_number":544,"context_line":"        self.db_api.image_update(self.adm_context, UUID3, fixture)"},{"line_number":545,"context_line":""},{"line_number":546,"context_line":"        fixture \u003d {\u0027name\u0027: \u0027fake,name\u0027}"},{"line_number":547,"context_line":"        self.db_api.image_update(self.adm_context, UUID2, fixture)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a57f1b5_8f110baf","line":544,"range":{"start_line":544,"start_character":20,"end_line":544,"end_character":32},"in_reply_to":"3a57f1b5_ef4bdf57","updated":"2016-02-10 15:26:54.000000000","message":"Ah, sorry :) You list images later...","commit_id":"2dd1781a57552d2ec1e797492e654b24b4dad760"}],"glance/tests/unit/common/test_utils.py":[{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"b454aba3a3a833309044f1e740fa86c4fef02ad9","unresolved":false,"context_lines":[{"line_number":427,"context_line":"        expr \u003d \u0027in:bar\u0027"},{"line_number":428,"context_line":"        returned \u003d utils.split_filter_op(expr)"},{"line_number":429,"context_line":"        self.assertEqual((\u0027in\u0027, \u0027bar\u0027), returned)"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"    def test_default_operator(self):"},{"line_number":432,"context_line":"        expr \u003d \u0027bar\u0027"},{"line_number":433,"context_line":"        returned \u003d utils.split_filter_op(expr)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3a57f1b5_6f7ccf72","line":430,"updated":"2016-02-10 15:21:09.000000000","message":"Add several tests here with split_filter_value_for_quotes","commit_id":"2dd1781a57552d2ec1e797492e654b24b4dad760"}]}
