Scripts that support several Python versions or platforms need reliable feature checks.
sys tells you about the interpreter that is running your code:
sys.version_infois a named tuple like(3, 13, 1, 'final', 0). Compare it as a tuple:sys.version_info >= (3, 11). Don't parse the human-readablesys.versionstring.sys.platformidentifies the OS:'linux','darwin'(macOS),'win32'(all Windows, even 64-bit). Check withsys.platform.startswith("linux")for safety.sys.executableis the absolute path of the Python binary. Use it to run child Python processes so they use the same interpreter and virtual environment:subprocess.run([sys.executable, "-m", "pip", "list"]).sys.implementation.nameis'cpython','pypy'and so on.sys.maxsizeis the largest container index (2**63 - 1on 64-bit builds); Python ints themselves are unbounded.sys.byteorderis'little'or'big'.
Type checkers such as mypy and pyright understand sys.version_info and sys.platform comparisons and skip branches that don't apply, so those checks are preferable to try/except ImportError tricks for typing.
Python 3.13 introduced an optional free-threaded build without the GIL; sys._is_gil_enabled() reports whether the GIL is active at runtime.
Example
import sys
print(sys.version_info >= (3, 8)) # True
major, minor = sys.version_info[:2]
print(type(major).__name__) # int
print(sys.platform in {"linux", "darwin", "win32"}) # True
print(sys.implementation.name) # cpython
print(sys.maxsize == 2**63 - 1) # True
if sys.version_info >= (3, 11):
import tomllib # stdlib since 3.11
else:
import tomli as tomllib # third-party backport
print(tomllib.loads('x = 1')) # {'x': 1}Remember
- Compare
sys.version_infotuples instead of parsingsys.version sys.platformis 'linux', 'darwin' or 'win32'- Use
sys.executableto launch child Python processes in the same environment
Watch out for
- Checking
sys.version[0] == '3'style string slices; they break on versions like 3.10 vs 3.9.