sys — interpreter & runtime introspection#

Part of a series demonstrating the 5 most-imported modules across the top PyPI packages (from imports_ranked.csv). Rank 2 of 5 — imported by 65.7% of crawled packages.

sys is the window into the running Python interpreter: version, platform, module cache, streams, recursion limits, and program exit.

Version and platform#

import sys

print('version     :', sys.version.split()[0])
print('version_info:', tuple(sys.version_info))
print('platform    :', sys.platform)
print('executable  :', sys.executable)
print('maxsize     :', sys.maxsize)
print('byteorder   :', sys.byteorder)
version     : 3.11.15
version_info: (3, 11, 15, 'final', 0)
platform    : linux
executable  : /opt/hostedtoolcache/Python/3.11.15/x64/bin/python
maxsize     : 9223372036854775807
byteorder   : little

sys.path — the module search path#

The list of directories Python searches when importing.

import sys
print(f'{len(sys.path)} entries on sys.path; first few:')
for p in sys.path[:5]:
    print('  ', p or '<cwd>')
5 entries on sys.path; first few:
   /opt/hostedtoolcache/Python/3.11.15/x64/lib/python311.zip
   /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11
   /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/lib-dynload
   <cwd>
   /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages

sys.modules — the import cache#

Every imported module lives here; imports are cheap after the first.

import sys
print('modules loaded:', len(sys.modules))
print('is json loaded? ', 'json' in sys.modules)
import json
print('is json loaded? ', 'json' in sys.modules)
modules loaded: 857
is json loaded?  True
is json loaded?  True

sys.argv — command-line arguments#

In a notebook argv reflects the kernel launch, but this is how scripts read their arguments: argv[0] is the program, the rest are args.

import sys
print('argv length:', len(sys.argv))
print('argv[0]    :', sys.argv[0])
argv length: 4
argv[0]    : /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/ipykernel_launcher.py

getsizeof, recursion limit, and float_info#

import sys
print('size of []      :', sys.getsizeof([]), 'bytes')
print('size of [1,2,3] :', sys.getsizeof([1, 2, 3]), 'bytes')
print('recursion limit :', sys.getrecursionlimit())
print('float max       :', sys.float_info.max)
size of []      : 56 bytes
size of [1,2,3] : 88 bytes
recursion limit : 1000
float max       : 1.7976931348623157e+308

Standard streams: stdout / stderr#

print writes to sys.stdout; diagnostics conventionally go to sys.stderr.

import sys
sys.stdout.write('to stdout\n')
sys.stderr.write('to stderr (shown in red in Jupyter)\n')
sys.stdout.flush()
to stdout
to stderr (shown in red in Jupyter)

sys.exit — ending a program#

sys.exit() raises SystemExit. We catch it here so it does not stop the kernel; in a real script it terminates the process with a status code (0 = success).

import sys
try:
    sys.exit(0)
except SystemExit as e:
    print('SystemExit raised with code:', e.code)
SystemExit raised with code: 0

Bonus: sys.stdlib_module_names#

The very set used by the analysis script to decide what counts as standard library.

import sys
names = getattr(sys, 'stdlib_module_names', frozenset())
print('stdlib modules known to this interpreter:', len(names))
print('sample:', sorted(names)[:12])
stdlib modules known to this interpreter: 305
sample: ['__future__', '_abc', '_aix_support', '_ast', '_asyncio', '_bisect', '_blake2', '_bootsubprocess', '_bz2', '_codecs', '_codecs_cn', '_codecs_hk']