4 ms·
I had commented on something related to this a couple of weeks ago here: https://news.ycombinator.com/item?id=28930278 https://news.ycombinator.com/item?id=2893
by tyingq 5y ago
I had commented on something related to this a couple of weeks ago here: https://news.ycombinator.com/item?id=28930278 https://news.ycombinator.com/item?id=28930278
The top reply had a great suggestion. Putting this at the top of a python 3.6+ required script results in a reasonable error for those with older /usr/bin/python interpreters, instead of a generic syntax error stack trace.
#!/usr/bin/python
0_0 # Python >= 3.6 is required
- slightwinder 5y agoWhile this looks funny and smart, it's not really a good solution as it lacks well communicated documentation. Python has a proper way to check for version, which is backward-compatible till version 2.0, so around 20+ years. import sys if sys.version_info.major < 3: raise Exception('Need Python 3 or higher') EDIT: correction, sys.version_info.major is only there since Python 2.7. For older versions sys.version_info[0] should be used.
- tyingq 5y ago>so around 20+ years. Right, but if there's anything below that that would cause a syntax error, like an f-string, that Exception you created never happens. The end user just sees a syntax error. It's unfortunate there's not a better way to handle it, especially with so many people still having /usr/bin/python linked to a 2.x version.
- deleted 5y ago[deleted]
- maple3142 5y agoI think this is worse because once you have a python 3 only syntax in your script (such as f-string), python 2 will simply throw syntax error because it need to parse the file to execute. The original solution looks hacky, but it can actually inform user to use python 3.
- BiteCode_dev 5y agoWhy use a hack when you can do it cleanly and give a good error message to your user ? import sys if sys.version_info < (3, 6): print('This script requires python 3.6+) else: from module import main main() If you want all of it to be in one file, you can use a zipapp: https://docs.python.org/fr/3/library/zipapp.html https://docs.python.org/fr/3/library/zipapp.html If you don't want to make the zipapp manually, or want it to automatically extract everything on first run, use shiv: http://shiv.readthedocs.io http://shiv.readthedocs.io
- tyingq 5y agoThere's still lots of use cases for sharing a single file script where you would like people with Python2 as /usr/bin/python to get a reasonable error. Zipapps don't work well as gists, for example. Edit: Zipapps feel hacky to me. I get that not everyone would share that opinion.
- BiteCode_dev 5y agoA zipapp is not a hack, it's an official feature of the python stdlib (as shown in the parent comment), and is made for the specific use case of grouping several files into one module for ease of sharing. All of this works fine with python 2.7 as long as you put the rest of your code in your main() entry point, which you should do anyway. So an f-string would cause no problem. Also, "informative stack trace" is only informative to another dev, and an experienced one at that, given how many juniors I encounter that can't read a traceback. Indeed, you script users may not be devs, and for those, a traceback would be confusing. For this reason, a script should only output a traceback in dev mode, but in production, if the dev flag is not set (-X dev), you should never see a traceback. It's a good practice to suppress it with sys.excepthook, and log it into a file instead. Using a syntax error like you do for this purpose IS the big hack. Now I'm not against a hack. I can see the value of it for your own scripts, of things that you code quick and dirty style. After all, I don't always want to have a clean entry point and more than one file.
- tyingq 5y ago
- vortico 5y agoI usually put this at the top, so it raises a syntax error if using an old version. f"Python 3.6+ is required"