1454

How do I check which version of the Python interpreter is running my script?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
carrier
  • 32,209
  • 23
  • 76
  • 99
  • 5
    The current thread is about checking python version from a python program/script. In case you are looking to check the version of python interpreter installed on your machine from command line then please refer to the following post - [Which version of Python do I have installed?](https://stackoverflow.com/q/8917885/465053) – RBT Jul 20 '18 at 05:09
  • 11
    here is a fun way to separate python 3 and 2... `python_version = int(str(range(3))[-2])` – Chris_Rands Jun 20 '19 at 12:33
  • @RBT: for a one-line check from the command-line, see [my answer](https://stackoverflow.com/a/61992940/202229). – smci May 24 '20 at 22:01

27 Answers27

1667

This information is available in the sys.version string in the sys module:

>>> import sys

Human readable:

>>> print(sys.version)  # parentheses necessary in python 3.       
2.5.2 (r252:60911, Jul 31 2008, 17:28:52) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)]

For further processing, use sys.version_info or sys.hexversion:

>>> sys.version_info
(2, 5, 2, 'final', 0)
# or
>>> sys.hexversion
34014192

To ensure a script runs with a minimal version requirement of the Python interpreter add this to your code:

assert sys.version_info >= (2, 5)

This compares major and minor version information. Add micro (=0, 1, etc) and even releaselevel (='alpha','final', etc) to the tuple as you like. Note however, that it is almost always better to "duck" check if a certain feature is there, and if not, workaround (or bail out). Sometimes features go away in newer releases, being replaced by others.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
krawyoti
  • 19,695
  • 1
  • 23
  • 17
  • 46
    it's actually the syntax for print. not for checking the version. i use that in my python 2 and 3 scripts: `PY3 = sys.version_info[0] == 3` – gcb Jul 30 '15 at 08:47
  • 8
    PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 – xiaoweiz Jan 01 '16 at 05:02
  • 32
    You can also access some of the fields in `sys.version_info` as properties, so `PY3 = sys.version_info.major == 3` might be a little more appealing. – krs013 Dec 13 '16 at 16:34
  • 1
    Note: sys.hexversion is compared to 0x020502F0, see https://docs.python.org/2/library/sys.html#sys.hexversion – Yinon Ehrlich May 16 '18 at 07:59
  • 7
    @gcb your code snippet will break whenever Python 4 happens. You should do `if sys.version_info >= (3,)`. It's totally pythonic to compare different sized tuples and it'll do the right thing. – Boris Verkhovskiy Nov 02 '19 at 23:51
  • @Boris But Python code is not guaranteed to be forward compatible! Or did that change? – xuiqzy Oct 02 '20 at 13:05
  • 6
    If the python file is run with `-O` or `-OO`, the assert will be removed. So, it might be better to make a regular if check and exit the program if the condition is not fulfilled. – xuiqzy Oct 02 '20 at 13:08
  • You’re going to intentionally not make your code forwards compatible because you might have to remove a deprecated method in the future? Why would you add future work for a maintainer of your code when you could not do that? – Boris Verkhovskiy Oct 02 '20 at 13:18
  • 1
    @Boris It's all about what contract you're representing. Do you want to express "this is guaranteed not to work on versions < 3, and it may/should work on higher versions," or do you want to express "this is guaranteed to work on these specific version ranges"? Both are valid choices for different situations. Personally, as the hypothetical future maintainer, I would prefer the original author had written the version that breaks on Python 4, forcing me to analyze it and explicitly accept it, rather than slipping past quietly and hoping it keeps working. – GrandOpener Mar 04 '21 at 17:21
422

From the command line (note the capital 'V'):

python -V

This is documented in 'man python'.

From IPython console

!python -V
Ankit Agrawal
  • 616
  • 9
  • 20
jcolino
  • 4,605
  • 1
  • 12
  • 2
114

Use platform's python_version from the stdlib:

from platform import python_version
print(python_version())

# 3.9.2
Bill
  • 10,323
  • 10
  • 62
  • 85
99

I like sys.hexversion for stuff like this.

