py3: stop normalizing 2nd argument of *attr() to unicode
authorGregory Szorc <gregory.szorc@gmail.com>
Sun, 06 Oct 2019 17:45:05 -0400
changeset 43103 c95b2f40db7c
parent 43102 829088e87032
child 43104 74802979dd9d
py3: stop normalizing 2nd argument of *attr() to unicode Now that we don't byteify strings, we can stop normalizing the 2nd string argument to getattr() and remove explicit overrides we were using in the code base. We no longer use some helper functions in the source transformer, so we remove those as well. Differential Revision: https://phab.mercurial-scm.org/D7012
mercurial/__init__.py
mercurial/keepalive.py
mercurial/policy.py
mercurial/pycompat.py
mercurial/testing/storage.py
mercurial/util.py
--- a/mercurial/__init__.py	Sun Oct 06 14:58:41 2019 -0400
+++ b/mercurial/__init__.py	Sun Oct 06 17:45:05 2019 -0400
@@ -110,65 +110,14 @@
             except IndexError:
                 return False
 
-        def _findargnofcall(n):
-            """Find arg n of a call expression (start at 0)
-
-            Returns index of the first token of that argument, or None if
-            there is not that many arguments.
-
-            Assumes that token[i + 1] is '('.
-
-            """
-            nested = 0
-            for j in range(i + 2, len(tokens)):
-                if _isop(j, ')', ']', '}'):
-                    # end of call, tuple, subscription or dict / set
-                    nested -= 1
-                    if nested < 0:
-                        return None
-                elif n == 0:
-                    # this is the starting position of arg
-                    return j
-                elif _isop(j, '(', '[', '{'):
-                    nested += 1
-                elif _isop(j, ',') and nested == 0:
-                    n -= 1
-
-            return None
-
-        def _ensureunicode(j):
-            """Make sure the token at j is a unicode string
-
-            This rewrites a string token to include the unicode literal prefix
-            so the string transformer won't add the byte prefix.
-
-            Ignores tokens that are not strings. Assumes bounds checking has
-            already been done.
-
-            """
-            st = tokens[j]
-            if st.type == token.STRING and st.string.startswith(("'", '"')):
-                tokens[j] = st._replace(string='u%s' % st.string)
-
         for i, t in enumerate(tokens):
             # This looks like a function call.
             if t.type == token.NAME and _isop(i + 1, '('):
                 fn = t.string
 
-                # *attr() builtins don't accept byte strings to 2nd argument.
-                if fn in (
-                    'getattr',
-                    'setattr',
-                    'hasattr',
-                    'safehasattr',
-                ) and not _isop(i - 1, '.'):
-                    arg1idx = _findargnofcall(1)
-                    if arg1idx is not None:
-                        _ensureunicode(arg1idx)
-
                 # It changes iteritems/values to items/values as they are not
                 # present in Python 3 world.
-                elif fn in ('iteritems', 'itervalues') and not (
+                if fn in ('iteritems', 'itervalues') and not (
                     tokens[i - 1].type == token.NAME
                     and tokens[i - 1].string == 'def'
                 ):
@@ -182,7 +131,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\x13'
+    BYTECODEHEADER = b'HG\x00\x14'
 
     class hgloader(importlib.machinery.SourceFileLoader):
         """Custom module loader that transforms source code.
--- a/mercurial/keepalive.py	Sun Oct 06 14:58:41 2019 -0400
+++ b/mercurial/keepalive.py	Sun Oct 06 17:45:05 2019 -0400
@@ -255,7 +255,7 @@
         # If not a persistent connection, don't try to reuse it. Look
         # for this using getattr() since vcr doesn't define this
         # attribute, and in that case always close the connection.
-        if getattr(r, r'will_close', True):
+        if getattr(r, 'will_close', True):
             self._cm.remove(h)
 
         if DEBUG:
--- a/mercurial/policy.py	Sun Oct 06 14:58:41 2019 -0400
+++ b/mercurial/policy.py	Sun Oct 06 17:45:05 2019 -0400
@@ -70,7 +70,7 @@
     except AttributeError:
         raise ImportError(r'cannot import name %s' % modname)
     # force import; fakelocals[modname] may be replaced with the real module
-    getattr(mod, r'__doc__', None)
+    getattr(mod, '__doc__', None)
     return fakelocals[modname]
 
 
@@ -94,7 +94,7 @@
 
 def _checkmod(pkgname, modname, mod):
     expected = _cextversions.get((pkgname, modname))
-    actual = getattr(mod, r'version', None)
+    actual = getattr(mod, 'version', None)
     if actual != expected:
         raise ImportError(
             r'cannot import module %s.%s '
--- a/mercurial/pycompat.py	Sun Oct 06 14:58:41 2019 -0400
+++ b/mercurial/pycompat.py	Sun Oct 06 17:45:05 2019 -0400
@@ -270,7 +270,7 @@
     def getdoc(obj):
         """Get docstring as bytes; may be None so gettext() won't confuse it
         with _('')"""
-        doc = getattr(obj, u'__doc__', None)
+        doc = getattr(obj, '__doc__', None)
         if doc is None:
             return doc
         return sysbytes(doc)
--- a/mercurial/testing/storage.py	Sun Oct 06 14:58:41 2019 -0400
+++ b/mercurial/testing/storage.py	Sun Oct 06 17:45:05 2019 -0400
@@ -24,7 +24,7 @@
 
 
 class basetestcase(unittest.TestCase):
-    if not getattr(unittest.TestCase, r'assertRaisesRegex', False):
+    if not getattr(unittest.TestCase, 'assertRaisesRegex', False):
         assertRaisesRegex = (  # camelcase-required
             unittest.TestCase.assertRaisesRegexp
         )
--- a/mercurial/util.py	Sun Oct 06 14:58:41 2019 -0400
+++ b/mercurial/util.py	Sun Oct 06 17:45:05 2019 -0400
@@ -623,7 +623,7 @@
     def _fillbuffer(self):
         res = super(observedbufferedinputpipe, self)._fillbuffer()
 
-        fn = getattr(self._input._observer, r'osread', None)
+        fn = getattr(self._input._observer, 'osread', None)
         if fn:
             fn(res, _chunksize)
 
@@ -634,7 +634,7 @@
     def read(self, size):
         res = super(observedbufferedinputpipe, self).read(size)
 
-        fn = getattr(self._input._observer, r'bufferedread', None)
+        fn = getattr(self._input._observer, 'bufferedread', None)
         if fn:
             fn(res, size)
 
@@ -643,7 +643,7 @@
     def readline(self, *args, **kwargs):
         res = super(observedbufferedinputpipe, self).readline(*args, **kwargs)
 
-        fn = getattr(self._input._observer, r'bufferedreadline', None)
+        fn = getattr(self._input._observer, 'bufferedreadline', None)
         if fn:
             fn(res)