Patchwork [2,of,2,V3] encoding: use unicode literals to appease Python 3

login
register
mail settings
Submitter Gregory Szorc
Date July 4, 2016, 6:44 p.m.
Message ID <d0a5fd1255a1c7d9f09b.1467657850@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/15743/
State Changes Requested
Headers show

Comments

Gregory Szorc - July 4, 2016, 6:44 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1467657692 25200
#      Mon Jul 04 11:41:32 2016 -0700
# Node ID d0a5fd1255a1c7d9f09bcdc3d054e095a2e9bba9
# Parent  99a1ac83fe44142a9793a93e55b41aa052954842
encoding: use unicode literals to appease Python 3

Various places in encoding.py related to encoding names and
environment variables were expecting unicode/str types, not
bytes. This was causing various imports in Python 3 to fail
with our new module loader.

Add some u'' prefixes to prevent these literals from getting
b'' prefixed by the loader so Python 3 imports don't fail
as fast.

The introduction of u'' on Python 2 could cause some implicit
conversions between str and unicode types using the ascii encoding.
However, values of HGENCODING, HGENCODINGMODE, and HGENCODINGAMBIGUOUS
*should* be ASCII. So I think this is safe. The alternative is
likely a helper function to access os.environ on Python 2 and
os.environb on Python 3 and returns bytes everywhere. This could
be done as a follow-up.
Augie Fackler - July 12, 2016, 4:38 p.m.
On Mon, Jul 04, 2016 at 11:44:10AM -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1467657692 25200
> #      Mon Jul 04 11:41:32 2016 -0700
> # Node ID d0a5fd1255a1c7d9f09bcdc3d054e095a2e9bba9
> # Parent  99a1ac83fe44142a9793a93e55b41aa052954842
> encoding: use unicode literals to appease Python 3

I think this series is regrettable, but required. I'm happy with it,
but would like someone else to review.

