[PATCH] py3: handle os.environ.get() case in module loader
Siddharth Agarwal
sid at less-broken.com
Thu Aug 4 23:26:54 EDT 2016
On 8/4/16 12:11, Pulkit Goyal wrote:
> # HG changeset patch
> # User Pulkit Goyal <7895pulkit at gmail.com>
> # Date 1470337846 -19800
> # Fri Aug 05 00:40:46 2016 +0530
> # Branch stable
> # Node ID 6bc900348ed8d695dddc9451f56e3adf38149127
> # Parent 44c45c5f2481e94b8eeb24b31fea4b49d3453835
> py3: handle os.environ.get() case in module loader
>
> The os.environ.get() doesnot accepts bytes on Python 3. Instead of adding u''
> in the source code, its preferred to add a case in the custom module loader
> which handles this.
I agree with Greg -- this makes things more complicated than necessary.
We should just have a helper (e.g. util.environ) that gets assigned to
os.environ on py2 and os.environb on py3. (And with possibly different
behavior on Windows, similar to filenames.)
- Siddharth
>
> Firstly the code rewrite the token to include u'' to undo the effect by the
> transformer on the first argument. Then it searches for more arguments if
> present and does the same for them.
>
> diff -r 44c45c5f2481 -r 6bc900348ed8 mercurial/__init__.py
> --- a/mercurial/__init__.py Thu Aug 04 00:32:19 2016 +0530
> +++ b/mercurial/__init__.py Fri Aug 05 00:40:46 2016 +0530
> @@ -272,6 +272,47 @@
> except IndexError:
> pass
>
> + # os.environ.get() doesnot accepts byte strings on Python 3.
> + # Rewrite the token to include the unicode literal prefix so
> + # the string transformer above doesn't add the byte prefix.
> + if (fn in ('get') and
> + prevtoken.type == token.OP and prevtoken.string == '.'
> + and tokens[i - 2].string == 'environ' and
> + tokens[i - 4].string == 'os'):
> + # (tokens[i-4:i-2], os.environ)
> + # (OP, '.')
> + # (NAME, 'get')
> + # (OP, '(')
> + # (STRING, 'HGENCODING')
> + # (OP, ')')
> + try:
> + st = tokens[i + 2]
> + if (st.type == token.STRING and
> + st.string[0] in ("'", '"')):
> + rt = tokenize.TokenInfo(st.type, 'u%s' % st.string,
> + st.start, st.end, st.line)
> + tokens[i + 2] = rt
> +
> + # This while loop deals with the further arguments in
> + # in os.environ.get(). It checks whether we have ')'
> + # as the next token or we have a ',' which indicates
> + # that we have more arguments. This loop terminates
> + # when we get the ')' token.
> + j = 3
> + while (tokens[i + j].string != ')' and
> + tokens[i + j].string == ','):
> + st = tokens[i + j + 1]
> + if (st.type == token.STRING and
> + st.string[0] in ("'", '"')):
> + rt = tokenize.TokenInfo(st.type, 'u%s' %
> + st.string, st.start,
> + st.end, st.line)
> + tokens[i + j + 1] = rt
> + j += 2
> +
> + except IndexError:
> + pass
> +
> # Emit unmodified token.
> yield t
>
> @@ -279,7 +320,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\x01'
> + BYTECODEHEADER = b'HG\x00\x02'
>
> class hgloader(importlib.machinery.SourceFileLoader):
> """Custom module loader that transforms source code.
> diff -r 44c45c5f2481 -r 6bc900348ed8 tests/test-check-py3-compat.t
> --- a/tests/test-check-py3-compat.t Thu Aug 04 00:32:19 2016 +0530
> +++ b/tests/test-check-py3-compat.t Fri Aug 05 00:40:46 2016 +0530
> @@ -15,90 +15,90 @@
> #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-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list