# HG changeset patch # User Gregory Szorc # Date 1570398305 14400 # Node ID c95b2f40db7c67c91bca88bea545ed5564e0b295 # Parent 829088e870325ba69cac94e02fa198d08d837e6b 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 diff -r 829088e87032 -r c95b2f40db7c mercurial/__init__.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. diff -r 829088e87032 -r c95b2f40db7c mercurial/keepalive.py --- 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: diff -r 829088e87032 -r c95b2f40db7c mercurial/policy.py --- 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 ' diff -r 829088e87032 -r c95b2f40db7c mercurial/pycompat.py --- 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) diff -r 829088e87032 -r c95b2f40db7c mercurial/testing/storage.py --- 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 ) diff -r 829088e87032 -r c95b2f40db7c mercurial/util.py --- 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)