>>> import sys
>>> sys.hexversion
33883376
>>> '%x' % sys.hexversion
'20504f0'
>>> sys.hexversion < 0x02060000
True
wjandrea
  • 28,235
  • 9
  • 60
  • 81
brianz
  • 7,268
  • 4
  • 37
  • 44
  • 3
    @0xC0000022L Had you ever wondered how you would be able to compare the text from the tuple? How does 'final' compares to beta, rc, or whatever it could be there. Instead if you have a numeric value, you will always be able to specify an exact version. – sorin Jun 04 '13 at 10:52
  • 1
    @sorin: uhm, that doesn't exactly matter, does it? If I compare against `(2,6,4)` the `'final'` doesn't seem to affect the comparison and it isn't supposed to. Apparently no slicing is needed when I compare the "most significant" parts of the tuple. This seems to be how it's treated and that's what my question was about. I'm not saying this solution doesn't have its merit, I'm just wondering why it's the best - i.e. what I am missing. – 0xC0000022L Jun 04 '13 at 10:57
  • As long you do not endup comparing `(3,3,0,'rc1','0')` and `(3,3,0,'beta','0')` – sorin Jun 05 '13 at 09:51
  • 16
    The release level is defined to be one of 'alpha', 'beta', 'candidate', or 'final' which also happens to be compare correctly... – Fredrik Jul 22 '13 at 19:56
72

Your best bet is probably something like so:

>>> import sys
>>> sys.version_info
(2, 6, 4, 'final', 0)
>>> if not sys.version_info[:2] == (2, 6):
...    print "Error, I need python 2.6"
... else:
...    from my_module import twoPointSixCode
>>> 

Additionally, you can always wrap your imports in a simple try, which should catch syntax errors. And, to @Heikki's point, this code will be compatible with much older versions of python:

>>> try:
...     from my_module import twoPointSixCode
... except Exception: 
...     print "can't import, probably because your python is too old!"
>>>
Seth
  • 45,033
  • 10
  • 85
  • 120
  • 4
    Why a plain Exception and not an ImportError? :P – deadly Oct 15 '13 at 09:54
  • 5
    @deadly - ImportError won't catch SyntaxErrors, which will be thrown if you try to use a new syntax in an old python, such as trying to use the [shortcut conditional](https://mail.python.org/pipermail/python-dev/2005-September/056846.html) in pre-2.5. – Seth Oct 22 '13 at 05:24
  • 1
    `except Exception` is too broad. Wouldn't it be better to use specific exceptions which you expect? – user Feb 01 '16 at 17:14
  • 2
    @Fermiparadox - Being broad keeps the assumptions low. The `except Exception:` line by itself already assumes a modern (2.x+) python. Maybe some future python will rearrange exception names in some backward-incompatible way? (Probably not, but who knows what python will look like in 20 years when we all have oculus rift eyeball implants? Code lasts a long time.) – Seth Feb 01 '16 at 21:27
50

Put something like:

#!/usr/bin/env/python
import sys
if sys.version_info<(2,6,0):
  sys.stderr.write("You need python 2.6 or later to run this script\n")
  exit(1)

at the top of your script.

Note that depending on what else is in your script, older versions of python than the target may not be able to even load the script, so won't get far enough to report this error. As a workaround, you can run the above in a script that imports the script with the more modern code.

