( )⚙ D5025 py3: make test-contrib-perf.t work on python 3

This is an archive of the discontinued Mercurial Phabricator instance.

py3: make test-contrib-perf.t work on python 3
ClosedPublic

Authored by pulkit on Oct 12 2018, 9:58 PM.

Details

Diff Detail

Repository
rHG Mercurial
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

pulkit created this revision.Oct 12 2018, 9:58 PM
yuja added a subscriber: yuja.Oct 13 2018, 12:39 AM
  • a/contrib/perf.py

+++ b/contrib/perf.py
@@ -75,14 +75,16 @@

_byteskwargs = pycompat.byteskwargs  # since 4.1 (or fbc3f73dc802)
_sysstr = pycompat.sysstr         # since 4.0 (or 2219f4f82ede)
_xrange = pycompat.xrange         # since 4.8 (or 7eba8f83129b)

+ fsencode = pycompat.fsencode # since 3.9 (or f4a5e0e86a7e)

if pycompat.ispy3:
    _maxint = sys.maxsize  # per py3 docs for replacing maxint
else:
    _maxint = sys.maxint

except (ImportError, AttributeError):

import inspect
getargspec = inspect.getargspec
_byteskwargs = identity

+ fsencode = fsencode # no py3 support

Fixed invalid reference in flight.

def perfstartup(ui, repo, **opts):

opts = _byteskwargs(opts)
timer, fm = gettimer(ui, opts)
  • cmd = sys.argv[0]

+ cmd = fsencode(sys.argv[0])

Applying fsencode() on sys.argv is probably wrong on Windows, but it's perf.py,
I don't care.

This revision was automatically updated to reflect the committed changes.

def perfstartup(ui, repo, **opts):

opts = _byteskwargs(opts)
timer, fm = gettimer(ui, opts)
  • cmd = sys.argv[0]

+ cmd = fsencode(sys.argv[0])

Applying fsencode() on sys.argv is probably wrong on Windows, but it's perf.py,
I don't care.

What's the right way to do it on windows?

yuja added a comment.Oct 13 2018, 5:53 AM
>> - cmd = sys.argv[0] +    cmd = fsencode(sys.argv[0])
> 
> Applying fsencode() on sys.argv is probably wrong on Windows, but it's perf.py,
>  I don't care.
What's the right way to do it on windows?

I think encoding.strtolocal() is close, but I have no idea what's the best
way to get char *argv[] back from wchar_t *argv[].

In D5025#75556, @yuja wrote:

def perfstartup(ui, repo, **opts):

opts = _byteskwargs(opts)
timer, fm = gettimer(ui, opts)
  • cmd = sys.argv[0]

+ cmd = fsencode(sys.argv[0])

Applying fsencode() on sys.argv is probably wrong on Windows, but it's perf.py,
I don't care.

Sadly, it doesn't work on Windows. But since os.system() is called with an r-string, bytes wouldn't be right anyway. When I simply formatted in sys.argv[0], I got this:

--- c:/Users/Matt/projects/hg_py3/tests/test-contrib-perf.t
+++ c:/Users/Matt/projects/hg_py3/tests/test-contrib-perf.t.err
@@ -184,6 +184,7 @@
   $ hg perfrevrange
   $ hg perfrevset 'all()'
   $ hg perfstartup
+  (null): can't open file '<unprintable file name>': [Errno 2] $ENOENT$
   $ hg perfstatus
   $ hg perftags
   $ hg perftemplating

This will be good to figure out because there are ~400 other instances of this error, mostly around launching hooks. What I've found to work (both here and for the hooks) is to make sure that python3 is launched:

os.system(r"py -3 %s version -q > NUL" % sys.argv[0])

It's perfectly capable of running r'notepad', so this must be an hg.exe/python.exe issue. This probably gets messy (at least with the hooks) because *.py files are associated with python2, and python2 is in $PATH (but not python3- both of which are named python.exe). py -3 will also pay attention to the shbang line, all of which are coded to python2. The only other thing of note that I see is that wrapper.exe implements main() and not wmain(), but I can't believe that py3 is incapable of launching things built without Unicode support.

In D5025#75556, @yuja wrote:

def perfstartup(ui, repo, **opts):

opts = _byteskwargs(opts)
timer, fm = gettimer(ui, opts)
  • cmd = sys.argv[0]

+ cmd = fsencode(sys.argv[0])

Applying fsencode() on sys.argv is probably wrong on Windows, but it's perf.py,
I don't care.

Sadly, it doesn't work on Windows. But since os.system() is called with an r-string, bytes wouldn't be right anyway. When I simply formatted in sys.argv[0], I got this:

--- c:/Users/Matt/projects/hg_py3/tests/test-contrib-perf.t
+++ c:/Users/Matt/projects/hg_py3/tests/test-contrib-perf.t.err
@@ -184,6 +184,7 @@
   $ hg perfrevrange
   $ hg perfrevset 'all()'
   $ hg perfstartup
+  (null): can't open file '<unprintable file name>': [Errno 2] $ENOENT$
   $ hg perfstatus
   $ hg perftags
   $ hg perftemplating

This will be good to figure out because there are ~400 other instances of this error, mostly around launching hooks.

Nevermind. Looking closer at exewrapper.c, the signature of Py_Main() changed. Is there any reason not to convert that file to the usual TCHAR type, and #define UNICODE when building for py3?