Patchwork [5,of,5,STABLE,pypy] util: fix sortdict.update() to call __setitem__() on PyPy (issue5639)

login
register
mail settings
Submitter Yuya Nishihara
Date Aug. 2, 2017, 2:22 p.m.
Message ID <b05cb26a301c4495f518.1501683745@mimosa>
Download mbox | patch
Permalink /patch/22640/
State Accepted
Headers show

Comments

Yuya Nishihara - Aug. 2, 2017, 2:22 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1501681879 -32400
#      Wed Aug 02 22:51:19 2017 +0900
# Branch stable
# Node ID b05cb26a301c4495f518f7180a69389b839a1fed
# Parent  2c94746eb01204a1c703d555f21ebec031ed74b7
util: fix sortdict.update() to call __setitem__() on PyPy (issue5639)

It appears that overriding __setitem__() doesn't work as documented on PyPy.
Let's patch it as before bd0fd3ff9916.

https://docs.python.org/2/library/collections.html#ordereddict-examples-and-recipes

The issue was ui.configitems() wasn't ordered correctly, so the pull command
was wrapped in different order.
Augie Fackler - Aug. 2, 2017, 3:01 p.m.
On Wed, Aug 02, 2017 at 11:22:25PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1501681879 -32400
> #      Wed Aug 02 22:51:19 2017 +0900
> # Branch stable
> # Node ID b05cb26a301c4495f518f7180a69389b839a1fed
> # Parent  2c94746eb01204a1c703d555f21ebec031ed74b7
> util: fix sortdict.update() to call __setitem__() on PyPy (issue5639)

queued, thanks

Patch

diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -16,6 +16,7 @@  import shlex
 import sys
 
 ispy3 = (sys.version_info[0] >= 3)
+ispypy = (r'__pypy__' in sys.builtin_module_names)
 
 if not ispy3:
     import cookielib
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -584,6 +584,14 @@  class sortdict(collections.OrderedDict):
             del self[key]
         super(sortdict, self).__setitem__(key, value)
 
+    if pycompat.ispypy:
+        # __setitem__() isn't called as of PyPy 5.8.0
+        def update(self, src):
+            if isinstance(src, dict):
+                src = src.iteritems()
+            for k, v in src:
+                self[k] = v
+
 @contextlib.contextmanager
 def acceptintervention(tr=None):
     """A context manager that closes the transaction on InterventionRequired