pythonpython-2.7python-typing

How to have a script exit if it's running a earlier version of the interpreter than required?


I want to require Python v3.6+ for my command-line script. I have a script named quit_on_27.py as follows:

import sys

if sys.version_info < (3, 6):
    sys.exit("Please use Python 3.6+")


def hello(name:str):
    print(f'Hello, {name}!')


if __name__ == '__main__':
    hello('Jon')

When I run this as a script using Python 2.7:

> python .\quit_on_27.py
  File ".\quit_on_27.py", line 7
    def hello(name:str):
                  ^
SyntaxError: invalid syntax

I also have the same SyntaxError when I use assert sys.version_info >= (3, 6) as mentioned in How do I check which version of Python is running my script? in place of my conditional above.

I'd like to use typing and f-strings and other features not available in Python 2.7, and I'd like to let users know to use a newer version of Python rather than just seeing a SyntaxError.

How do I get this script to exit gracefully and helpfully?

This is more specific than How can I have a python script safely exit itself? since I am asking why my conditional doesn't work as I intended based on the version of Python running the script.

Note: my script does run as intended in Python 3.6.


Solution

  • As I (and @Klaus D.) suggested, one way to handle situations like this where the syntax being used is incompatible with earlier versions of the interpeter, would be to put the code using the syntax into a different script and only import it if the version is equal to or higher than the minimum needed.

    That said, yet another way to do it is to "hide" the offending code in a string and only execute that string if the version check passes:

    Here's what I mean:

    import sys
    
    if sys.version_info < (3, 6):
        sys.exit("Please use Python 3.6+")
    
    exec("""
        def hello(name:str):
            print(f'Hello, {name}!')
    """)
    
    if __name__ == '__main__':
        hello('Jon')
    

    This latter method may not be compatible with other tools you may be using (like mypy) depending on how "smart" they are…