>
> Various places in encoding.py related to encoding names and
> environment variables were expecting unicode/str types, not
> bytes. This was causing various imports in Python 3 to fail
> with our new module loader.
>
> Add some u'' prefixes to prevent these literals from getting
> b'' prefixed by the loader so Python 3 imports don't fail
> as fast.
>
> The introduction of u'' on Python 2 could cause some implicit
> conversions between str and unicode types using the ascii encoding.
> However, values of HGENCODING, HGENCODINGMODE, and HGENCODINGAMBIGUOUS
> *should* be ASCII. So I think this is safe. The alternative is
> likely a helper function to access os.environ on Python 2 and
> os.environb on Python 3 and returns bytes everywhere. This could
> be done as a follow-up.
>
> diff --git a/mercurial/encoding.py b/mercurial/encoding.py
> --- a/mercurial/encoding.py
> +++ b/mercurial/encoding.py
> @@ -65,30 +65,30 @@ def _getpreferredencoding():
>      oldloc = locale.setlocale(locale.LC_CTYPE)
>      locale.setlocale(locale.LC_CTYPE, "")
>      result = locale.nl_langinfo(locale.CODESET)
>      locale.setlocale(locale.LC_CTYPE, oldloc)
>
>      return result
>
>  _encodingfixers = {
> -    '646': lambda: 'ascii',
> -    'ANSI_X3.4-1968': lambda: 'ascii',
> -    'mac-roman': _getpreferredencoding
> +    u'646': lambda: u'ascii',
> +    u'ANSI_X3.4-1968': lambda: u'ascii',
> +    u'mac-roman': _getpreferredencoding
>  }
>
>  try:
> -    encoding = os.environ.get("HGENCODING")
> +    encoding = os.environ.get(u'HGENCODING')
>      if not encoding:
> -        encoding = locale.getpreferredencoding() or 'ascii'
> +        encoding = locale.getpreferredencoding() or u'ascii'
>          encoding = _encodingfixers.get(encoding, lambda: encoding)()
>  except locale.Error:
> -    encoding = 'ascii'
> -encodingmode = os.environ.get("HGENCODINGMODE", "strict")
> -fallbackencoding = 'ISO-8859-1'
> +    encoding = u'ascii'
> +encodingmode = os.environ.get(u'HGENCODINGMODE', u'strict')
> +fallbackencoding = u'ISO-8859-1'
>
>  class localstr(str):
>      '''This class allows strings that are unmodified to be
>      round-tripped to the local encoding and back'''
>      def __new__(cls, u, l):
>          s = str.__new__(cls, l)
>          s._utf8 = u
>          return s
> @@ -175,18 +175,18 @@ def fromlocal(s):
>          return s.decode(encoding, encodingmode).encode("utf-8")
>      except UnicodeDecodeError as inst:
>          sub = s[max(0, inst.start - 10):inst.start + 10]
>          raise error.Abort("decoding near '%s': %s!" % (sub, inst))
>      except LookupError as k:
>          raise error.Abort(k, hint="please check your locale settings")
>
>  # How to treat ambiguous-width characters. Set to 'wide' to treat as wide.
> -wide = (os.environ.get("HGENCODINGAMBIGUOUS", "narrow") == "wide"
> -        and "WFA" or "WF")
> +wide = (os.environ.get(u'HGENCODINGAMBIGUOUS', u'narrow') == u'wide'
> +        and u'WFA' or u'WF')
>
>  def colwidth(s):
>      "Find the column width of a string for display in the local encoding"
>      return ucolwidth(s.decode(encoding, 'replace'))
>
>  def ucolwidth(d):
>      "Find the column width of a Unicode string for display"
>      eaw = getattr(unicodedata, 'east_asian_width', None)
> diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t
> --- a/tests/test-check-py3-compat.t
> +++ b/tests/test-check-py3-compat.t
> @@ -19,100 +19,100 @@
>    tests/md5sum.py not using absolute_import
>    tests/readlink.py not using absolute_import
>    tests/run-tests.py not using absolute_import
>    tests/test-demandimport.py not using absolute_import
>
>  #if py3exe
>    $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs $PYTHON3 contrib/check-py3-compat.py
>    doc/hgmanpage.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
> -  hgext/acl.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/automv.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/blackbox.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/bugzilla.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/censor.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/chgserver.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/children.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/churn.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/clonebundles.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> +  hgext/acl.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/automv.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/blackbox.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/bugzilla.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/censor.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/chgserver.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/children.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/churn.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/clonebundles.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    hgext/color.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
> -  hgext/convert/bzr.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/common.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/convcmd.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/cvs.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/cvsps.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/darcs.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/filemap.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/git.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/gnuarch.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/hg.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/monotone.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/p4.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/convert/subversion.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> +  hgext/convert/bzr.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/common.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/convcmd.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/cvs.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/cvsps.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/darcs.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/filemap.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/git.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/gnuarch.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/hg.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/monotone.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/p4.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/convert/subversion.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    hgext/convert/transport.py: error importing module: <ImportError> No module named 'svn.client' (line *) (glob)
> -  hgext/eol.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/extdiff.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/factotum.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/fetch.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/fsmonitor/state.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/fsmonitor/watchmanclient.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/gpg.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/graphlog.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/hgk.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/highlight/highlight.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/histedit.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/journal.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/keyword.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/basestore.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/lfcommands.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/lfutil.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/localstore.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/overrides.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/proto.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/remotestore.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/reposetup.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/storefactory.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/largefiles/uisetup.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> +  hgext/eol.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/extdiff.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/factotum.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/fetch.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/fsmonitor/state.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/fsmonitor/watchmanclient.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/gpg.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/graphlog.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/hgk.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/highlight/highlight.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/histedit.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/journal.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/keyword.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/basestore.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/lfcommands.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/lfutil.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/localstore.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/overrides.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/proto.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/remotestore.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/reposetup.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/storefactory.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/largefiles/uisetup.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    hgext/largefiles/wirestore.py: error importing module: <SystemError> Parent module 'hgext.largefiles' not loaded, cannot perform relative import (line *) (glob)
> -  hgext/mq.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/notify.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/pager.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/patchbomb.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/purge.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/rebase.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/record.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/relink.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/schemes.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/share.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/shelve.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/strip.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/transplant.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/win32mbcs.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  hgext/win32text.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> +  hgext/mq.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/notify.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/pager.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/patchbomb.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/purge.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/rebase.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/record.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/relink.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/schemes.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/share.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/shelve.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/strip.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/transplant.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/win32mbcs.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  hgext/win32text.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/archival.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
> -  mercurial/bookmarks.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/branchmap.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> +  mercurial/bookmarks.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/branchmap.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/bundle2.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
> -  mercurial/bundlerepo.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/byterange.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/changegroup.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/changelog.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/cmdutil.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> +  mercurial/bundlerepo.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/byterange.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/changegroup.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/changelog.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/cmdutil.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/commands.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
> -  mercurial/commandserver.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/config.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/context.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/copies.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/crecord.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/dagparser.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/dagutil.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/destutil.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/dirstate.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/discovery.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> -  mercurial/dispatch.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
> +  mercurial/commandserver.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/config.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/context.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/copies.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/crecord.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/dagparser.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/dagutil.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/destutil.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/dirstate.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/discovery.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> +  mercurial/dispatch.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/exchange.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/extensions.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/fancyopts.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/filelog.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/filemerge.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/fileset.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/formatter.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
>    mercurial/graphmod.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Yuya Nishihara - July 13, 2016, 12:33 p.m.
On Mon, 04 Jul 2016 11:44:10 -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1467657692 25200
> #      Mon Jul 04 11:41:32 2016 -0700
> # Node ID d0a5fd1255a1c7d9f09bcdc3d054e095a2e9bba9
> # Parent  99a1ac83fe44142a9793a93e55b41aa052954842
> encoding: use unicode literals to appease Python 3

