-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Allow Python 3 (second try) #5967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
em++
Outdated
| if __name__ == '__main__': | ||
| sys.exit(subprocess.call(['python2', os.path.join(os.path.dirname(os.path.realpath(__file__)), 'emcc.py')] + sys.argv[1:])) | ||
| emcc = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'emcc') | ||
| if __name__ == '__main__' and not force_python_version.run(emcc): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line reads unclearly to me. It seems odd that the check for __main__ is related to a check for the python version, and also it's a little surprising that force_python_version returns a result saying whether it ran the command or not.
Could force_python_version call sys.exit to quit, if it ran the command? Then we could just call it inside an if on __main__ as a command, not a condition, that might be clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Otherwise I think this PR is good!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could
force_python_versioncallsys.exitto quit, if it ran the command?
Actually it already does, and I just updated force_python_version to also automate import emcc; emcc.run().
|
|
|
Turns out that |
kripken
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work here!
One more comment, we should measure that these changes don't affect build times. It seems like it shouldn't - same amount of imports/subprocess invocations - but still. Seeing how fast libc or zlib are build, for example.
tests/test_other.py
Outdated
| if has: | ||
| print(' checking emcc...') | ||
| check_execute([python, EMCC, '--version']) | ||
| check_execute([python, EMCC[:-3], '--version']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't it work with or without .py? Maybe I don't remember why the test checks the .py version later...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it works with or without it. I did this because the test specifically wants to test emcc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be a def remove_py_suffix() function or similar that looks for .py at the end and removes that? This could be a bit brittle otherwise for future refactors in mind, if one unconditionally just removes three last chars here?
tools/force_python_version.py
Outdated
| import subprocess | ||
| return subprocess.run(py2 + [os.path.realpath(filename) + '.py'] + sys.argv[1:]).returncode | ||
|
|
||
| def allowed_version(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about is_allowed_version, since this checks it, and doesn't return the allowed version?
| @@ -0,0 +1,43 @@ | |||
| ''' | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about calling this just python_version, or python_version_handling or something like that, since it also provides utilities to check it etc.?
| EMCC = path_from_root('emcc') | ||
| EMXX = path_from_root('em++') | ||
| EMAR = path_from_root('emar') | ||
| EMCC = path_from_root('emcc.py') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why, and why these three (and not emranlib just below etc.)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Calling emcc recursively will cause multiple duplicated Python version warnings
- There are many tests that call
[PYTHON, EMCC]and expect emptystderroutput. A Python version warning will break all of them.
The version warning occurs only on emcc wrapper so this change will remove the problems.
emranlib is just a no-op, em-config already allows Python 3, so no need to change. (Do we want it to require Python 2?)
| if env.get(dangerous) and env.get(dangerous) == non_native.get(dangerous): | ||
| del env[dangerous] # better to delete it than leave it, as the non-native one is definitely wrong | ||
| return env | ||
| env['CC'] = quote(EMCC) if not WINDOWS else 'python %s' % quote(EMCC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Calling
emccinternally will cause multiple duplicated Python version warnings - I think they are anyway equivalent, is there a specific need to do this conditionally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, hopefully we don't need the conditional stuff. @juj, was it working around a windows issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's safe to do this, as we should be calling [PYTHON, EMCC] anyhow everywhere, including windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Windows it's not possible to invoke /path/to/emscripten/emcc when emcc is a python script. (there's no concept of reading a shebang from the file on Windows), but one always needs to do python /path/to/emscripten/emcc to run the Python script.
That's why we have the emcc.bat file on Windows. If one invokes the subprocess with "shell expansion" enabled, then /path/to/emscripten/emcc works, and looks up /path/to/emscripten/emcc.bat. However shell expansion is sometimes considered poor form in subprocess invocations, which is why we'd prefer to disable shell expansion when invoking, and explicitly call the batch file /path/to/emscripten/emcc.bat.
To summarize, on Windows
subprocess.run(['c:/emscripten/emcc`]) # Fails, emcc is a py script, can't execute
subprocess.run(['c:/emscripten/emcc.py`]) # Fails, emcc.py is a py script, can't execute
subprocess.run(['c:/emscripten/emcc.py`], shell=True) # Fails, emcc.py is a py script, can't execute
subprocess.run(['c:/emscripten/emcc`], shell=True) # Works, and invokes emcc.bat
subprocess.run(['c:/emscripten/emcc.bat`], shell=True) # Works, and invokes emcc.bat
subprocess.run(['c:/emscripten/emcc.bat`]) # Works, and invokes emcc.bat, preferred
subprocess.run(['python', 'c:/emscripten/emcc`]) # Works, and invokes emcc python script, slightly more preferred compared to the .bat script to avoid py -> batch -> py roundtripping
subprocess.run(['python', 'c:/emscripten/emcc.py`]) # Works, and invokes emcc.py script, slightly more preferred compared to the .bat script to avoid py -> batch -> py roundtrippingWe prefer to avoid shell=True whenever possible, since it expands PATHs, %s and possibly $s depending on the calling terminal (PowerShell, MinGW, CygWin, MSYS). Since we're already being explicit with the path where emcc executable resides, it's nicer to explicitly say "emcc.bat is here on this absolute path, call this one", or "run this py script on python".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for great explanation! Yes, we need to explicitly call python on Windows, by is there a specific need to do this conditionally I meant that we can also do same thing on non-Windows: env['CC'] = 'python %s' % quote(EMCC)
I should have been clearer, sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right, I see now I kind of was explaining a separate issue. Yeah, the original adjustment was about bff4d2b, and I agree that it should also work on non-Windows, so this change is good.
|
I tried renaming |
|
I prefer the new names ( |
|
I like |
|
This PR looks good to merge to me now, any remaining concerns? Were there still any random test failures? |
|
I'm not seeing any random failures now, I think it's safe to merge. |
|
@saschanaz , great work here and in all the PRs with Python3 support leading to here :) |
|
Thanks for the great work! But this broke some of my builds :/ (I just updated to 1.37.36). The problem is this part of get_building_env: This used to just point to |
|
Thanks @cpitclaudel for the bug report. Can you please open a new issue for that, with a testcase showing the failure? (would be very helpful if you can extract the relevant part of the Z3 configure script for that, then we can use it in testing) |
|
Sure, with pleasure :) #6378 |
Replaces #5955
This PR:
EMSCRIPTEN_ALLOW_NEWER_PYTHONto allow Python 3force_python_version.pyto conditionally force Python 2colored_logger.pyemcc.pyinstead ofemccinternally