)]}'
{"taskflow/engines/action_engine/analyzer.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b7f1d0ed3a1e3397813a9a9ae3997d0febb40c1c","unresolved":false,"context_lines":[{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        predecessor_states \u003d self._storage.get_atoms_states(predecessor_names)"},{"line_number":185,"context_line":"        predecessor_states_iter \u003d six.itervalues(predecessor_states)"},{"line_number":186,"context_line":"        if len(predecessor_states) \u003d\u003d 0:"},{"line_number":187,"context_line":"            ok_to_run \u003d True"},{"line_number":188,"context_line":"        elif self._execution_graph.node[atom].get(\u0027required_predecessors\u0027, None) \u003d\u003d flow.Required.ANY:"},{"line_number":189,"context_line":"            ok_to_run \u003d any(state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_2478018f","line":186,"updated":"2015-08-04 21:32:06.000000000","message":"Flake8 will likely blowup on u due to line-length.","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"a6ae7a3efd903e3709491e15cf2803ed90e0a55c","unresolved":false,"context_lines":[{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        predecessor_states \u003d self._storage.get_atoms_states(predecessor_names)"},{"line_number":185,"context_line":"        predecessor_states_iter \u003d six.itervalues(predecessor_states)"},{"line_number":186,"context_line":"        if len(predecessor_states) \u003d\u003d 0:"},{"line_number":187,"context_line":"            ok_to_run \u003d True"},{"line_number":188,"context_line":"        elif self._execution_graph.node[atom].get(\u0027required_predecessors\u0027, None) \u003d\u003d flow.Required.ANY:"},{"line_number":189,"context_line":"            ok_to_run \u003d any(state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_559e8363","line":186,"in_reply_to":"1a4dcd0f_2478018f","updated":"2015-08-09 20:43:01.000000000","message":"Done","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b7f1d0ed3a1e3397813a9a9ae3997d0febb40c1c","unresolved":false,"context_lines":[{"line_number":184,"context_line":"        predecessor_states \u003d self._storage.get_atoms_states(predecessor_names)"},{"line_number":185,"context_line":"        predecessor_states_iter \u003d six.itervalues(predecessor_states)"},{"line_number":186,"context_line":"        if len(predecessor_states) \u003d\u003d 0:"},{"line_number":187,"context_line":"            ok_to_run \u003d True"},{"line_number":188,"context_line":"        elif self._execution_graph.node[atom].get(\u0027required_predecessors\u0027, None) \u003d\u003d flow.Required.ANY:"},{"line_number":189,"context_line":"            ok_to_run \u003d any(state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE"},{"line_number":190,"context_line":"                        for state, intention in predecessor_states_iter)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_a4e3b104","line":187,"updated":"2015-08-04 21:32:06.000000000","message":"Another idea,\n\nThis check seems to be static right, in that for a given atom it will never change during the lifetime of the engine that it is contained in.\n\nIf so why not just build a function that calculates the \u0027ok_to_run\u0027 value in https://github.com/openstack/taskflow/blob/master/taskflow/engines/action_engine/runtime.py#L52 (and cache it there),\n\nWhat do u think?\n\nSomething like the following could be built in that compile() function there and cached for the lifetime of that runtime (and just extracted and called in this function):\n\n\n\n  if execution_graph.predecessors(atom) \u003d\u003d 0:\n    ok_to_run_func \u003d lambda predecessor_states: True\n  elif execution_graph.node[atom].get(\u0027required_predecessors\u0027, None) \u003d\u003d flow.Required.ANY:\n    ok_to_run_func \u003d lambda predecessor_states: any(state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE\n                                                    for state, intention in predecessor_states)\n  else:\n    ok_to_run_func \u003d lambda predecessor_states: all(state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE\n                                                    for state, intention in predecessor_states)","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"a6ae7a3efd903e3709491e15cf2803ed90e0a55c","unresolved":false,"context_lines":[{"line_number":184,"context_line":"        predecessor_states \u003d self._storage.get_atoms_states(predecessor_names)"},{"line_number":185,"context_line":"        predecessor_states_iter \u003d six.itervalues(predecessor_states)"},{"line_number":186,"context_line":"        if len(predecessor_states) \u003d\u003d 0:"},{"line_number":187,"context_line":"            ok_to_run \u003d True"},{"line_number":188,"context_line":"        elif self._execution_graph.node[atom].get(\u0027required_predecessors\u0027, None) \u003d\u003d flow.Required.ANY:"},{"line_number":189,"context_line":"            ok_to_run \u003d any(state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE"},{"line_number":190,"context_line":"                        for state, intention in predecessor_states_iter)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_b3c00ce2","line":187,"in_reply_to":"1a4dcd0f_a4e3b104","updated":"2015-08-09 20:43:01.000000000","message":"made some tests it seems that for `any` case condition should be more complex, check it please, in next patch.","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"afdd40742054fc4483822678cfa7a1c232f329ac","unresolved":false,"context_lines":[{"line_number":196,"context_line":"            ok_to_run \u003d True"},{"line_number":197,"context_line":"        elif self._execution_graph.node[atom].get("},{"line_number":198,"context_line":"                flow.NODE_REQUIRED_PREDECESSORS, None) \u003d\u003d flow.Required.ANY:"},{"line_number":199,"context_line":"            count \u003d sum((state[0] \u003d\u003d st.PENDING or state[0] \u003d\u003d st.RUNNING)"},{"line_number":200,"context_line":"                        and state[1] \u003d\u003d st.EXECUTE for state"},{"line_number":201,"context_line":"                        in predecessor_states.values())"},{"line_number":202,"context_line":"            if count:"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_2b6217d9","line":199,"updated":"2015-08-10 18:42:02.000000000","message":"What about using:\n\nhttps://github.com/openstack/taskflow/blob/master/taskflow/utils/iter_utils.py#L20\n\nPretty sure u can just use that?","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"76347b67a22970200a7b4066eceb9ab33150c5d9","unresolved":false,"context_lines":[{"line_number":196,"context_line":"            ok_to_run \u003d True"},{"line_number":197,"context_line":"        elif self._execution_graph.node[atom].get("},{"line_number":198,"context_line":"                flow.NODE_REQUIRED_PREDECESSORS, None) \u003d\u003d flow.Required.ANY:"},{"line_number":199,"context_line":"            count \u003d sum((state[0] \u003d\u003d st.PENDING or state[0] \u003d\u003d st.RUNNING)"},{"line_number":200,"context_line":"                        and state[1] \u003d\u003d st.EXECUTE for state"},{"line_number":201,"context_line":"                        in predecessor_states.values())"},{"line_number":202,"context_line":"            if count:"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_4838f23d","line":199,"in_reply_to":"1a4dcd0f_2b6217d9","updated":"2015-08-16 18:15:55.000000000","message":"Done","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"afdd40742054fc4483822678cfa7a1c232f329ac","unresolved":false,"context_lines":[{"line_number":203,"context_line":"                ok_to_run \u003d False"},{"line_number":204,"context_line":"            else:"},{"line_number":205,"context_line":"                ok_to_run \u003d any("},{"line_number":206,"context_line":"                    state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE"},{"line_number":207,"context_line":"                    for state, intention in predecessor_states_iter)"},{"line_number":208,"context_line":"        else:"},{"line_number":209,"context_line":"            ok_to_run \u003d all(state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_8b91eb9c","line":206,"updated":"2015-08-10 18:42:02.000000000","message":"I wonder if this can just be combined with the above sum() loop somehow to avoid iterating over this twice, what do u think?","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"76347b67a22970200a7b4066eceb9ab33150c5d9","unresolved":false,"context_lines":[{"line_number":203,"context_line":"                ok_to_run \u003d False"},{"line_number":204,"context_line":"            else:"},{"line_number":205,"context_line":"                ok_to_run \u003d any("},{"line_number":206,"context_line":"                    state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE"},{"line_number":207,"context_line":"                    for state, intention in predecessor_states_iter)"},{"line_number":208,"context_line":"        else:"},{"line_number":209,"context_line":"            ok_to_run \u003d all(state \u003d\u003d st.SUCCESS and intention \u003d\u003d st.EXECUTE"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_0822ea01","line":206,"in_reply_to":"1a4dcd0f_8b91eb9c","updated":"2015-08-16 18:15:55.000000000","message":"ok, now it is one iteration:) also moved this to another method","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"ec79f3865f7edb566876b648daccba4f62121061","unresolved":false,"context_lines":[{"line_number":79,"context_line":"            [self._atom], runtime.analyzer.iterate_subgraph(self._atom))"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        def ignore_atoms_with_required_predecessors(atom):"},{"line_number":82,"context_line":"            atom_attrs \u003d runtime._compilation.execution_graph.node[atom]"},{"line_number":83,"context_line":"            return atom_attrs.get("},{"line_number":84,"context_line":"                flow.NODE_REQUIRED_PREDECESSORS, flow.Required.ALL) \u003d\u003d\\"},{"line_number":85,"context_line":"                flow.Required.ALL"}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_1b5c5bec","line":82,"updated":"2015-08-27 18:01:25.000000000","message":"Can u just use runtime.compilation instead of accessing runtime._compilation. Thanks :)","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"98f841cf3940ee7304edb87598a8ed90c329c3dd","unresolved":false,"context_lines":[{"line_number":79,"context_line":"            [self._atom], runtime.analyzer.iterate_subgraph(self._atom))"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        def ignore_atoms_with_required_predecessors(atom):"},{"line_number":82,"context_line":"            atom_attrs \u003d runtime._compilation.execution_graph.node[atom]"},{"line_number":83,"context_line":"            return atom_attrs.get("},{"line_number":84,"context_line":"                flow.NODE_REQUIRED_PREDECESSORS, flow.Required.ALL) \u003d\u003d\\"},{"line_number":85,"context_line":"                flow.Required.ALL"}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_7486c166","line":82,"in_reply_to":"da20952f_1b5c5bec","updated":"2015-08-27 22:34:36.000000000","message":"Done","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"ec79f3865f7edb566876b648daccba4f62121061","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                flow.Required.ALL"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        runtime.reset_nodes(filter("},{"line_number":88,"context_line":"            ignore_atoms_with_required_predecessors, successors_iter),"},{"line_number":89,"context_line":"            state\u003dst.IGNORE, intention\u003dst.IGNORE)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_1bb8dbe4","line":88,"updated":"2015-08-27 18:01:25.000000000","message":"Can u import this and use it instead (so that python2.x/3.x works in a similar manner);\n\n  \u003e\u003e from six.moves import filter as compat_filter\n\nThis makes sure the filter is an iterable one is alway used on both versions of python.","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"98f841cf3940ee7304edb87598a8ed90c329c3dd","unresolved":false,"context_lines":[{"line_number":85,"context_line":"                flow.Required.ALL"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        runtime.reset_nodes(filter("},{"line_number":88,"context_line":"            ignore_atoms_with_required_predecessors, successors_iter),"},{"line_number":89,"context_line":"            state\u003dst.IGNORE, intention\u003dst.IGNORE)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_34afe995","line":88,"in_reply_to":"da20952f_1bb8dbe4","updated":"2015-08-27 22:34:36.000000000","message":"Done","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"ec79f3865f7edb566876b648daccba4f62121061","unresolved":false,"context_lines":[{"line_number":199,"context_line":"            edge_deciders \u003d self._runtime.fetch_edge_deciders(atom)"},{"line_number":200,"context_line":"            return (True, IgnoreDecider(atom, edge_deciders))"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    def _ok_to_run(self, atom, predecessor_states):"},{"line_number":203,"context_line":"        def _is_task_not_finished(state):"},{"line_number":204,"context_line":"            return (state[0] \u003d\u003d st.PENDING or state[0] \u003d\u003d st.RUNNING)\\"},{"line_number":205,"context_line":"                and state[1] \u003d\u003d st.EXECUTE"}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_9bc06b2c","line":202,"updated":"2015-08-27 18:01:25.000000000","message":"\u0027_ok_to_run\u0027 -\u003e \u0027_is_ok_to_run\u0027 would be my preference, since its checking if it \u0027is\u0027 ok to run this.","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"98f841cf3940ee7304edb87598a8ed90c329c3dd","unresolved":false,"context_lines":[{"line_number":199,"context_line":"            edge_deciders \u003d self._runtime.fetch_edge_deciders(atom)"},{"line_number":200,"context_line":"            return (True, IgnoreDecider(atom, edge_deciders))"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    def _ok_to_run(self, atom, predecessor_states):"},{"line_number":203,"context_line":"        def _is_task_not_finished(state):"},{"line_number":204,"context_line":"            return (state[0] \u003d\u003d st.PENDING or state[0] \u003d\u003d st.RUNNING)\\"},{"line_number":205,"context_line":"                and state[1] \u003d\u003d st.EXECUTE"}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_f4697126","line":202,"in_reply_to":"da20952f_9bc06b2c","updated":"2015-08-27 22:34:36.000000000","message":"Done","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"ec79f3865f7edb566876b648daccba4f62121061","unresolved":false,"context_lines":[{"line_number":200,"context_line":"            return (True, IgnoreDecider(atom, edge_deciders))"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    def _ok_to_run(self, atom, predecessor_states):"},{"line_number":203,"context_line":"        def _is_task_not_finished(state):"},{"line_number":204,"context_line":"            return (state[0] \u003d\u003d st.PENDING or state[0] \u003d\u003d st.RUNNING)\\"},{"line_number":205,"context_line":"                and state[1] \u003d\u003d st.EXECUTE"},{"line_number":206,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_1672f2ad","line":203,"updated":"2015-08-27 18:01:25.000000000","message":"how about passing the following instead, to make it more clear what the arguments are.\n\n   def _is_task_not_finished(state, intention):\n\n\n   def _is_task_finished(state, intention):","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"98f841cf3940ee7304edb87598a8ed90c329c3dd","unresolved":false,"context_lines":[{"line_number":200,"context_line":"            return (True, IgnoreDecider(atom, edge_deciders))"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    def _ok_to_run(self, atom, predecessor_states):"},{"line_number":203,"context_line":"        def _is_task_not_finished(state):"},{"line_number":204,"context_line":"            return (state[0] \u003d\u003d st.PENDING or state[0] \u003d\u003d st.RUNNING)\\"},{"line_number":205,"context_line":"                and state[1] \u003d\u003d st.EXECUTE"},{"line_number":206,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_3487e9d8","line":203,"in_reply_to":"da20952f_1672f2ad","updated":"2015-08-27 22:34:36.000000000","message":"Done","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"}],"taskflow/engines/action_engine/compiler.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"d4ef3b155b081c2adb859513d889fc78d7a0b8cc","unresolved":false,"context_lines":[{"line_number":262,"context_line":"                                                               parent\u003dparent)"},{"line_number":263,"context_line":"        self._linker.apply_constraints(graph, flow, decomposed_members)"},{"line_number":264,"context_line":"        for (n, n_attrs) in flow.iter_nodes():"},{"line_number":265,"context_line":"            graph.node[n] \u003d n_attrs.copy()"},{"line_number":266,"context_line":"        if flow.retry is not None:"},{"line_number":267,"context_line":"            self._connect_retry(flow.retry, graph)"},{"line_number":268,"context_line":"        return graph, node"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_273b239e","line":265,"updated":"2015-08-04 21:51:52.000000000","message":"Hmmm, should this be graph.node[n].update(n_attrs) vs replacing it?\n\nI\u0027m also pretty sure this won\u0027t work when a flow contains another flow, as the graph won\u0027t have a node for that, so u may need to do this logic in  `self._decompose_flow` instead right?\n\nFor example:\n\n  \u003e\u003e\u003e f \u003d linear_flow.Flow(\u0027a\u0027)\n  \u003e\u003e\u003e f.add(linear_flow.Flow(\u0027b\u0027))\n\nWhen the decomposition happens into a flat graph there is no longer a \u0027b\u0027 flow, but only the tasks/atoms that were contained in it, so u might have to do this slightly differently.\n\nPerhaps when iterating over flows and turning them into there corresponding graphs (which are then merged into the single flat graph that is obtained here): perhaps this can just be done when https://github.com/networkx/networkx/blob/master/networkx/classes/graph.py#L408 is called (add_node)","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"a6ae7a3efd903e3709491e15cf2803ed90e0a55c","unresolved":false,"context_lines":[{"line_number":262,"context_line":"                                                               parent\u003dparent)"},{"line_number":263,"context_line":"        self._linker.apply_constraints(graph, flow, decomposed_members)"},{"line_number":264,"context_line":"        for (n, n_attrs) in flow.iter_nodes():"},{"line_number":265,"context_line":"            graph.node[n] \u003d n_attrs.copy()"},{"line_number":266,"context_line":"        if flow.retry is not None:"},{"line_number":267,"context_line":"            self._connect_retry(flow.retry, graph)"},{"line_number":268,"context_line":"        return graph, node"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_f5830f01","line":265,"in_reply_to":"1a4dcd0f_273b239e","updated":"2015-08-09 20:43:01.000000000","message":"Done","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"afdd40742054fc4483822678cfa7a1c232f329ac","unresolved":false,"context_lines":[{"line_number":261,"context_line":"        graph, node, decomposed_members \u003d self._decompose_flow(flow,"},{"line_number":262,"context_line":"                                                               parent\u003dparent)"},{"line_number":263,"context_line":"        self._linker.apply_constraints(graph, flow, decomposed_members)"},{"line_number":264,"context_line":"        for (n, n_attrs) in flow.iter_nodes():"},{"line_number":265,"context_line":"            if graph.has_node(n):"},{"line_number":266,"context_line":"                graph.node[n].update(n_attrs)"},{"line_number":267,"context_line":"        if flow.retry is not None:"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_8b9ecb52","line":264,"updated":"2015-08-10 18:42:02.000000000","message":"I\u0027m pretty sure all u need to do is pass the node attributes to https://github.com/openstack/taskflow/blob/master/taskflow/engines/action_engine/compiler.py#L193 and then they will be retained throughout the rest of the processing, that seems imho cleaner than doing this and having to check for \u0027has_node\u0027","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"76347b67a22970200a7b4066eceb9ab33150c5d9","unresolved":false,"context_lines":[{"line_number":261,"context_line":"        graph, node, decomposed_members \u003d self._decompose_flow(flow,"},{"line_number":262,"context_line":"                                                               parent\u003dparent)"},{"line_number":263,"context_line":"        self._linker.apply_constraints(graph, flow, decomposed_members)"},{"line_number":264,"context_line":"        for (n, n_attrs) in flow.iter_nodes():"},{"line_number":265,"context_line":"            if graph.has_node(n):"},{"line_number":266,"context_line":"                graph.node[n].update(n_attrs)"},{"line_number":267,"context_line":"        if flow.retry is not None:"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_d7bea863","line":264,"in_reply_to":"1a4dcd0f_8b9ecb52","updated":"2015-08-16 18:15:55.000000000","message":"Done","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"a35dd9a1acf9f6d1c26cad7ddb2ce02442a6c0f8","unresolved":false,"context_lines":[{"line_number":245,"context_line":"        if flow.retry is not None:"},{"line_number":246,"context_line":"            node.add(tr.Node(flow.retry))"},{"line_number":247,"context_line":"        decomposed_members \u003d {}"},{"line_number":248,"context_line":"        for item in flow:"},{"line_number":249,"context_line":"            attrs \u003d flow.get_node_meta(item)"},{"line_number":250,"context_line":"            subgraph, _subnode \u003d self._deep_compiler_func(item,"},{"line_number":251,"context_line":"                                                          parent\u003dnode,"}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_56d70a23","line":248,"updated":"2015-08-27 18:03:53.000000000","message":"Why not just use iter_nodes() which returns the data here?\n\nVs having a new `get_node_meta` method?","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"98f841cf3940ee7304edb87598a8ed90c329c3dd","unresolved":false,"context_lines":[{"line_number":245,"context_line":"        if flow.retry is not None:"},{"line_number":246,"context_line":"            node.add(tr.Node(flow.retry))"},{"line_number":247,"context_line":"        decomposed_members \u003d {}"},{"line_number":248,"context_line":"        for item in flow:"},{"line_number":249,"context_line":"            attrs \u003d flow.get_node_meta(item)"},{"line_number":250,"context_line":"            subgraph, _subnode \u003d self._deep_compiler_func(item,"},{"line_number":251,"context_line":"                                                          parent\u003dnode,"}],"source_content_type":"text/x-python","patch_set":10,"id":"da20952f_74f24171","line":248,"in_reply_to":"da20952f_56d70a23","updated":"2015-08-27 22:34:36.000000000","message":"Done","commit_id":"20ad1c0927afd8dff1173ca9ddcd73337e02dfe1"}],"taskflow/engines/action_engine/runtime.py":[{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"4e729bc079edd3c6d3de5f7a9c125e30d7f2438b","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        tweaked \u003d []"},{"line_number":203,"context_line":"        for atom in atoms:"},{"line_number":204,"context_line":"            if atom.parents_required !\u003d task.Required.ALL:"},{"line_number":205,"context_line":"                continue"},{"line_number":206,"context_line":"            metadata \u003d self._atom_cache[atom.name]"},{"line_number":207,"context_line":"            atom_meta \u003d self.compilation.execution_graph.node[atom]"},{"line_number":208,"context_line":"            if atom_meta.get(\u0027required_predecessors\u0027, None) !\u003d flow.Required.ALL:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_5182ad95","line":205,"updated":"2015-08-04 21:18:21.000000000","message":"left from patch set one","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"a6ae7a3efd903e3709491e15cf2803ed90e0a55c","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        tweaked \u003d []"},{"line_number":203,"context_line":"        for atom in atoms:"},{"line_number":204,"context_line":"            if atom.parents_required !\u003d task.Required.ALL:"},{"line_number":205,"context_line":"                continue"},{"line_number":206,"context_line":"            metadata \u003d self._atom_cache[atom.name]"},{"line_number":207,"context_line":"            atom_meta \u003d self.compilation.execution_graph.node[atom]"},{"line_number":208,"context_line":"            if atom_meta.get(\u0027required_predecessors\u0027, None) !\u003d flow.Required.ALL:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_15a47bb7","line":205,"in_reply_to":"1a4dcd0f_5182ad95","updated":"2015-08-09 20:43:01.000000000","message":"Done","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b7f1d0ed3a1e3397813a9a9ae3997d0febb40c1c","unresolved":false,"context_lines":[{"line_number":205,"context_line":"                continue"},{"line_number":206,"context_line":"            metadata \u003d self._atom_cache[atom.name]"},{"line_number":207,"context_line":"            atom_meta \u003d self.compilation.execution_graph.node[atom]"},{"line_number":208,"context_line":"            if atom_meta.get(\u0027required_predecessors\u0027, None) !\u003d flow.Required.ALL:"},{"line_number":209,"context_line":"                continue"},{"line_number":210,"context_line":"            if state or intention:"},{"line_number":211,"context_line":"                tweaked.append((atom, state, intention))"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_44350dd8","line":208,"updated":"2015-08-04 21:32:06.000000000","message":"Interesting. I\u0027m wonder if we should do a continue here, vs just resetting the node to its original state no matter what the \u0027required_predecessors\u0027 is, since resetting to me implies that its going to be reset, not that it \u0027may or may not be reset\u0027. What\u0027s the harm in just letting it get reset completely?","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"a6ae7a3efd903e3709491e15cf2803ed90e0a55c","unresolved":false,"context_lines":[{"line_number":205,"context_line":"                continue"},{"line_number":206,"context_line":"            metadata \u003d self._atom_cache[atom.name]"},{"line_number":207,"context_line":"            atom_meta \u003d self.compilation.execution_graph.node[atom]"},{"line_number":208,"context_line":"            if atom_meta.get(\u0027required_predecessors\u0027, None) !\u003d flow.Required.ALL:"},{"line_number":209,"context_line":"                continue"},{"line_number":210,"context_line":"            if state or intention:"},{"line_number":211,"context_line":"                tweaked.append((atom, state, intention))"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_8c42b866","line":208,"in_reply_to":"1a4dcd0f_44350dd8","updated":"2015-08-09 20:43:01.000000000","message":"We need to ignore nodes with required_predecessors attribute.Analyzer resets their state to Ignore https://github.com/openstack/taskflow/blob/master/taskflow/engines/action_engine/analyzer.py#L78 I could filter them in analyzer\u0027s affect method. So reset_nodes become unchanged.","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"}],"taskflow/examples/switch_graph_flow.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"8acf5f8277e621dc4b496f30513b70867171cc72","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    return False"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"# Declare our work to be done..."},{"line_number":45,"context_line":"r \u003d gf.Flow(\"root\")"},{"line_number":46,"context_line":"r_a \u003d DummyTask(\u0027r-a\u0027)"},{"line_number":47,"context_line":"r_b \u003d DummyTask(\u0027r-b\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_24ba41c1","line":44,"updated":"2015-08-04 21:33:09.000000000","message":"Maybe we should have a new example that shows this? What do u think?","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"a6ae7a3efd903e3709491e15cf2803ed90e0a55c","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    return False"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"# Declare our work to be done..."},{"line_number":45,"context_line":"r \u003d gf.Flow(\"root\")"},{"line_number":46,"context_line":"r_a \u003d DummyTask(\u0027r-a\u0027)"},{"line_number":47,"context_line":"r_b \u003d DummyTask(\u0027r-b\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_55c76363","line":44,"in_reply_to":"1a4dcd0f_24ba41c1","updated":"2015-08-09 20:43:01.000000000","message":"Done","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"}],"taskflow/flow.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b7f1d0ed3a1e3397813a9a9ae3997d0febb40c1c","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        \"\"\""},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    @abc.abstractmethod"},{"line_number":107,"context_line":"    def iter_nodes(self):"},{"line_number":108,"context_line":"        \"\"\"Iterate over nodes of the flow"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_1132e510","line":107,"updated":"2015-08-04 21:32:06.000000000","message":"Hmmm, did u want this to be?\n\n  @abc.abstractmethod\n  def iter_nodes(self, data\u003dTrue):\n     ...\n\nProbably useful to have the docstring be similar to `iter_links` also.","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"a6ae7a3efd903e3709491e15cf2803ed90e0a55c","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        \"\"\""},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"    @abc.abstractmethod"},{"line_number":107,"context_line":"    def iter_nodes(self):"},{"line_number":108,"context_line":"        \"\"\"Iterate over nodes of the flow"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_75fdbfaf","line":107,"in_reply_to":"1a4dcd0f_1132e510","updated":"2015-08-09 20:43:01.000000000","message":"Done","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"}],"taskflow/patterns/graph_flow.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"b7f1d0ed3a1e3397813a9a9ae3997d0febb40c1c","unresolved":false,"context_lines":[{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def set_required_predecessors(self, node,required\u003dflow.Required.ALL):"},{"line_number":121,"context_line":"        graph \u003d gr.DiGraph(self._graph)"},{"line_number":122,"context_line":"        graph.node[node].update({\u0027required_predecessors\u0027: required})"},{"line_number":123,"context_line":"        self._swap(graph)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_847d551e","line":122,"updated":"2015-08-04 21:32:06.000000000","message":"Cool, few comments would be to:\n\n  - Make \u0027required_predecessors\u0027 a constant so that it can be used by the engine (vs duplicating strings all over the place); possibly putting it under https://github.com/openstack/taskflow/blob/master/taskflow/flow.py#L22 (similar constants used already).\n  - Check that the node exists in graph.node before doing things on it and throw an appropriate exception if the node isn\u0027t even in the graph.\n\n    \u003e\u003e\u003e import networkx as nx\n    \u003e\u003e\u003e g \u003d nx.DiGraph()\n    \u003e\u003e\u003e g.has_node\n    \u003e\u003e\u003e g.has_node(\u0027a\u0027)\n    False\n\n    vs\n\n    \u003e\u003e\u003e g.node[\u0027b\u0027]\n    Traceback (most recent call last):\n      File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n    KeyError: \u0027b\u0027","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"a6ae7a3efd903e3709491e15cf2803ed90e0a55c","unresolved":false,"context_lines":[{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def set_required_predecessors(self, node,required\u003dflow.Required.ALL):"},{"line_number":121,"context_line":"        graph \u003d gr.DiGraph(self._graph)"},{"line_number":122,"context_line":"        graph.node[node].update({\u0027required_predecessors\u0027: required})"},{"line_number":123,"context_line":"        self._swap(graph)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a4dcd0f_15d31b61","line":122,"in_reply_to":"1a4dcd0f_847d551e","updated":"2015-08-09 20:43:01.000000000","message":"Done","commit_id":"3e02dca0bccbb8fca0061a43d5ecc501669cfb08"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"afdd40742054fc4483822678cfa7a1c232f329ac","unresolved":false,"context_lines":[{"line_number":263,"context_line":"            yield n"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    def iter_links(self, data\u003dTrue):"},{"line_number":266,"context_line":"        for (u, v, e_data) in self._get_subgraph().edges_iter(data\u003ddata):"},{"line_number":267,"context_line":"            yield (u, v, e_data)"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def iter_nodes(self, data\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_abe707ab","line":266,"updated":"2015-08-10 18:42:02.000000000","message":"Sooo if data\u003dFalse this won\u0027t be returning a 3 tuple, so probably should handle that appropriately.\n\n    \u003e\u003e\u003e import networkx as nx\n    \u003e\u003e\u003e g \u003d nx.DiGraph()\n    \u003e\u003e\u003e g.add_node(\u0027a\u0027)\n    \u003e\u003e\u003e g.add_node(\u0027b\u0027)\n    \u003e\u003e\u003e g.add_edge(\u0027a\u0027, \u0027b\u0027)\n    \u003e\u003e\u003e for (u, v, e_data) in g.edges_iter(data\u003dFalse):\n    ...    pass\n    ... \n    Traceback (most recent call last):\n      File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n    ValueError: need more than 2 values to unpack","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"76347b67a22970200a7b4066eceb9ab33150c5d9","unresolved":false,"context_lines":[{"line_number":263,"context_line":"            yield n"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    def iter_links(self, data\u003dTrue):"},{"line_number":266,"context_line":"        for (u, v, e_data) in self._get_subgraph().edges_iter(data\u003ddata):"},{"line_number":267,"context_line":"            yield (u, v, e_data)"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def iter_nodes(self, data\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_a2ac6aed","line":266,"in_reply_to":"1a4dcd0f_abe707ab","updated":"2015-08-16 18:15:55.000000000","message":"Done","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"afdd40742054fc4483822678cfa7a1c232f329ac","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            yield (u, v, e_data)"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def iter_nodes(self, data\u003dTrue):"},{"line_number":270,"context_line":"        for (u, u_data) in self._get_subgraph().nodes_iter(data\u003ddata):"},{"line_number":271,"context_line":"            yield (u, u_data)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_2bfc573d","line":270,"updated":"2015-08-10 18:42:02.000000000","message":"Same issue as above.","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"76347b67a22970200a7b4066eceb9ab33150c5d9","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            yield (u, v, e_data)"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def iter_nodes(self, data\u003dTrue):"},{"line_number":270,"context_line":"        for (u, u_data) in self._get_subgraph().nodes_iter(data\u003ddata):"},{"line_number":271,"context_line":"            yield (u, u_data)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_02843e5b","line":270,"in_reply_to":"1a4dcd0f_2bfc573d","updated":"2015-08-16 18:15:55.000000000","message":"Done","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"}],"taskflow/patterns/linear_flow.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"afdd40742054fc4483822678cfa7a1c232f329ac","unresolved":false,"context_lines":[{"line_number":57,"context_line":"            prior_provides.update(item.provides)"},{"line_number":58,"context_line":"        return frozenset(requires)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def iter_links(self, data\u003dTrue):"},{"line_number":61,"context_line":"        for src, dst in zip(self._children[:-1], self._children[1:]):"},{"line_number":62,"context_line":"            yield (src, dst, _LINK_METADATA.copy())"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_eb5f4f73","line":60,"updated":"2015-08-10 18:42:02.000000000","message":"Sooo u probably want to do the following right?\n\n    if data:\n      for src, dst in zip(self._children[:-1], self._children[1:]):\n        yield (src, dst, _LINK_METADATA.copy()) \n    else:\n      for src, dst in zip(self._children[:-1], self._children[1:]):\n       yield (src, dst)","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"76347b67a22970200a7b4066eceb9ab33150c5d9","unresolved":false,"context_lines":[{"line_number":57,"context_line":"            prior_provides.update(item.provides)"},{"line_number":58,"context_line":"        return frozenset(requires)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    def iter_links(self, data\u003dTrue):"},{"line_number":61,"context_line":"        for src, dst in zip(self._children[:-1], self._children[1:]):"},{"line_number":62,"context_line":"            yield (src, dst, _LINK_METADATA.copy())"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_8fb6b7da","line":60,"in_reply_to":"1a4dcd0f_eb5f4f73","updated":"2015-08-16 18:15:55.000000000","message":"Done","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"afdd40742054fc4483822678cfa7a1c232f329ac","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            yield (src, dst, _LINK_METADATA.copy())"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def iter_nodes(self, data\u003dTrue):"},{"line_number":65,"context_line":"        for n in self._children:"},{"line_number":66,"context_line":"            yield (n, {})"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_ab594790","line":65,"updated":"2015-08-10 18:42:02.000000000","message":"Same as above, u now have to do different things depending on if data is requested or not.","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"76347b67a22970200a7b4066eceb9ab33150c5d9","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            yield (src, dst, _LINK_METADATA.copy())"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def iter_nodes(self, data\u003dTrue):"},{"line_number":65,"context_line":"        for n in self._children:"},{"line_number":66,"context_line":"            yield (n, {})"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_02d2fe5b","line":65,"in_reply_to":"1a4dcd0f_ab594790","updated":"2015-08-16 18:15:55.000000000","message":"Done","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"}],"taskflow/patterns/unordered_flow.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"afdd40742054fc4483822678cfa7a1c232f329ac","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        return iter(())"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def iter_nodes(self, data\u003dTrue):"},{"line_number":52,"context_line":"        for n in self._children:"},{"line_number":53,"context_line":"            yield (n, {})"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_6b89ffc9","line":52,"updated":"2015-08-10 18:42:02.000000000","message":"Need to handle data/no data here as like in other patterns.","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"},{"author":{"_account_id":14819,"name":"Timofey Durakov","email":"timofei.nd@gmail.com","username":"tdurakov"},"change_message_id":"76347b67a22970200a7b4066eceb9ab33150c5d9","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        return iter(())"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def iter_nodes(self, data\u003dTrue):"},{"line_number":52,"context_line":"        for n in self._children:"},{"line_number":53,"context_line":"            yield (n, {})"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_c2c73696","line":52,"in_reply_to":"1a4dcd0f_6b89ffc9","updated":"2015-08-16 18:15:55.000000000","message":"Done","commit_id":"309938361cb375daa3a7a0170a34841cfe2fbc55"}]}
