-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Do not add python executable to executable scripts when reloading #1242
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
This seems very prone to errors. What if the script isn't executable? I don't understand what Nix is doing, so I don't know how to evaluate this patch. Why is Nix doing something weird here? Why does Werkzeug need to work around that instead of the other way around? |
Thanks for the reply @davidism 😄
If a script is marked as executable; it should probably be executable.
I'm not sure who is wrong. I'm going to explain with an example of the flask binary; where reloading is currently broken in Nix. With nix, you might get something where the flask binary is like:
(an uguly bash script to set the PATH and other environment variables. This needs to happen early, so that the python interpreter is started in the correct environment) Then the entrypoint is moved to #!/nix/store/cwxxbpfz2i2j34f3sgmd6vdl6wv98c2s-python3-3.6.4/bin/python3.6m
# -*- coding: utf-8 -*-
import sys;import site;import functools;sys.argv[0] = '/nix/store/i51148l3f065w38p8idp0w5jil0d2kjc-python3.6-Flask-0.12.2/bin/flask';functools.reduce(lambda k, p: site.addsitedir(p, k), ['/nix/store/i51148l3f065w38p8idp0w5jil0d2kjc-python3.6-Flask-0.12.2/lib/python3.6/site-packages','/nix/store/fkfjrajxckwgrxbx9qbky7jh7mv75m6q-python3.6-itsdangerous-0.24/lib/python3.6/site-packages','/nix/store/l6dnj5nh4d6ifgssl9cwfw0vqqj09zrn-python3.6-setuptools-36.4.0/lib/python3.6/site-packages','/nix/store/nrm9sc7rg99bix45mclh96s8fa8yma61-python3.6-click-6.7/lib/python3.6/site-packages','/nix/store/c1qlbn8508pis7ml4rrprf2zzb45i288-python3.6-Werkzeug-0.12.2/lib/python3.6/site-packages','/nix/store/6ywdg5wcvk00n79rwzrb03lihglnrm0n-python3.6-Jinja2-2.9.6/lib/python3.6/site-packages','/nix/store/sfpi2nb3bkgy16sgivlj6156hg0963nw-python3.6-markupsafe-1.0/lib/python3.6/site-packages'], site._init_pathinfo());
import re
import sys
from flask.cli import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main()) Here, nix has added a line to change the This change is quite similar to the workaround that already exists on windows regarding the |
Sometimes, the file in `sys.argv[0]` may use an interpreter other than python. For example; NixOs replaces `sys.argv[0]` to a wrapper shell script which changes the environment variables before running the main entrypoint. Currently, the reloader assumes that all scripts need the python interpreter appended their command line. This patch changes that to check if the script is set as executable, and does not use the python command if it is.
81b0117
to
315b78c
Compare
Rebased and added changelog. When I tried to do |
Awesome! Thanks for rebasing that. |
This broke the reloader on Windows. The check you added returns |
Ended up separating the checks between |
This change screwed me up. If you are working with e.g. NTFS (mounted in Linux) you can set all files to be executable or none. Great deal, I know. However, now things blow up in my face. And a shebang is not a proper solution as you might have started the server with a certain interpreter and you don't expect it be run with what ever interpreter is referenced in the shebang (changing the source code every time you want a different interpreter isn't a proper solution either). |
A script marked as executable must have a corresponding If you are having issues because your Windows filesystem marks all files as executable in Docker or mounted in Linux, either add an interpreter comment, or use the If you are having issues with different interpreters on different machines, you can either ensure the correct interpreter is on the See #1482 and docker/docs#8609. |
@samdroid-apps due to the number of issues being raised, I'm going to need to revert this. There are many cases where this is causing more harm than good.
Since this change, I have been getting a constant stream of bug reports here and questions on Stack Overflow. We're going to need to rethink how Nix fits in here. |
I'm not familiar with Nix or the wrapper techniques it's using, but it might be enough for the |
Reverts #1242 In order to support NixOS wrappers, the reloader would call an executable script directly. This caused issues with Windows, Docker, and other common development environments, resulting in an "Exec format error". Revert that change until a better workaround can be found.
This is a workaround for a change in Werkzeug 0.15.x (see pallets/werkzeug#1242). The reloading server used by `make run-app` won't preserve the Python executable if the running Python script is executable; this is a problem if you want to use a specific version of Python (say if you are in a venv).
I'm currently studying how to fix this in NixOS: If the problem is intractable on the NixOS side, maybe we can special case NixOS in werkzeug. |
Sometimes, the file in
sys.argv[0]
may use an interpreterother than python. For example; NixOs replaces
sys.argv[0]
to awrapper shell script which changes the environment variables before
running the main entrypoint.
Currently, the reloader assumes that all scripts need the python
interpreter appended their command line. This patch changes that to
check if the script is set as executable, and does not use the
python command if it is.