py3: add pycompat.open and replace open() calls
open() requires mode argument as unicodes on Python 3. This patch introduces
pycompat.open() which is inserted to files using transformer and replaces
builtins.open() calls.
--- a/mercurial/__init__.py Fri Aug 05 13:56:10 2016 +0200
+++ b/mercurial/__init__.py Fri Mar 03 13:04:32 2017 +0530
@@ -280,7 +280,7 @@
continue
r, c = t.start
l = (b'; from mercurial.pycompat import '
- b'delattr, getattr, hasattr, setattr, xrange\n')
+ b'delattr, getattr, hasattr, setattr, xrange, open\n')
for u in tokenize.tokenize(io.BytesIO(l).readline):
if u.type in (tokenize.ENCODING, token.ENDMARKER):
continue
@@ -327,7 +327,7 @@
# ``replacetoken`` or any mechanism that changes semantics of module
# loading is changed. Otherwise cached bytecode may get loaded without
# the new transformation mechanisms applied.
- BYTECODEHEADER = b'HG\x00\x06'
+ BYTECODEHEADER = b'HG\x00\x07'
class hgloader(importlib.machinery.SourceFileLoader):
"""Custom module loader that transforms source code.
--- a/mercurial/pycompat.py Fri Aug 05 13:56:10 2016 +0200
+++ b/mercurial/pycompat.py Fri Mar 03 13:04:32 2017 +0530
@@ -96,6 +96,9 @@
setattr = _wrapattrfunc(builtins.setattr)
xrange = builtins.range
+ def open(name, mode='r', buffering=-1):
+ return builtins.open(name, sysstr(mode), buffering)
+
# getopt.getopt() on Python 3 deals with unicodes internally so we cannot
# pass bytes there. Passing unicodes will result in unicodes as return
# values which we need to convert again to bytes.