rjmunro
  • 27,203
  • 20
  • 110
  • 132
  • 7
    This is incorrect (or at least, incomplete) because the old interpreters will barf on newer language constructs such as `x if Pred() else y`. They will die during the "lexing" phase, and never have a chance to actually *execute* `exit(1)`. [Seth's answer](http://stackoverflow.com/questions/3016157/determing-python-version-at-runtime/3016171#3016171) is correct in encapsulating the new language features in other files. – Mark Rushakoff Jun 10 '10 at 16:20
  • 2
    @MarkRushakoff: your comment is confusing. Which aspect of this answer is wrong? The missing `else` branch or that a `<` is used for `version_info`? AFAIK Python pads missing values in tuples, and all of this should be valid before 2.6, no? So Seth's answer uses slicing (redundantly) while this one doesn't and that makes your comment even more confusing. – 0xC0000022L Jun 03 '13 at 16:19
  • 6
    I think what @MarkRushakoff is saying is that if you have this at the top of a file, and a new language feature elsewhere in the same file, the old version of python will die when loading the file, before it runs any of it, so the error won't be shown. Basically you have to put the above (or another check) at the top of a file, then import the code that requires a new version of python from separate files. – rjmunro Jun 03 '13 at 17:44
33

Here's a short commandline version which exits straight away (handy for scripts and automated execution):

python -c "print(__import__('sys').version)"

Or just the major, minor and micro:

python -c "print(__import__('sys').version_info[:1])" # (2,)
python -c "print(__import__('sys').version_info[:2])" # (2, 7)
python -c "print(__import__('sys').version_info[:3])" # (2, 7, 6)
Wolph
  • 78,177
  • 11
  • 137
  • 148
  • Nice, this solves my problem where I was getting the version number by capturing the output of `python2 --version` and `python3 --version` from PHP. While I would get the latter without problems via `passthru()`, the former would only print to screen but never be captured, even when redirected into a file... – Tox Sep 05 '19 at 18:17
  • 1
    @tox You can tell `print() ` to write to a file if that's more convenient. – Wolph Sep 05 '19 at 22:08
  • In my case that would be more of the same as I'm already redirecting the `passthru()` output to a file. Your solution does exactly what I need. :) – Tox Sep 06 '19 at 08:33
  • Thank you. Also in my case it was usefull to add assert to validate version with exit code `python -c "assert __import__('sys').version_info[:2] >= (3, 6)"` – Alex Kosh May 13 '21 at 12:44
14

With six module, you can do it by:

import six

if six.PY2:
  # this is python2.x
else:
  # six.PY3
  # this is python3.x
Dzhuang
  • 1,895
  • 1
  • 14
  • 15
8
import sys
sys.version.split(' ')[0]

sys.version gives you what you want, just pick the first number :)

fengshaun
  • 2,100
  • 1
  • 16
  • 25
5

Like Seth said, the main script could check sys.version_info (but note that that didn't appear until 2.0, so if you want to support older versions you would need to check another version property of the sys module).

But you still need to take care of not using any Python language features in the file that are not available in older Python versions. For example, this is allowed in Python 2.5 and later:

try:
    pass
except:
    pass
finally:
    pass

but won't work in older Python versions, because you could only have except OR finally match the try. So for compatibility with older Python versions you need to write:

try:
    try:
        pass
    except:
        pass
finally:
    pass
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
Heikki Toivonen
  • 30,964
  • 11
  • 42
  • 44
5

Several answers already suggest how to query the current python version. To check programmatically the version requirements, I'd make use of one of the following two methods:

# Method 1: (see krawyoti's answer)
import sys
assert(sys.version_info >= (2,6))

# Method 2: 
import platform
from distutils.version import StrictVersion 
assert(StrictVersion(platform.python_version()) >= "2.6")
normanius
  • 8,629
  • 7
  • 53
  • 83
3

Just for fun, the following is a way of doing it on CPython 1.0-3.7b2, Pypy, Jython and Micropython. This is more of a curiosity than a way of doing it in modern code. I wrote it as part of http://stromberg.dnsalias.org/~strombrg/pythons/ , which is a script for testing a snippet of code on many versions of python at once, so you can easily get a feel for what python features are compatible with what versions of python:

via_platform = 0
check_sys = 0
via_sys_version_info = 0
via_sys_version = 0
test_sys = 0
try:
    import platform
except (ImportError, NameError):
    # We have no platform module - try to get the info via the sys module
    check_sys = 1

if not check_sys:
    if hasattr(platform, "python_version"):
        via_platform = 1
    else:
        check_sys = 1

if check_sys:
    try:
        import sys
        test_sys = 1
    except (ImportError, NameError):
        # just let via_sys_version_info and via_sys_version remain False - we have no sys module
        pass

if test_sys:
    if hasattr(sys, "version_info"):
        via_sys_version_info = 1
    elif hasattr(sys, "version"):
        via_sys_version = 1
    else:
        # just let via_sys remain False
        pass

if via_platform:
    # This gives pretty good info, but is not available in older interpreters.  Also, micropython has a
    # platform module that does not really contain anything.
    print(platform.python_version())
elif via_sys_version_info:
    # This is compatible with some older interpreters, but does not give quite as much info.
    print("%s.%s.%s" % sys.version_info[:3])
elif via_sys_version:
    import string
    # This is compatible with some older interpreters, but does not give quite as much info.
    verbose_version = sys.version
    version_list = string.split(verbose_version)
    print(version_list[0])
else:
    print("unknown")
dstromberg
  • 6,954
  • 1
  • 26
  • 27
3

If you want to detect pre-Python 3 and don't want to import anything...

...you can (ab)use list comprehension scoping changes and do it in a single expression:

is_python_3_or_above = (lambda x: [x for x in [False]] and None or x)(True)
Community
  • 1
  • 1
user541686
  • 205,094
  • 128
  • 528
  • 886
3
from sys import version_info, api_version, version, hexversion

print(f"sys.version: {version}")
print(f"sys.api_version: {api_version}")
print(f"sys.version_info: {version_info}")
print(f"sys.hexversion: {hexversion}")

output

sys.version: 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)]
sys.api_version: 1013
sys.version_info: sys.version_info(major=3, minor=6, micro=5, releaselevel='final', serial=0)
sys.hexversion: 50726384
oetzi
  • 1,002
  • 10
  • 21
  • For Python 2.7, we must use `print("sys.version: {}".format(version))`. – Marco Jan 15 '20 at 14:13
  • @Marco, right. string formatting is done for v 3+ with keyword arguments. can be done as print('[{},{},{}]'.format(1,2,3)) for python 2.7 ref: https://stackoverflow.com/questions/517355/string-formatting-in-python – oetzi Apr 22 '20 at 18:19