>  try:
> -    encoding = os.environ.get("HGENCODING")
> +    encoding = os.environ.get(u'HGENCODING')
>      if not encoding:
> -        encoding = locale.getpreferredencoding() or 'ascii'
> +        encoding = locale.getpreferredencoding() or u'ascii'
>          encoding = _encodingfixers.get(encoding, lambda: encoding)()
>  except locale.Error:
> -    encoding = 'ascii'
> -encodingmode = os.environ.get("HGENCODINGMODE", "strict")
> -fallbackencoding = 'ISO-8859-1'
> +    encoding = u'ascii'
> +encodingmode = os.environ.get(u'HGENCODINGMODE', u'strict')
> +fallbackencoding = u'ISO-8859-1'

encoding.encoding should be str. Otherwise "hg debuginstall" would concatenate
unicode and str.

Mixing unicode and str in public API would be a source of unicode bugs
no developer would notice.

> -wide = (os.environ.get("HGENCODINGAMBIGUOUS", "narrow") == "wide"
> -        and "WFA" or "WF")
> +wide = (os.environ.get(u'HGENCODINGAMBIGUOUS', u'narrow') == u'wide'
> +        and u'WFA' or u'WF')

Comparison between str and unicode can emit UnicodeWarning: Unicode equal
comparison failed to convert both arguments to Unicode - interpreting them
as being unequal
Yuya Nishihara - July 13, 2016, 12:40 p.m.
On Tue, 12 Jul 2016 12:38:02 -0400, Augie Fackler wrote:
> On Mon, Jul 04, 2016 at 11:44:10AM -0700, Gregory Szorc wrote:
> > # HG changeset patch
> > # User Gregory Szorc <gregory.szorc@gmail.com>
> > # Date 1467657692 25200
> > #      Mon Jul 04 11:41:32 2016 -0700
> > # Node ID d0a5fd1255a1c7d9f09bcdc3d054e095a2e9bba9
> > # Parent  99a1ac83fe44142a9793a93e55b41aa052954842
> > encoding: use unicode literals to appease Python 3  
> 
> I think this series is regrettable, but required. I'm happy with it,
> but would like someone else to review.

