Can I assert the python version before the interpreter parses the code?
Asked Answered
A

2

5

I want to inform the user which python version they should use:

import sys
assert sys.version_info >= (3, 6), "Use Python 3.6 or newer"
print(f"a format string")

But instead, running the above file makes a syntax error:

$ python fstring.py. # default python is 2.7
  File "fstring.py", line 3
    print(f"a format string")
                           ^
SyntaxError: invalid syntax

Is it possible to do this per-file, without wrapping all the f-strings inside of try blocks?

Asci answered 19/9, 2020 at 14:4 Comment(2)
Note, you can't wrap the f-strings in try-blocks either. SyntaxErrors are raised when the code is being compiledSeverance
Start the script withf"If you see this in an error message, use Python 3.6 or newer"? :-P Wouldn't be pretty, but might serve the purpose.Zischke
C
6

No, this is not possible on a per-file basis, because parsing happens for the whole file before any of it is executed, and therefore before any assertions are checked. try also won't work, for the same reason.

The only way this could possibly work is if you defer the parsing of part of the code until runtime by putting the code in a string and calling eval, but... don't do that. You have two sensible options: don't use f-strings at all, or let it fail with a SyntaxError instead of your own custom error message.

Alternatively, if you are working on a Unix or Linux system then you can mark the file as executable and give it a shebang line at the start like #!/usr/bin/python3.8 so that the user doesn't need to know the right version to use themselves.

If you want to do this on a per-module basis instead, see @Chris's answer.

Claribel answered 19/9, 2020 at 14:11 Comment(4)
All the user wants to do is check/print the current running Python version - of course they can do that using sys.version_infoFlabby
@barny That is not at all what the question is about; I do not understand how you have read the question and reached that conclusion.Claribel
@barny but they can't do that and use f-strings in the same piece of source codeSeverance
So, wrapping this up, in case you have any f-strings in a Python script, you literally cannot explicitly tell user to use correct Python version unless change all f-strings to a format style. Right? If this is an option, you could just rename your file to .py3 extension. It's not an option for me, unfortunately.Duplicature
I
5

If you are writing a module, you can do this via your module's __init__.py, e.g. if you have something like

  • foo_module/
    • __init__.py
    • foo_module/
      • foo.py
    • setup.py

where __init__.py contains

import sys


assert sys.version_info >= (3, 6), "Use Python 3.6 or newer"

and foo.py contains

print(f"a format string")

Example:

Python 2.7.18 (default, Jun 23 2020, 19:04:42) 
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from foo_module import foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "foo_module/__init__.py", line 4, in <module>
    assert sys.version_info >= (3, 6), "Use Python 3.6 or newer"
AssertionError: Use Python 3.6 or newer
Isopropyl answered 19/9, 2020 at 14:17 Comment(3)
This works per-module, but the question says per-file.Claribel
@kaya3, true, I missed the words "per-file" in the question. Still, I'm going to leave this up as it could help other users looking for a solution for modules. Your answer is correct for the single file case.Isopropyl
This solves my problem, even though I asked a slightly different question. I'll accept the other answer but I upvoted this one.Asci

© 2022 - 2024 — McMap. All rights reserved.