3

This just returns 2.7, 3.6 or 3.9

import sys
current_version = ".".join(map(str, sys.version_info[0:2]))

which is what you usually you need...

freedev
  • 25,946
  • 8
  • 108
  • 125
2

The simplest way

Just type python in your terminal and you can see the version as like following

desktop:~$ python
Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
cjahangir
  • 1,773
  • 18
  • 27
  • 32
    *"The simplest way"* ...to do something different than what was asked for. – Luc Aug 06 '16 at 18:29
  • So make a system call within a script to see what the "default" is? It would help to show how you would embed this. – mckenzm Apr 22 '21 at 18:07
2

sys.version_info doesn't seem to return a tuple as of 3.7. Rather, it returns a special class, so all of the examples using tuples don't work, for me at least. Here's the output from a python console:

>>> import sys
>>> type(sys.version_info)
<class 'sys.version_info'>

I've found that using a combination of sys.version_info.major and sys.version_info.minor seems to suffice. For example,...

import sys
if sys.version_info.major > 3:
    print('Upgrade to Python 3')
    exit(1)

checks if you're running Python 3. You can even check for more specific versions with...

import sys
ver = sys.version_info
if ver.major > 2:
    if ver.major == 3 and ver.minor <= 4:
        print('Upgrade to Python 3.5')
        exit(1)

can check to see if you're running at least Python 3.5.

Parker E.
  • 80
  • 7
  • 1
    It's something like a subclass of `namedtuple` and comparing it with tuple definitely works. To get full equality you need a five-element typle: major, minor, micro, releaselevel (string) and serial. – Mikhail Edoshin Mar 28 '19 at 13:29
1

Check Python version: python -V or python --version or apt-cache policy python

you can also run whereis python to see how many versions are installed.

Shusen Yi
  • 779
  • 7
  • 6
  • 6
    Same answer was already posted. and, The question is not "How do I check what version of python I have installed?" but "How do I check version in my script". – Stanley Ko Apr 11 '18 at 02:32
1

To verify the Python version for commands on Windows, run the following commands in a command prompt and verify the output

c:\>python -V
Python 2.7.16