The patch 1 seems fine, and great if we must avoid bulk rewriting to b''.
Gregory Szorc - July 14, 2016, 2:40 a.m.
On Wed, Jul 13, 2016 at 5:40 AM, Yuya Nishihara <yuya@tcha.org> wrote:

> On Tue, 12 Jul 2016 12:38:02 -0400, Augie Fackler wrote:
> > On Mon, Jul 04, 2016 at 11:44:10AM -0700, Gregory Szorc wrote:
> > > # HG changeset patch
> > > # User Gregory Szorc <gregory.szorc@gmail.com>
> > > # Date 1467657692 25200
> > > #      Mon Jul 04 11:41:32 2016 -0700
> > > # Node ID d0a5fd1255a1c7d9f09bcdc3d054e095a2e9bba9
> > > # Parent  99a1ac83fe44142a9793a93e55b41aa052954842
> > > encoding: use unicode literals to appease Python 3
> >
> > I think this series is regrettable, but required. I'm happy with it,
> > but would like someone else to review.
>
> The patch 1 seems fine, and great if we must avoid bulk rewriting to b''.
>

All I care about is getting patch 1 landed. I mainly only submitted the
other patches to demonstrate what things would look like with the source
rewriting in place.

Since you have valid issues with patch 2, please drop it and patch 3.

Patch

diff --git a/mercurial/encoding.py b/mercurial/encoding.py
--- a/mercurial/encoding.py
+++ b/mercurial/encoding.py
@@ -65,30 +65,30 @@  def _getpreferredencoding():
     oldloc = locale.setlocale(locale.LC_CTYPE)
     locale.setlocale(locale.LC_CTYPE, "")
     result = locale.nl_langinfo(locale.CODESET)
     locale.setlocale(locale.LC_CTYPE, oldloc)
 
     return result
 
 _encodingfixers = {
-    '646': lambda: 'ascii',
-    'ANSI_X3.4-1968': lambda: 'ascii',
-    'mac-roman': _getpreferredencoding
+    u'646': lambda: u'ascii',
+    u'ANSI_X3.4-1968': lambda: u'ascii',
+    u'mac-roman': _getpreferredencoding
 }
 
 try:
-    encoding = os.environ.get("HGENCODING")
+    encoding = os.environ.get(u'HGENCODING')
     if not encoding:
-        encoding = locale.getpreferredencoding() or 'ascii'
+        encoding = locale.getpreferredencoding() or u'ascii'
         encoding = _encodingfixers.get(encoding, lambda: encoding)()
 except locale.Error:
-    encoding = 'ascii'
-encodingmode = os.environ.get("HGENCODINGMODE", "strict")
-fallbackencoding = 'ISO-8859-1'
+    encoding = u'ascii'
+encodingmode = os.environ.get(u'HGENCODINGMODE', u'strict')
+fallbackencoding = u'ISO-8859-1'
 
 class localstr(str):
     '''This class allows strings that are unmodified to be
     round-tripped to the local encoding and back'''
     def __new__(cls, u, l):
         s = str.__new__(cls, l)
         s._utf8 = u
         return s
@@ -175,18 +175,18 @@  def fromlocal(s):
         return s.decode(encoding, encodingmode).encode("utf-8")
     except UnicodeDecodeError as inst:
         sub = s[max(0, inst.start - 10):inst.start + 10]
         raise error.Abort("decoding near '%s': %s!" % (sub, inst))
     except LookupError as k:
         raise error.Abort(k, hint="please check your locale settings")
 
 # How to treat ambiguous-width characters. Set to 'wide' to treat as wide.
-wide = (os.environ.get("HGENCODINGAMBIGUOUS", "narrow") == "wide"
-        and "WFA" or "WF")
+wide = (os.environ.get(u'HGENCODINGAMBIGUOUS', u'narrow') == u'wide'
+        and u'WFA' or u'WF')
 
 def colwidth(s):
     "Find the column width of a string for display in the local encoding"
     return ucolwidth(s.decode(encoding, 'replace'))
 
 def ucolwidth(d):
     "Find the column width of a Unicode string for display"
     eaw = getattr(unicodedata, 'east_asian_width', None)
diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t
--- a/tests/test-check-py3-compat.t
+++ b/tests/test-check-py3-compat.t
@@ -19,100 +19,100 @@ 
   tests/md5sum.py not using absolute_import
   tests/readlink.py not using absolute_import
   tests/run-tests.py not using absolute_import
   tests/test-demandimport.py not using absolute_import
 
 #if py3exe
   $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs $PYTHON3 contrib/check-py3-compat.py
   doc/hgmanpage.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
-  hgext/acl.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/automv.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/blackbox.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/bugzilla.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/censor.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/chgserver.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/children.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/churn.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/clonebundles.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
+  hgext/acl.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/automv.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/blackbox.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/bugzilla.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/censor.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/chgserver.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/children.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/churn.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/clonebundles.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   hgext/color.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
-  hgext/convert/bzr.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/common.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/convcmd.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/cvs.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/cvsps.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/darcs.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/filemap.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/git.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/gnuarch.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/hg.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/monotone.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/p4.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/convert/subversion.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
+  hgext/convert/bzr.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/common.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/convcmd.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/cvs.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/cvsps.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/darcs.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/filemap.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/git.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/gnuarch.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/hg.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/monotone.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/p4.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/convert/subversion.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   hgext/convert/transport.py: error importing module: <ImportError> No module named 'svn.client' (line *) (glob)
-  hgext/eol.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/extdiff.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/factotum.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/fetch.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/fsmonitor/state.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/fsmonitor/watchmanclient.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/gpg.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/graphlog.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/hgk.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/highlight/highlight.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/histedit.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/journal.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/keyword.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/basestore.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/lfcommands.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/lfutil.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/localstore.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/overrides.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/proto.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/remotestore.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/reposetup.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/storefactory.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/largefiles/uisetup.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
+  hgext/eol.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/extdiff.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/factotum.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/fetch.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/fsmonitor/state.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/fsmonitor/watchmanclient.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/gpg.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/graphlog.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/hgk.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/highlight/highlight.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/histedit.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/journal.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/keyword.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/basestore.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/lfcommands.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/lfutil.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/localstore.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/overrides.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/proto.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/remotestore.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/reposetup.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/storefactory.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/largefiles/uisetup.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   hgext/largefiles/wirestore.py: error importing module: <SystemError> Parent module 'hgext.largefiles' not loaded, cannot perform relative import (line *) (glob)
-  hgext/mq.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/notify.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/pager.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/patchbomb.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/purge.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/rebase.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/record.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/relink.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/schemes.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/share.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/shelve.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/strip.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/transplant.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/win32mbcs.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  hgext/win32text.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
+  hgext/mq.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/notify.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/pager.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/patchbomb.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/purge.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/rebase.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/record.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/relink.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/schemes.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/share.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/shelve.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/strip.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/transplant.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/win32mbcs.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  hgext/win32text.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/archival.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
-  mercurial/bookmarks.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/branchmap.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
+  mercurial/bookmarks.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/branchmap.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/bundle2.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
-  mercurial/bundlerepo.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/byterange.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/changegroup.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/changelog.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/cmdutil.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
+  mercurial/bundlerepo.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/byterange.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/changegroup.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/changelog.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/cmdutil.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/commands.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
-  mercurial/commandserver.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/config.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/context.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/copies.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/crecord.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/dagparser.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/dagutil.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/destutil.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/dirstate.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/discovery.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
-  mercurial/dispatch.py: error importing: <TypeError> str expected, not bytes (error at encoding.py:*) (glob)
+  mercurial/commandserver.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/config.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/context.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/copies.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/crecord.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/dagparser.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/dagutil.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/destutil.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/dirstate.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/discovery.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
+  mercurial/dispatch.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/exchange.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/extensions.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/fancyopts.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/filelog.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/filemerge.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/fileset.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/formatter.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)
   mercurial/graphmod.py: error importing: <TypeError> str expected, not bytes (error at i18n.py:*) (glob)