PyMOTW: sys, Part 1: Interpreter Settings

By Doug Hellmann
October 12, 2009

Interpreter Settings

sys contains attributes and functions for accessing compile-time or runtime configuration settings for the interpreter.

Build-time Version Information

The version used to build the C interpreter is available in a few forms. sys.version is a human-readable string that usually includes the full version number as well as information about the build date, compiler, and platform. sys.hexversion is easier to use for checking the interpreter version since it is a simple integer. When formatted using hex(), it is clear that parts of sys.hexversion come from the version information also visible in the more readable sys.version_info (a 5-part tuple representing just the version number). More specific information about the source that went into the build can be found in the sys.subversion tuple, which includes the actual branch and subversion revision that was checked out and built. The separate C API version used by the current interpreter is saved in sys.api_version.

import sys

print 'Version info:'
print 'sys.version =', repr(sys.version)
print 'sys.version_info =', sys.version_info
print 'sys.hexversion =', hex(sys.hexversion)
print 'sys.subversion =', sys.subversion
print 'sys.api_version =', sys.api_version

$ python
Version info:

sys.version = '2.6.2 (r262:71600, Apr 16 2009, 09:17:39) \n[GCC 4.0.1 (Apple Computer, Inc. build 5250)]'
sys.version_info = (2, 6, 2, 'final', 0)
sys.hexversion = 0x20602f0
sys.subversion = ('CPython', 'tags/r262', '71600')
sys.api_version = 1013

The operating system platform used to build the interpreter is saved as sys.platform. For most Unix systems, the value comes from combining the output of uname -s with the first part of the version in uname -r. For other operating systems there is a hard-coded table of values.

import sys

print 'This interpreter was built for:', sys.platform

$ python
This interpreter was built for: darwin

Install Location

The path to the actual interpreter program is available in sys.executable on all systems for which having a path to the interpreter makes sense. This can be useful for ensuring that the right interpreter is being used, and also gives clues about paths that might be set based on the interpreter location.

sys.prefix refers to the parent directory of the interpreter installation. It usually includes bin and lib directories for

import sys

print 'Interpreter executable:', sys.executable
print 'Installation prefix :', sys.prefix


The build for PyMOTW uses a virtualenv, so these paths do not match the defaults.

$ python
Interpreter executable: /Users/dhellmann/.virtualenvs/pymotw/bin/python
Installation prefix : /Users/dhellmann/.virtualenvs/pymotw/bin/..

Command Line Options

The CPython interpreter accepts several command line options to control its behavior.

$ python -h
usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
Options and arguments (and corresponding environment variables):
-B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x
-c cmd : program passed in as string (terminates option list)
-d : debug output from parser; also PYTHONDEBUG=x
-E : ignore PYTHON* environment variables (such as PYTHONPATH)
-h : print this help message and exit (also --help)
-i : inspect interactively after running script; forces a prompt even
if stdin does not appear to be a terminal; also PYTHONINSPECT=x
-m mod : run library module as a script (terminates option list)
-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x
-OO : remove doc-strings in addition to the -O optimizations
-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew
-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE
-S : don't imply 'import site' on initialization
-t : issue warnings about inconsistent tab usage (-tt: issue errors)
-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x
see man page for details on internal buffering relating to '-u'
-v : verbose (trace import statements); also PYTHONVERBOSE=x
can be supplied multiple times to increase verbosity
-V : print the Python version number and exit (also --version)
-W arg : warning control; arg is action:message:category:module:lineno
-x : skip first line of source, allowing use of non-Unix forms of #!cmd
-3 : warn about Python 3.x incompatibilities that 2to3 cannot trivially fix
file : program read from script file
- : program read from stdin (default; interactive mode if a tty)
arg ...: arguments passed to program in sys.argv[1:]