c:\>py -2 -V
Python 2.7.16

c:\>py -3 -V
Python 3.7.3

Also, To see the folder configuration for each Python version, run the following commands:

For Python 2,'py -2 -m site'
For Python 3,'py -3 -m site'
Aamir M Meman
  • 1,645
  • 14
  • 15
1

The even simpler simplest way:

In Spyder, start a new "IPython Console", then run any of your existing scripts.

Now the version can be seen in the first output printed in the console window:

"Python 3.7.3 (default, Apr 24 2019, 15:29:51)..."

enter image description here

S. Jessen
  • 89
  • 1
  • 3
1

if you want to check the python version for at least condition (e.g., python 3.9.0):

import platform
python_version_tuple = list(map(int, platform.python_version_tuple()))

if python_version_tuple >= [3, 9, 0]:
    # Running at least Python 3.9.0
else:
    # Running Python below 3.9.0
Madiyar
  • 779
  • 11
  • 7
1

From within python3:

from sys import version_info 
python_version = f"{version_info.major}.{version_info.minor}"
print(python_version)

Should return (or similar):

3.9

Olaf
  • 146
  • 1
  • 8
0

To check from the command-line, in one single command, but include major, minor, micro version, releaselevel and serial, then invoke the same Python interpreter (i.e. same path) as you're using for your script:

> path/to/your/python -c "import sys; print('{}.{}.{}-{}-{}'.format(*sys.version_info))"

3.7.6-final-0

Note: .format() instead of f-strings or '.'.join() allows you to use arbitrary formatting and separator chars, e.g. to make this a greppable one-word string. I put this inside a bash utility script that reports all important versions: python, numpy, pandas, sklearn, MacOS, xcode, clang, brew, conda, anaconda, gcc/g++ etc. Useful for logging, replicability, troubleshootingm bug-reporting etc.

smci
  • 32,567
  • 20
  • 113
  • 146
  • 1
    This answer would be appropriate for a different question, like the one [linked](https://stackoverflow.com/questions/8917885/which-version-of-python-do-i-have-installed) in the comments under the question. It is not appropriate for determining what Python version is executing a script from within that script, since there is no guarantee that the `python` command invokes that particular Python interpreter. – user2357112 Jun 07 '20 at 23:15
  • @user2357112supportsMonica: this answer is perfectly approprriate to the question as stated. The question as stated nowhere says "from inside the script". If it did, that would be different. Clearly this answer implies "invoke the same Python interpreter i.e. same path as you used for your script". But if you insist I have to edit that into the answer, I will. – smci Jun 08 '20 at 04:36
  • f-strings can also use arbitrary formatting. Also, I think beginners might very well use another python version in their ide than what is used when they type python in the command line and they might not be aware of this difference. – xuiqzy Oct 02 '20 at 13:17
0

all answers has great insights

another way is platform.python_version_tuple()

python3 -c “import platform; print(platform.python_version_tuple())”

(‘3’, ‘6’, ‘8’)
Ram Ghadiyaram
  • 28,239
  • 13
  • 95
  • 121
-1

If you are working on linux just give command python output will be like this

Python 2.4.3 (#1, Jun 11 2009, 14:09:37)

[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

A-Sharabiani
  • 17,750
  • 17
  • 113
  • 128
pkm
  • 2,683
  • 2
  • 29
  • 44
  • 6
    I want my python script to be able to obtain the version of python that is interpreting it. The correct answer has been accepted. – carrier Jul 16 '13 at 17:42
  • The does not help to get `Python` version within the script, also similar answer already posted before: https://stackoverflow.com/a/35294211/950762 – Akif Sep 11 '18 at 10:51
-1

For windows, Go to command prompt and type this command to get the python version:

python --version

Or

python -V
MD Mushfirat Mohaimin
  • 1,966
  • 3
  • 10
  • 22
shaila
  • 177
  • 2
  • 10
-3

A attempt using os.popen to read it in a variable:

import os
ver = os.popen('python -V').read().strip()
print(ver)
Wasif
  • 14,755
  • 3
  • 14
  • 34