reloader uses "-m" instead of file if possible#1416
Merged
Conversation
Python replaces "-m module" with the path to the module file. But this causes the reloader to be called with the path instead of "-m". Calling Python with a file adds its directory to the path. Adding "werkzeug" to the path broke imports.
|
I don't remember if I ran into this problem when I was launching my app via an entrypoint as defined in setup.py... I do know I had problems with the |
This was referenced Jan 25, 2019
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Unfortunately, Python doesn't make the fact that it was run as
python -m moduleavailable, it replaces-m modulewith the path to the module insys.argv. However, Python also has different behavior forpython -m modulevspython file.py: running a file adds its directory tosys.path. When the reloader was run withpython -m werkzeug.serving, it would end up callingpython /path/to/werkzeug/serving.pyon reload, which added/path/to/werkzeugtosys.path. This caused import conflicts with module names in Werkzeug shadowing builtins.To determine if
-mwas used, I looked at__main__.__package__. For all the cases I could think of, it seems that if that's notNone, then it was run as-m, otherwise it was run as a file. If we're running as-m, then the module name can be reconstructed by appending the name of the file insys.argv[0]to__main__.__package__.This includes a workaround for Flask's workaround of the previous behavior. Flask currently replaces
sys.argv[0:0]with["-m", "flask"]. If Werkzeug sees"-m"as the first arg it assumes the command line is already correct. This can be removed once Flask depends on the next version of Werkzeug.I tested every combination I could think of on Python 3 and 2, Linux and Windows:
python app.pypython -m app__main__.py.python -m app.cli__main__.py.python -m werkzeug.servingpython -m flask runflask runpython2 -m /path/to/app(without ".py" extension, Python 2 only)Also removed a comment saying not to use relative imports in
werkzeug.serving(8b2b621), now that we reload with-mrelative imports would work correctly.Closes #461
Closes #531
Closes #593
Closes pallets/flask#2777