D7012: py3: stop normalizing 2nd argument of *attr() to unicode

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Mon Oct 7 20:04:44 UTC 2019


indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  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.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D7012

AFFECTED FILES
  mercurial/__init__.py
  mercurial/keepalive.py
  mercurial/policy.py
  mercurial/pycompat.py
  mercurial/testing/storage.py
  mercurial/util.py

CHANGE DETAILS

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -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)
 
diff --git a/mercurial/testing/storage.py b/mercurial/testing/storage.py
--- a/mercurial/testing/storage.py
+++ b/mercurial/testing/storage.py
@@ -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
         )
diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -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)
diff --git a/mercurial/policy.py b/mercurial/policy.py
--- a/mercurial/policy.py
+++ b/mercurial/policy.py
@@ -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 '
diff --git a/mercurial/keepalive.py b/mercurial/keepalive.py
--- a/mercurial/keepalive.py
+++ b/mercurial/keepalive.py
@@ -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:
diff --git a/mercurial/__init__.py b/mercurial/__init__.py
--- a/mercurial/__init__.py
+++ b/mercurial/__init__.py
@@ -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.



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list