Home > database >  How can I avoid this Python catch-22 of version testing -vs- initial syntax checker
How can I avoid this Python catch-22 of version testing -vs- initial syntax checker

Time:09-03

I have a python script that requires Python 3.8 or better to support the walrus operator and other Python3 operations. I want to test the version and output a "nice" message if the minimum version is not detected, however, I am getting the following syntax checking error if I am on Python2 and the script will not run to give the "nice" message.

  File "./te_add_for_wcs.py", line 743
    if (cert_count := apiResponse.get("X-Total-Count","NO_COUNT")) == 'NO_COUNT':
                   ^
SyntaxError: invalid syntax

Is there a way to get around this, or am I out of luck when users of Python2 attempt to use my script and would need to figure out the error means wrong version?

Trying to keep this to just one script file, as I can think of ways use multiple scripts that call each other to take care of prerequisites.

CodePudding user response:

I appreciate all the "comment" answers!

@MattDMo answer is what I will need to do, as I have no interest a ton of extra work (as indicated by @chepner), because @Kraigolas is absolutely correct - version 2 should not be used by anyone in production, or only used in isolated environments.

Developers like myself should assume that people will be using version 3 of Python and I should be documenting it well that scripts will only support Python3 and have logic that detects the minimum version of Python3 that is required.

Thank you again!

CodePudding user response:

The problem is that := is a syntax error, raised before any portion of the script can execute. You could "hide" the use of := in a module that is imported conditionally, based on a version check.

if sys.version_info.major < 3 or sys.version_info.minor < 8:
    sys.exit("Script requires Python 3.8 or later")
else:
    import module.with_function_using_assignment_expression

Rather than an error, though, I would just hold off using := in the code, but adding a deprecation warning to the script to let users know that a future version of the script (with :=) will require Python 3.8 or later.

import warnings


# Or maybe DecprecationWarning; I'm not entirely clear on the
# distinction between the two.
warnings.warn("This script will require Python 3.8 or later in the near future",
              warnings.FutureWarning)


...

# TODO: use an assignment expression to define cert_count directly
# in the if condition.
cert_count = apiResponse.get("X-Total-Count", "NO_COUNT")
if cert_count == "NO_COUNT":
    ...

After a suitable waiting period, you can go ahead and use :=, and let the users accept the consequences of not upgrading to Python 3.8.

CodePudding user response:

While I understand wanting to keep this in one file, for completeness, here's an easy 2-file solution:

wrapper_main.py

import sys

if sys.version_info.major < 3: # replace with your exact version requirements
    print("Please upgrade to python3!")
    sys.exit(0)

import main
main.main()

main.py

def main():
    a := 1
    print("Entering main!")

Tested on python 2.7 that this runs and exits without syntax error.

  • Related