--- a/.hgsigs Mon Apr 22 17:46:57 2019 +0100
+++ b/.hgsigs Tue Apr 23 15:49:17 2019 -0400
@@ -177,3 +177,4 @@
593718ff5844cad7a27ee3eb5adad89ac8550949 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlxCG6EQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YptD/9DG76IvubjzVsfX1UiQcV1mqWuSgz/idpeFCrc6Z1dyFB5UmbHKfAaZnrPBR7ly6bGD9+NZupB9A8QRxX92koiq0Hw2ywbwR5oWVrBaDiinIDLiTQTUCPnNMH0FSNrt4Kf9Gj4RqMufZvL+dR0pDYV0n6HP3aGOeTnowNhv0lUbw/Gx20YrcCU9uf3GbgRvMQiFNv9cTJAdQlH++98C8MVLfRU4ZxP11hI7sR8mp1q6ruJoozd0Cta67E6MyC/L2Rp3W89psvvY7DSTg9RwQwoS8I6U9iyQJ16Bb6UgZVV6jqQqOSxWUaPfKUhJLl2ENHH5f3rzoi3NH6jHuy5rq2v9XuvOpQ7LqSi1Ev0oq1xllZiyD4Zm69Z/Is0mxwqPskZGWR5Lh6Uq3Dh0zJW7O5M2m1IHdAYqffHpUr2NgEQVST4VDvO4fR2d7n6+ZNXYbZrpmQ1j4bpOZCEMqWXPfl4HY7a60hWa884mWxtVLGvhYycxnN8r1o5ouS0pAMAI6qEFFW1XFFN4eNDDWl83BkuDa32DTEthoyi15JM5jS7VPDYACdHE3IVqsTsZq7nn60uoFCGpdMcSqrD2mlUd9Z12x8NnCIrxKhlHLkq89OrQAcz8/0bbluGuzm3FHKb+8VQWr0MgkvOLTqqvOqn97oBdKqo0eyT0IPz8QeVYPbZfQ==
83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlxUk3gQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91aT7EACaycWeal53ShxaNyTNOa5IPZ71+iyWA9xEh7hK6cDDirpItarWLRVWoWqBlWRBBs6uU4BxnpPSCLFkJLu6ts/5p4R6/0Z04Pasd6sFi14bCGslmPJFlwrpfFDpQvFR6xZAtv1xGb8n+rjpK+wfstjRgyf84zn4//0dOdylY5EUXOk4/3zcXKAzPgZHBRper+PlQ0ICgYHiKQUlyDWrFrdSEis6OqBa+PbxdmgzLYbhXi0bvS5XRWM9EVJZa+5ITEVOEGPClRcoA7SJE5DiapMYlwNnB3U6TEazJoj5yuvGhrJzj9lx7/jx9tzZ/mhdOVsSRiSCBu46B/E63fnUDqaMw8KKlFKBRuzKnqnByZD8fuD34YJ6A82hta56W4SJ4pusa/X2nAJn1QbRjESY4wN4FEaNdYiMbpgbG2uBDhmEowAyhXtiuQAPCUra5o42a+E+tAgV5uNUAal8vk0DcPRmzc4UntQiQGwxL0fsTEpMQtG5ryxWRmOIBq6aKGuLVELllPCwOh8UIGLlpAoEynlNi9qJNT6kHpSmwquiU6TG6R1dA/ckBK2H90hewtb/jwLlenGugpylLQ2U/NsDdoWRyHNrdB4eUJiWD/BBPXktZQJVja97Js+Vn44ctCkNjui/53xcBQfIYdHGLttIEq56v/yZiSviCcTUhBPRSEdoUg==
4ea21df312ec7159c5b3633096b6ecf68750b0dd 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlyQ7VYQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91aziD/4uI/Nr+UJgOri1zfa6ObXuMVO2FeadAolKemMDE/c4ddPUN2AwysZyJaOHmqj5VR0nf4a9CpTBc8Ciq9tfaFSWN6XFIJ2s3GPHhsnyhsPbF56c2bpl2W/csxor9eDGpv9TrQOK0qgI4wGxSQVFW0uUgHtZ5Yd6JWupHuyDfWopJf3oonissKI9ykRLeZEQ3sPIP6vTWMM3pdavAmDii3qKVEaCEGWmXgnM/vfBJ/tA1U5LSXpxwkJB7Pi/6Xc6OnGHWmCpsA4L6TSRkoyho4a6tLUA1Qlqm6sMxJjXAer8dmDLpmXL7gF3JhZgkiX74i2zDZnM4i42E6EhO52l3uorF5gtsw85dY20MSoBOmn5bM7k40TCA+vriNZJgmDrTYgY3B00mNysioEuSpDkILPJIV4U9LTazsxR49h3/mH2D1Sdxu6YtCIPE8ggThmveW/dZQy6W1xLfS66pFmDvq8ND0WjDa/Fi9dmjMcQtzA9CZL8AMlSc2aLJs++KjCuN+t6tn/tLhLz1nHaSitqgsIoJmBWb00QjOilnAQq7H8gUpUqMdLyEeL2B9HfJobQx6A8Op2xohjI7qD5gLGAxh+QMmuUmf7wx1h2UuQvrNW5di7S3k3nxfhm87Gkth3j0M/aMy0P6irPOKcKns55r6eOzItC+ezQayXc4A10F+x6Ew==
+4a8d9ed864754837a185a642170cde24392f9abf 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAly3aLkQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91bpXD/0Qdx3lNv6230rl369PnGM7o56BFywJtGtQ0FjBj81/Q6IKNJkAus/FXA02MevAxnKhyCMPHbiWQn4cn+Fpt9Y7FOFl3MTdoY5v4rGDAbAaJsjyK3BNqSwWD1uFaOnFDzA/112MJ6nDciVaOzeD7qakMj8zdVhvyEfFszN7f7xT1JyGc+cOWfbvcIv/IXWZNrSZC0EzcZspfwxYQwFscgDL3AHeKeYqihJ6vgWxgEg4V8ZnJ6roJeERTp2wwvIj/pKSEpgzfLQfHiEwvH9MKMaJHGx4huzWJxYX2DB83LaK7cgkKqzyQ+z8rsb27oFPMVgb1Kg78+6sRujFdkahFWYYGPT6sFBDWkRQ/J7DRnBzHH2wbBoyNkApmLEfaRGJpxX8wojPFGJkNr6GF12uF7E+djsuE8ZL7l4p2YD33NBSzcEjNTlgruRauj/7SoSC3BgDlrqCypCkNgn5nDDjvf6oJx16qGqZsglHJOl0S2LRiGaMQTpBhpDWAyVIAQBRW/vF1IRnNJaQ+dX7M9VqlVsXnfh8WD+FPKDgpiSLO8hIuvlYlcrtU9rXyWu1njKvCs744G836k4SNBoi+y6bi6XbmU0Uv0GSCLyj1BIsqglfXuac0QHlz5RNmS6LVf7z13ZIn/ePXehYoKHu+PNDmbVGGwAVoZP4HLEqonD3SVpVcQ==
--- a/.hgtags Mon Apr 22 17:46:57 2019 +0100
+++ b/.hgtags Tue Apr 23 15:49:17 2019 -0400
@@ -190,3 +190,4 @@
593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0
83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9
4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1
+4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0
--- a/mercurial/branchmap.py Mon Apr 22 17:46:57 2019 +0100
+++ b/mercurial/branchmap.py Tue Apr 23 15:49:17 2019 -0400
@@ -341,7 +341,7 @@
cachekey.append(hex(self.filteredhash))
f.write(" ".join(cachekey) + '\n')
nodecount = 0
- for label, nodes in sorted(self.iteritems()):
+ for label, nodes in sorted(self._entries.iteritems()):
label = encoding.fromlocal(label)
for node in nodes:
nodecount += 1
--- a/setup.py Mon Apr 22 17:46:57 2019 +0100
+++ b/setup.py Tue Apr 23 15:49:17 2019 -0400
@@ -85,10 +85,21 @@
if badpython:
error = """
-Mercurial only supports Python 2.7.
Python {py} detected.
-Please re-run with Python 2.7.
-""".format(py=sys.version_info)
+
+Mercurial currently has beta support for Python 3 and use of Python 2.7 is
+recommended for the best experience.
+
+Please re-run with Python 2.7 for a faster, less buggy experience.
+
+If you would like to beta test Mercurial with Python 3, this error can
+be suppressed by defining the HGPYTHON3 environment variable when invoking
+this command. No special environment variables or configuration changes are
+necessary to run `hg` with Python 3.
+
+See https://www.mercurial-scm.org/wiki/Python3 for more on Mercurial's
+Python 3 support.
+""".format(py='.'.join('%d' % x for x in sys.version_info[0:2]))
printf(error, file=sys.stderr)
sys.exit(1)
@@ -795,8 +806,8 @@
normalizecrlf('doc/%s.html' % root)
# This logic is duplicated in doc/Makefile.
- sources = {f for f in os.listdir('mercurial/help')
- if re.search(r'[0-9]\.txt$', f)}
+ sources = set(f for f in os.listdir('mercurial/help')
+ if re.search(r'[0-9]\.txt$', f))
# common.txt is a one-off.
gentxt('common')
@@ -937,6 +948,83 @@
with open(outfile, 'wb') as fp:
fp.write(data)
+# virtualenv installs custom distutils/__init__.py and
+# distutils/distutils.cfg files which essentially proxy back to the
+# "real" distutils in the main Python install. The presence of this
+# directory causes py2exe to pick up the "hacked" distutils package
+# from the virtualenv and "import distutils" will fail from the py2exe
+# build because the "real" distutils files can't be located.
+#
+# We work around this by monkeypatching the py2exe code finding Python
+# modules to replace the found virtualenv distutils modules with the
+# original versions via filesystem scanning. This is a bit hacky. But
+# it allows us to use virtualenvs for py2exe packaging, which is more
+# deterministic and reproducible.
+#
+# It's worth noting that the common StackOverflow suggestions for this
+# problem involve copying the original distutils files into the
+# virtualenv or into the staging directory after setup() is invoked.
+# The former is very brittle and can easily break setup(). Our hacking
+# of the found modules routine has a similar result as copying the files
+# manually. But it makes fewer assumptions about how py2exe works and
+# is less brittle.
+
+# This only catches virtualenvs made with virtualenv (as opposed to
+# venv, which is likely what Python 3 uses).
+py2exehacked = py2exeloaded and getattr(sys, 'real_prefix', None) is not None
+
+if py2exehacked:
+ from distutils.command.py2exe import py2exe as buildpy2exe
+ from py2exe.mf import Module as py2exemodule
+
+ class hgbuildpy2exe(buildpy2exe):
+ def find_needed_modules(self, mf, files, modules):
+ res = buildpy2exe.find_needed_modules(self, mf, files, modules)
+
+ # Replace virtualenv's distutils modules with the real ones.
+ modules = {}
+ for k, v in res.modules.items():
+ if k != 'distutils' and not k.startswith('distutils.'):
+ modules[k] = v
+
+ res.modules = modules
+
+ import opcode
+ distutilsreal = os.path.join(os.path.dirname(opcode.__file__),
+ 'distutils')
+
+ for root, dirs, files in os.walk(distutilsreal):
+ for f in sorted(files):
+ if not f.endswith('.py'):
+ continue
+
+ full = os.path.join(root, f)
+
+ parents = ['distutils']
+
+ if root != distutilsreal:
+ rel = os.path.relpath(root, distutilsreal)
+ parents.extend(p for p in rel.split(os.sep))
+
+ modname = '%s.%s' % ('.'.join(parents), f[:-3])
+
+ if modname.startswith('distutils.tests.'):
+ continue
+
+ if modname.endswith('.__init__'):
+ modname = modname[:-len('.__init__')]
+ path = os.path.dirname(full)
+ else:
+ path = None
+
+ res.modules[modname] = py2exemodule(modname, full,
+ path=path)
+
+ if 'distutils' not in res.modules:
+ raise SystemExit('could not find distutils modules')
+
+ return res
+
cmdclass = {'build': hgbuild,
'build_doc': hgbuilddoc,
'build_mo': hgbuildmo,
@@ -950,6 +1038,9 @@
'build_hgexe': buildhgexe,
}
+if py2exehacked:
+ cmdclass['py2exe'] = hgbuildpy2exe
+
packages = ['mercurial',
'mercurial.cext',
'mercurial.cffi',