[PATCH 1 of 2] py3: conditionalize the raise statement

Martijn Pieters mj at zopatista.com
Fri Aug 12 11:58:02 EDT 2016


On 8 August 2016 at 20:05, Pulkit Goyal <7895pulkit at gmail.com> wrote:
> # HG changeset patch
> # User Pulkit Goyal <7895pulkit at gmail.com>
> # Date 1470680471 -19800
> #      Mon Aug 08 23:51:11 2016 +0530
> # Node ID 9a344ce563ce2221bdfc9031b8f249d9da2f08b0
> # Parent  37b6f0ec6241a62de90737409458cd622e2fac0d
> py3: conditionalize the raise statement
>
> raise E,V,T is not acceptable in Python 3, thats is conditionalized.
> Moreover this will result in syntax error so we have to use exec() to
> execute this. Related PEP- https://www.python.org/dev/peps/pep-3109/#id14
>
> Moreover this patch also contain an update to test-check-py3-compat.t
>
> diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
> --- a/mercurial/bundle2.py
> +++ b/mercurial/bundle2.py
> @@ -989,7 +989,10 @@
>              outdebug(ui, 'closing payload chunk')
>              # abort current part payload
>              yield _pack(_fpayloadsize, 0)
> -            raise exc_info[0], exc_info[1], exc_info[2]
> +            if sys.version_info[0] >= 3:
> +                raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
> +            else:
> +                exec("""raise exc_info[0], exc_info[1], exc_info[2]""")

There is no need for an exec() call here. In Python 2 you can raise a
*tuple*, where the tuple consists of (type, value, traceback).

In other words, in Python 2, this is enough:

    raise exc_info

In Python 3, you want to raise `exc_info[1]`, don't create another
instance here, you are wrapping the exception value inside another
exception. You don't need to re-attach the traceback either; that same
traceback is *already there*

You could produce a helper function that produces the right 'format'
in Python 2 or 3:

    if sys.version_info[0] >= 3:
        import operator
        exc = operator.itemgetter(1)
    else:
        exc = tuple

then use

    raise exc(exc_info)


>          # end of payload
>          outdebug(ui, 'closing payload chunk')
>          yield _pack(_fpayloadsize, 0)
> 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
> @@ -81,7 +81,7 @@
>    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/bundle2.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
> +  mercurial/bundle2.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 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)
> @@ -136,13 +136,13 @@
>    mercurial/patch.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
>    mercurial/pathutil.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
>    mercurial/peer.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
> -  mercurial/pure/mpatch.py: error importing module: <ImportError> cannot import name 'pycompat' (line *) (glob)
> +  mercurial/pure/mpatch.py: error importing module: <ImportError> cannot import name 'policy' (line *) (glob)
>    mercurial/pure/osutil.py: error importing module: <ImportError> cannot import name 'policy' (line *) (glob)
>    mercurial/pure/parsers.py: error importing module: <ImportError> No module named 'mercurial.pure.node' (line *) (glob)
>    mercurial/pushkey.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
>    mercurial/pvec.py: error importing: <TypeError> getattr(): attribute name must be string (error at pycompat.py:*) (glob)
>    mercurial/registrar.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> -  mercurial/repair.py: error importing module: <SyntaxError> invalid syntax (bundle2.py, line *) (line *) (glob)
> +  mercurial/repair.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
>    mercurial/repoview.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
>    mercurial/revlog.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
>    mercurial/revset.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
> @@ -169,6 +169,6 @@
>    mercurial/verify.py: error importing: <TypeError> attribute name must be string, not 'bytes' (error at mdiff.py:*) (glob)
>    mercurial/win32.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
>    mercurial/windows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
> -  mercurial/wireproto.py: error importing module: <SyntaxError> invalid syntax (bundle2.py, line *) (line *) (glob)
> +  mercurial/wireproto.py: error importing module: <TypeError> a bytes-like object is required, not 'str' (line *) (glob)
>
>  #endif
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel



-- 
Martijn Pieters


More information about the Mercurial-devel mailing list