# UNDF: UNDF-2026-000000722 --- a/distlib/util.py +++ b/distlib/util.py @@ -1,6 +1,6 @@ import codecs -from collections import deque +from collections import deque, OrderedDict import contextlib @@ -1127,16 +1127,16 @@ def get_steps(self, final): if not self.is_step(final): raise ValueError('Unknown: %r' % final) - result = [] - todo = [] + result = OrderedDict() # preserves insertion order, O(1) move_to_end + todo = deque() # O(1) popleft instead of O(N) list.pop(0) seen = set() - todo.append(final) + todo.append(final) # deque.append is O(1) while todo: - step = todo.pop(0) + step = todo.popleft() # O(1) instead of O(N) list.pop(0) if step in seen: # if a step was already seen, # move it to the end (so it will appear earlier # when reversed on return) ... but not for the # final step, as that would be confusing for # users if step != final: - result.remove(step) # O(N) list scan - result.append(step) + result.move_to_end(step) # O(1) OrderedDict relink else: seen.add(step) - result.append(step) + result[step] = None preds = self._preds.get(step, ()) todo.extend(preds) - return reversed(result) + return reversed(list(result))