From 926295449a12b8fb51632b1823f0ce6995031254 Mon Sep 17 00:00:00 2001 From: Davide Depau <davide@depau.eu> Date: Fri, 26 Jan 2018 15:38:14 +0100 Subject: [PATCH 1/4] Ensure outgoing edge map is sorted by upstream label --- ffmpeg/dag.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ffmpeg/dag.py b/ffmpeg/dag.py index 3ce3891..86c695f 100644 --- a/ffmpeg/dag.py +++ b/ffmpeg/dag.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from ._utils import get_hash, get_hash_int from builtins import object -from collections import namedtuple +from collections import namedtuple, OrderedDict class DagNode(object): @@ -157,7 +157,7 @@ def topo_sort(downstream_nodes): raise RuntimeError('Graph is not a DAG') if downstream_node is not None: - outgoing_edge_map = outgoing_edge_maps.get(upstream_node, {}) + outgoing_edge_map = outgoing_edge_maps.get(upstream_node, OrderedDict()) outgoing_edge_infos = outgoing_edge_map.get(upstream_label, []) outgoing_edge_infos += [(downstream_node, downstream_label)] outgoing_edge_map[upstream_label] = outgoing_edge_infos @@ -174,4 +174,10 @@ def topo_sort(downstream_nodes): while unmarked_nodes: upstream_node, upstream_label = unmarked_nodes.pop() visit(upstream_node, upstream_label, None, None) + + # Sort outgoing edge maps by upstream label + for map in outgoing_edge_maps.values(): + for label in sorted(map.keys()): + map.move_to_end(label) + return sorted_nodes, outgoing_edge_maps From b7455d3261033c202fc78fb53a3391b1d3924b81 Mon Sep 17 00:00:00 2001 From: Davide Depau <davide@depau.eu> Date: Fri, 26 Jan 2018 16:02:31 +0100 Subject: [PATCH 2/4] Move OrderedDict sorting code to own function --- ffmpeg/_utils.py | 6 ++++++ ffmpeg/dag.py | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ffmpeg/_utils.py b/ffmpeg/_utils.py index 9b575a0..d3acc4c 100644 --- a/ffmpeg/_utils.py +++ b/ffmpeg/_utils.py @@ -27,6 +27,7 @@ def get_hash(item): repr_ = _recursive_repr(item).encode('utf-8') return hashlib.md5(repr_).hexdigest() + def get_hash_int(item): return int(get_hash(item), base=16) @@ -41,3 +42,8 @@ def escape_chars(text, chars): for ch in chars: text = text.replace(ch, '\\' + ch) return text + + +def sort_ordereddict(d): + for key in sorted(d.keys()): + d.move_to_end(key) diff --git a/ffmpeg/dag.py b/ffmpeg/dag.py index 86c695f..7e6b91e 100644 --- a/ffmpeg/dag.py +++ b/ffmpeg/dag.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from ._utils import get_hash, get_hash_int +from ._utils import get_hash, get_hash_int, sort_ordereddict from builtins import object from collections import namedtuple, OrderedDict @@ -177,7 +177,6 @@ def topo_sort(downstream_nodes): # Sort outgoing edge maps by upstream label for map in outgoing_edge_maps.values(): - for label in sorted(map.keys()): - map.move_to_end(label) + sort_ordereddict(map) return sorted_nodes, outgoing_edge_maps From b4e8c38b68402f15d6a74ef56fe4c6843669115d Mon Sep 17 00:00:00 2001 From: Davide Depau <davide@depau.eu> Date: Fri, 26 Jan 2018 16:05:56 +0100 Subject: [PATCH 3/4] Also ensure sortedness of incoming edge map --- ffmpeg/nodes.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ffmpeg/nodes.py b/ffmpeg/nodes.py index 2b4c94f..749cc74 100644 --- a/ffmpeg/nodes.py +++ b/ffmpeg/nodes.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals +from collections import OrderedDict + from .dag import KwargReprNode from ._utils import escape_chars, get_hash_int from builtins import object @@ -46,7 +48,7 @@ def get_stream_map(stream_spec): elif isinstance(stream_spec, Stream): stream_map = {None: stream_spec} elif isinstance(stream_spec, (list, tuple)): - stream_map = dict(enumerate(stream_spec)) + stream_map = OrderedDict(enumerate(stream_spec)) elif isinstance(stream_spec, dict): stream_map = stream_spec return stream_map @@ -84,7 +86,7 @@ class Node(KwargReprNode): @classmethod def __get_incoming_edge_map(cls, stream_map): - incoming_edge_map = {} + incoming_edge_map = OrderedDict() for downstream_label, upstream in list(stream_map.items()): incoming_edge_map[downstream_label] = (upstream.node, upstream.label) return incoming_edge_map From 34cc51d95d915fb2400e50c1c04e088520f41c75 Mon Sep 17 00:00:00 2001 From: Davide Depau <davide@depau.eu> Date: Fri, 26 Jan 2018 16:13:39 +0100 Subject: [PATCH 4/4] Replace OrderedDict.move_to_end with Python2-compatible alternative --- ffmpeg/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg/_utils.py b/ffmpeg/_utils.py index d3acc4c..0c10d4f 100644 --- a/ffmpeg/_utils.py +++ b/ffmpeg/_utils.py @@ -46,4 +46,4 @@ def escape_chars(text, chars): def sort_ordereddict(d): for key in sorted(d.keys()): - d.move_to_end(key) + d[key] = d.pop(key)