Other environment variables:
PYTHONSTARTUP: file executed on interactive startup (no default)
PYTHONPATH : ':'-separated list of directories prefixed to the
default module search path. The result is sys.path.
PYTHONHOME : alternate <prefix> directory (or <prefix>:<exec_prefix>).
The default module search path uses <prefix>/pythonX.X.
PYTHONCASEOK : ignore case in 'import' statements (Windows).
PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.

Some of these are available for programs to check through sys.flags.

import sys

if sys.flags.debug:
print 'Debuging'
if sys.flags.py3k_warning:
print 'Warning about Python 3.x incompatibilities'
if sys.flags.division_warning:
print 'Warning about division change'
if sys.flags.division_new:
print 'New division behavior enabled'
if sys.flags.inspect:
print 'Will enter interactive mode after running'
if sys.flags.optimize:
print 'Optimizing byte-code'
if sys.flags.dont_write_bytecode:
print 'Not writing byte-code files'
if sys.flags.no_site:
print 'Not importing "site"'
if sys.flags.ignore_environment:
print 'Ignoring environment'
if sys.flags.tabcheck:
print 'Checking for mixed tabs and spaces'
if sys.flags.verbose:
print 'Verbose mode'
if sys.flags.unicode:
print 'Unicode'

$ python -3 -S -E
Warning about Python 3.x incompatibilities
Warning about division change
Not importing "site"
Ignoring environment

Unicode Defaults

You can ask for the default Unicode encoding being used by the interpreter with getdefaultencoding(). The value is set during startup by site, which calls sys.setdefaultencoding() and then removes it from the namespace in sys to avoid having it called again.

The internal encoding default and the filesystem encoding may be different for some operating systems, so there is a separate way to retrieve the filesystem setting. getfilesystemencoding() returns an OS-specific (not filesystem-specific) value.

import sys

print 'Default encoding :', sys.getdefaultencoding()
print 'Filesystem encoding :', sys.getfilesystemencoding()


Rather than changing the global default encoding, most Unicode experts recommend making your
application explicitly Unicode-aware. This gives you two benefits: It lets you handle different
Unicode encodings, and ensures there are no assumptions about encodings in your application code.

$ python
Default encoding : ascii
Filesystem encoding : utf-8

Interactive Prompts

The interactive interpreter uses two separate prompts for indicating the default input level (ps1) and the “continuation” of a multi-line statement (ps2). The values are only used by the interactive interpreter.

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '

Either or both prompt can be changed to a different string

>>> sys.ps1 = '::: '
::: sys.ps2 = '~~~ '
::: for i in range(3):
~~~ print i

Alternately, any object that can be converted to a string (via __str__) can be used for the prompt.

import sys

class LineCounter(object):
def __init__(self):
self.count = 0
def __str__(self):
self.count += 1
return '(%3d)> ' % self.count

$ python
Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyMOTW.sys.sys_ps1 import LineCounter
>>> import sys
>>> sys.ps1 = LineCounter()
( 1)>
( 2)>
( 3)>

Display Hook

sys.displayhook is invoked by the interactive interpreter each time the user enters an expression. The result of the expression is passed as the only argument to the function. The default value (saved in sys.__displayhook__) prints the result to stdout and saves it in __builtin__._ for easy reference later.

import sys

class ExpressionCounter(object):

def __init__(self):
self.count = 0
self.previous_value = self

def __call__(self, value):
print ' Previous:', self.previous_value
print ' New :', value
if value != self.previous_value:
self.count += 1
sys.ps1 = '(%3d)> ' % self.count
self.previous_value = value

print 'installing'
sys.displayhook = ExpressionCounter()

$ python
Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)
[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyMOTW.sys.sys_displayhook
>>> 1+2

Previous: <PyMOTW.sys.sys_displayhook.ExpressionCounter object at 0x9c5f90>
New : 3

( 1)> 'abc'

Previous: 3
New : abc

( 2)> 'abc'

Previous: abc
New : abc

( 2)> 'abc' * 3

Previous: abc
New : abcabcabc

( 3)>


The canonical version of this article

You might also be interested in:

News Topics

Recommended for You

Got a Question?