)]}'
{"bin/swift-get-nodes":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":24,"context_line":"from swift.obj.diskfile import get_data_dir"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def print_item_locations(args):"},{"line_number":28,"context_line":"    account, container, obj, part, hash_str, nodes, more_nodes, loc \u003d args"},{"line_number":29,"context_line":"    target \u003d \u0027%s/%s/%s\u0027 % (account, container, obj)"},{"line_number":30,"context_line":"    print \u0027\\nAccount \\t%s\u0027 % account"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"AAAAW3%2F%2F%2FQY%3D","line":27,"updated":"2014-04-09 02:32:18.000000000","message":"I love pulling this into a function, but there seems to be some overlap with swift.cli.info.print_ring_locations - can this be moved closer to that implementation?","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    usage \u003d \u0027\u0027\u0027"},{"line_number":133,"context_line":"        Shows the nodes responsible for the item specified."},{"line_number":134,"context_line":"        Usage: %prog [-a] \u003cring.gz\u003e \u003caccount\u003e [\u003ccontainer\u003e] [\u003cobject\u003e]"},{"line_number":135,"context_line":"           Or: %prog [-a] \u003cring.gz\u003e -p partition"},{"line_number":136,"context_line":"           Or: %prog [-a] -P \u003cpolicy-name\u003e [-d \u003c/etc/swift/\u003e] \u003caccount\u003e \\"},{"line_number":137,"context_line":"\u003ccontainer\u003e \u003cobject\u003e"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"AAAAW3%2F%2F%2FN0%3D","line":134,"updated":"2014-04-09 02:32:18.000000000","message":"I know the current implementation expects the ring as an argument, but would things be simpler if you just removed that now?\n\ni.e.\n\n    if os.path.exists(args[0]):\n        ring \u003d Ring(args.pop(0))\n    else:\n        ring \u003d None\n\n    if \u0027/\u0027 in args[0]:\n        acct, cont, obj \u003d magic_path_split(args[0])\n    else:\n        acct, cont, obj \u003d magic_args_split(args[0])\n\n    if obj and not ring:\n        if not options.policy:\n            SystemExit(\u0027need a ring or policy\u0027)\n        ring \u003d POLICIES.get_ring(options.policy)\n\n    if cont and not ring:\n        ring \u003d Ring(swift_dir/container.ring.gz)\n    if acct and not ring:\n        ring \u003d Ring(swift_dir/account.ring.gz)\n\nI guess the tricky bit is\n\n    swift-get-nodes /this/path/does/not/exist.ring.gz /account/container/obj\n\nBut maybe you can figure something out...","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":160,"context_line":"        sys.exit(parser.print_usage())"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    if options.policy_name and len(args) !\u003d 3:"},{"line_number":163,"context_line":"        sys.exit(parser.print_usage())"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"    if len(args) \u003d\u003d 2 and \u0027/\u0027 in args[1]:"},{"line_number":166,"context_line":"        # Parse single path arg, as noted in above help text."}],"source_content_type":"application/octet-stream","patch_set":4,"id":"AAAAW3%2F%2F%2FP4%3D","line":163,"updated":"2014-04-09 02:32:18.000000000","message":"Can you support the form \u0027swift-get-nodes -P gold /account/container/obj\u0027?","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"}],"bin/swift-object-info":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"bf828035d9236b6a23b7daef851411aba015daed","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"def get_datadir_from_filepath(path):"},{"line_number":29,"context_line":"    #/srv/node/device/objects-dir/part/sufix/hash/timestamp.data"},{"line_number":30,"context_line":"    return path.split(\u0027/\u0027)[-5]"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"def print_object_info(*args, **kwargs):"}],"source_content_type":"application/octet-stream","patch_set":2,"id":"AAAAWH%2F%2BOqY%3D","line":30,"updated":"2014-03-28 08:52:26.000000000","message":"maybe \"get policy index from datadir\" and make policy completely optional (for backwards compat too)\n\n    int(os.path.basename(os.path.abspath(os.path.join(path, \u0027../../../../\u0027))).rsplit(\u0027-\u0027, 1)[-1])\n\nIf parsing fails because you\u0027re in a weird directory, and no policy option was provided, just treat it like ring is None.  If parsing fails but you were given a policy option - just use that like nothing happened.\n\nIf parsing succeeds and index doesn\u0027t match policy option\u0027s index - print a warning - what you have looks fine - but always use the given policy option to do all of the ring and datadir calculations.  This could be useful if you have a .data file in one location and you want to know what nodes it should be in if it was in a different policy.","commit_id":"939ef14d5509ec22a0ecf6268b3406435129adf8"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    swift_dir \u003d kwargs[\u0027swift_dir\u0027]"},{"line_number":35,"context_line":"    policy_name \u003d kwargs[\u0027policy_name\u0027]"},{"line_number":36,"context_line":"    policy_index \u003d None"},{"line_number":37,"context_line":"    ring \u003d None"},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"    if not exists(datafile) or not datafile.endswith(\u0027.data\u0027):"},{"line_number":40,"context_line":"        print \"Data file doesn\u0027t exist\""}],"source_content_type":"application/octet-stream","patch_set":4,"id":"AAAAW3%2F%2F%2FH0%3D","line":37,"updated":"2014-04-09 02:32:18.000000000","message":"oh wow, I think this looked a *lot* better in the signature.\n\nWhen you define a python function with (*args, **kwargs) it makes it look like you can call it without any args or kwargs - and this function would blow up pretty hard without some specific requirements.\n\nIf you need to *ignore* some extra kwargs you could stick a **kwargs on the end.  But otherwise it\u0027s better to call them out even if it means duplicating the defaults from the parser.  Sometimes I\u0027ll create my OptionParser as a global so on my function signatures can say \"swift_dir\u003dparser.defaults[\u0027swift_dir\u0027]\".\n\nThe other time you have to do this in py2 sometimes is if you want func(arg1, *args, default\u003dNone, **kwargs) - which is invalid (works in py3).  But in py2 you have to say:\n\n    func(arg1, *args, **kwargs)\n        default \u003d kwargs.get(\u0027default\u0027, None)\n\n^ which still supports calling w/o the named kwarg.","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":138,"context_line":"            print"},{"line_number":139,"context_line":"            print \u0027Attention: Ring location missmatching deteced!\u0027"},{"line_number":140,"context_line":"            print \u0027Double check your policy name!\u0027"},{"line_number":141,"context_line":"            print"},{"line_number":142,"context_line":"        print \u0027Ring locations:\u0027"},{"line_number":143,"context_line":"        part, nodes \u003d ring.get_nodes(account, container, obj)"},{"line_number":144,"context_line":"        for node in nodes:"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"AAAAW3%2F%2F%2FK8%3D","line":141,"updated":"2014-04-09 02:32:18.000000000","message":"phew, had trouble pulling this one a part.  I guess it\u0027s just complicated.  The comments helped.\n\nBut maybe if you called _policy_index like parsed_policy_index or moved it closer to the parsing of the policy_name option so it was clearer that policy_index came from the command line option it\u0027d be easier to follow?","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":172,"context_line":"                      help\u003d\"Pass the location of swift config directory,\\"},{"line_number":173,"context_line":"                            default is \u0027/etc/swift\u0027\")"},{"line_number":174,"context_line":"    parser.add_option(\u0027-p\u0027, \u0027--policy-name\u0027, dest\u003d\u0027policy_name\u0027,"},{"line_number":175,"context_line":"                      help\u003d\"Specify the policy name\")"},{"line_number":176,"context_line":"    options, args \u003d parser.parse_args(argv)"},{"line_number":177,"context_line":"    if len(args[1:]) \u003d\u003d 0:"},{"line_number":178,"context_line":"        sys.exit(parser.print_usage())"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"AAAAW3%2F%2F%2FRQ%3D","line":175,"updated":"2014-04-09 02:32:18.000000000","message":"Should use -P here to stay consistent with swift-get-nodes","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":175,"context_line":"                      help\u003d\"Specify the policy name\")"},{"line_number":176,"context_line":"    options, args \u003d parser.parse_args(argv)"},{"line_number":177,"context_line":"    if len(args[1:]) \u003d\u003d 0:"},{"line_number":178,"context_line":"        sys.exit(parser.print_usage())"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"    print_object_info(*args, **vars(options))"},{"line_number":181,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":4,"id":"AAAAW3%2F%2F%2FIc%3D","line":178,"updated":"2014-04-09 02:32:18.000000000","message":"is that trying to say if there is no first argument?  I mean... I guess that\u0027s what it\u0027s saying.  If the length of the list without the first element is zero...\n\nI think you just want \"if len(args) !\u003d 1\" and be done with it.","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"}],"swift/common/utils.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":2636,"context_line":"    elif \u0027-\u0027 in datadir:"},{"line_number":2637,"context_line":"        try:"},{"line_number":2638,"context_line":"            if datadir.rsplit(\u0027-\u0027, 1)[0] \u003d\u003d \u0027objects\u0027:"},{"line_number":2639,"context_line":"                return int(datadir.rsplit(\u0027-\u0027, 1)[-1])"},{"line_number":2640,"context_line":"        except ValueError:"},{"line_number":2641,"context_line":"            return None"},{"line_number":2642,"context_line":"    return None"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F%2FNc%3D","line":2639,"updated":"2014-04-09 02:32:18.000000000","message":"awww, double rsplit - probably clearer to just:\n\n    dir, index \u003d datadir.split(\u0027-\u0027, 1)\n    if dir \u003d\u003d \u0027objects\u0027:\n        return int(index)","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15af7fc2cefde146079e3f15ea9451cb1e2855b3","unresolved":false,"context_lines":[{"line_number":2638,"context_line":"            if datadir.rsplit(\u0027-\u0027, 1)[0] \u003d\u003d \u0027objects\u0027:"},{"line_number":2639,"context_line":"                return int(datadir.rsplit(\u0027-\u0027, 1)[-1])"},{"line_number":2640,"context_line":"        except ValueError:"},{"line_number":2641,"context_line":"            return None"},{"line_number":2642,"context_line":"    return None"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAW3%2F%2F%2FLY%3D","line":2641,"updated":"2014-04-09 02:32:18.000000000","message":"you can just just \"pass\" here right?\n\noh oh, or maybe set \"policy_index \u003d None\" at the top, and then update it as you go - then you get that \"single function exit point\" that some folks who watch cyclomatic complexity care about.\n\nAlso I\u0027ve been bitten a couple of times by functions that use None to indicate an error - especially ones that can also return non-truthy values (like 0).  You might check your call site, if you\u0027re already doing:\n\n    policy_index \u003d get_policy(datadir)\n    if policy_index is None:\n        # recovery\n\nYou may find it\u0027s just as easy to write:\n\n    try:\n        policy_index \u003d get_policy(datadir)\n    except ValueError:\n        # recovery","commit_id":"26e86383d3ee1d8d32d9fd8f501ea49179c5bb1f"}]}
