Patchwork [2,of,2] revset: force ascending order for baseset initialised from a set

login
register
mail settings
Submitter Pierre-Yves David
Date April 5, 2016, 1:13 a.m.
Message ID <39f4a3ece731d5bb2ea1.1459818797@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/14362/
State Accepted
Delegated to: Yuya Nishihara
Headers show

Comments

Pierre-Yves David - April 5, 2016, 1:13 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1459817154 25200
#      Mon Apr 04 17:45:54 2016 -0700
# Node ID 39f4a3ece731d5bb2ea16ace36712ddd696e613a
# Parent  0f39406de1cb1a95008c3b97273ebc7da7bf7c6b
# Available At http://mercurial-scm.org/repo/users/marmoute/mercurial/
#              hg pull http://mercurial-scm.org/repo/users/marmoute/mercurial/ -r 39f4a3ece731
# EXP-Topic pypy.revset
revset: force ascending order for baseset initialised from a set

It is possible to initialise a baseset directly from a set object. However, in
this case the iteration order was inherited from the set. Set have undefined
iteration order (especially cpython and pypy will have different one) so we
should not rely on it anywhere.

Therefor we declare the baseset "ascending" to enforce a consistent iteration
order. The sorting is done lazily by the baseset class and should have no
performance impact when it does not matter.

This makes test-revset.t pass with pypy.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2800,17 +2800,19 @@  class baseset(abstractsmartset):
     def __init__(self, data=(), datarepr=None):
         """
         datarepr: a tuple of (format, obj, ...), a function or an object that
                   provides a printable representation of the given data.
         """
+        self._ascending = None
         if not isinstance(data, list):
             if isinstance(data, set):
                 self._set = data
+                # set have no order we pick one for stability purpose
+                self._ascending = True
             data = list(data)
         self._list = data
         self._datarepr = datarepr
-        self._ascending = None
 
     @util.propertycache
     def _set(self):
         return set(self._list)