\section{Built-in Functions \label{built-in-funcs}}

The Python interpreter has a number of functions built into it that
are always available.  They are listed here in alphabetical order.


\setindexsubitem{(built-in function)}

\begin{funcdesc}{__import__}{name\optional{, globals\optional{, locals\optional{, fromlist\optional{, level}}}}}
  This function is invoked by the \keyword{import}\stindex{import}
  statement.  It mainly exists so that you can replace it with another
  function that has a compatible interface, in order to change the
  semantics of the \keyword{import} statement.  For examples of why
  and how you would do this, see the standard library modules
  \module{ihooks}\refstmodindex{ihooks} and
  \refmodule{rexec}\refstmodindex{rexec}.  See also the built-in
  module \refmodule{imp}\refbimodindex{imp}, which defines some useful
  operations out of which you can build your own
  \function{__import__()} function.

  For example, the statement \samp{import spam} results in the
  following call: \code{__import__('spam',} \code{globals(),}
  \code{locals(), [], -1)}; the statement \samp{from spam.ham import eggs}
  results in \samp{__import__('spam.ham', globals(), locals(),
  ['eggs'], -1)}.  Note that even though \code{locals()} and
  \code{['eggs']} are passed in as arguments, the
  \function{__import__()} function does not set the local variable
  named \code{eggs}; this is done by subsequent code that is generated
  for the import statement.  (In fact, the standard implementation
  does not use its \var{locals} argument at all, and uses its
  \var{globals} only to determine the package context of the
  \keyword{import} statement.)

  When the \var{name} variable is of the form \code{package.module},
  normally, the top-level package (the name up till the first dot) is
  returned, \emph{not} the module named by \var{name}.  However, when
  a non-empty \var{fromlist} argument is given, the module named by
  \var{name} is returned.  This is done for compatibility with the
  bytecode generated for the different kinds of import statement; when
  using \samp{import spam.ham.eggs}, the top-level package \module{spam}
  must be placed in the importing namespace, but when using \samp{from
  spam.ham import eggs}, the \code{spam.ham} subpackage must be used
  to find the \code{eggs} variable.  As a workaround for this
  behavior, use \function{getattr()} to extract the desired
  components.  For example, you could define the following helper:

\begin{verbatim}
def my_import(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod
\end{verbatim}

  \var{level} specifies whether to use absolute or relative imports.
  The default is \code{-1} which indicates both absolute and relative
  imports will be attempted.  \code{0} means only perform absolute imports.
  Positive values for \var{level} indicate the number of parent directories
  to search relative to the directory of the module calling
  \function{__import__}.
\versionchanged[The level parameter was added]{2.5}
\versionchanged[Keyword support for parameters was added]{2.5}
\end{funcdesc}

\begin{funcdesc}{abs}{x}
  Return the absolute value of a number.  The argument may be a plain
  or long integer or a floating point number.  If the argument is a
  complex number, its magnitude is returned.
\end{funcdesc}

\begin{funcdesc}{all}{iterable}
  Return True if all elements of the \var{iterable} are true.
  Equivalent to:
  \begin{verbatim}
     def all(iterable):
         for element in iterable:
             if not element:
                 return False
         return True
  \end{verbatim}
  \versionadded{2.5}
\end{funcdesc}

\begin{funcdesc}{any}{iterable}
  Return True if any element of the \var{iterable} is true.
  Equivalent to:
  \begin{verbatim}
     def any(iterable):
         for element in iterable:
             if element:
                 return True
         return False
  \end{verbatim}
  \versionadded{2.5}
\end{funcdesc}

\begin{funcdesc}{basestring}{}
  This abstract type is the superclass for \class{str} and \class{unicode}.
  It cannot be called or instantiated, but it can be used to test whether
  an object is an instance of \class{str} or \class{unicode}.
  \code{isinstance(obj, basestring)} is equivalent to
  \code{isinstance(obj, (str, unicode))}.
  \versionadded{2.3}
\end{funcdesc}

\begin{funcdesc}{bool}{\optional{x}}
  Convert a value to a Boolean, using the standard truth testing
  procedure.  If \var{x} is false or omitted, this returns
  \constant{False}; otherwise it returns \constant{True}.
  \class{bool} is also a class, which is a subclass of \class{int}.
  Class \class{bool} cannot be subclassed further.  Its only instances
  are \constant{False} and \constant{True}.

  \indexii{Boolean}{type}
  \versionadded{2.2.1}
  \versionchanged[If no argument is given, this function returns
                  \constant{False}]{2.3}
\end{funcdesc}

\begin{funcdesc}{callable}{object}
  Return true if the \var{object} argument appears callable, false if
  not.  If this returns true, it is still possible that a call fails,
  but if it is false, calling \var{object} will never succeed.  Note
  that classes are callable (calling a class returns a new instance);
  class instances are callable if they have a \method{__call__()}
  method.
\end{funcdesc}

\begin{funcdesc}{chr}{i}
  Return a string of one character whose \ASCII{} code is the integer
  \var{i}.  For example, \code{chr(97)} returns the string \code{'a'}.
  This is the inverse of \function{ord()}.  The argument must be in
  the range [0..255], inclusive; \exception{ValueError} will be raised
  if \var{i} is outside that range.
\end{funcdesc}

\begin{funcdesc}{classmethod}{function}
  Return a class method for \var{function}.

  A class method receives the class as implicit first argument,
  just like an instance method receives the instance.
  To declare a class method, use this idiom:

\begin{verbatim}
class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ...
\end{verbatim}

  The \code{@classmethod} form is a function decorator -- see the description
  of function definitions in chapter 7 of the
  \citetitle[../ref/ref.html]{Python Reference Manual} for details.

  It can be called either on the class (such as \code{C.f()}) or on an
  instance (such as \code{C().f()}).  The instance is ignored except for
  its class.
  If a class method is called for a derived class, the derived class
  object is passed as the implied first argument.

  Class methods are different than \Cpp{} or Java static methods.
  If you want those, see \function{staticmethod()} in this section.
  
  For more information on class methods, consult the documentation on the
  standard type hierarchy in chapter 3 of the
  \citetitle[../ref/types.html]{Python Reference Manual} (at the bottom).
  \versionadded{2.2}
  \versionchanged[Function decorator syntax added]{2.4}
\end{funcdesc}

\begin{funcdesc}{cmp}{x, y}
  Compare the two objects \var{x} and \var{y} and return an integer
  according to the outcome.  The return value is negative if \code{\var{x}
  < \var{y}}, zero if \code{\var{x} == \var{y}} and strictly positive if
  \code{\var{x} > \var{y}}.
\end{funcdesc}

\begin{funcdesc}{compile}{string, filename, kind\optional{,
                          flags\optional{, dont_inherit}}}
  Compile the \var{string} into a code object.  Code objects can be
  executed by an \keyword{exec} statement or evaluated by a call to
  \function{eval()}.  The \var{filename} argument should
  give the file from which the code was read; pass some recognizable value
  if it wasn't read from a file (\code{'<string>'} is commonly used).
  The \var{kind} argument specifies what kind of code must be
  compiled; it can be \code{'exec'} if \var{string} consists of a
  sequence of statements, \code{'eval'} if it consists of a single
  expression, or \code{'single'} if it consists of a single
  interactive statement (in the latter case, expression statements
  that evaluate to something else than \code{None} will be printed).

  When compiling multi-line statements, two caveats apply: line
  endings must be represented by a single newline character
  (\code{'\e n'}), and the input must be terminated by at least one
  newline character.  If line endings are represented by
  \code{'\e r\e n'}, use the string \method{replace()} method to
  change them into \code{'\e n'}.

  The optional arguments \var{flags} and \var{dont_inherit}
  (which are new in Python 2.2) control which future statements (see
  \pep{236}) affect the compilation of \var{string}.  If neither is
  present (or both are zero) the code is compiled with those future
  statements that are in effect in the code that is calling compile.
  If the \var{flags} argument is given and \var{dont_inherit} is not
  (or is zero) then the future statements specified by the \var{flags}
  argument are used in addition to those that would be used anyway.
  If \var{dont_inherit} is a non-zero integer then the \var{flags}
  argument is it -- the future statements in effect around the call to
  compile are ignored.

  Future statements are specified by bits which can be bitwise or-ed
  together to specify multiple statements.  The bitfield required to
  specify a given feature can be found as the \member{compiler_flag}
  attribute on the \class{_Feature} instance in the
  \module{__future__} module.
\end{funcdesc}

\begin{funcdesc}{complex}{\optional{real\optional{, imag}}}
  Create a complex number with the value \var{real} + \var{imag}*j or
  convert a string or number to a complex number.  If the first
  parameter is a string, it will be interpreted as a complex number
  and the function must be called without a second parameter.  The
  second parameter can never be a string.
  Each argument may be any numeric type (including complex).
  If \var{imag} is omitted, it defaults to zero and the function
  serves as a numeric conversion function like \function{int()},
  \function{long()} and \function{float()}.  If both arguments
  are omitted, returns \code{0j}.
\end{funcdesc}

\begin{funcdesc}{delattr}{object, name}
  This is a relative of \function{setattr()}.  The arguments are an
  object and a string.  The string must be the name
  of one of the object's attributes.  The function deletes
  the named attribute, provided the object allows it.  For example,
  \code{delattr(\var{x}, '\var{foobar}')} is equivalent to
  \code{del \var{x}.\var{foobar}}.
\end{funcdesc}

\begin{funcdesc}{dict}{\optional{mapping-or-sequence}}
  Return a new dictionary initialized from an optional positional
  argument or from a set of keyword arguments.
  If no arguments are given, return a new empty dictionary.
  If the positional argument is a mapping object, return a dictionary
  mapping the same keys to the same values as does the mapping object.
  Otherwise the positional argument must be a sequence, a container that
  supports iteration, or an iterator object.  The elements of the argument
  must each also be of one of those kinds, and each must in turn contain
  exactly two objects.  The first is used as a key in the new dictionary,
  and the second as the key's value.  If a given key is seen more than
  once, the last value associated with it is retained in the new
  dictionary.

  If keyword arguments are given, the keywords themselves with their
  associated values are added as items to the dictionary. If a key
  is specified both in the positional argument and as a keyword argument,
  the value associated with the keyword is retained in the dictionary.
  For example, these all return a dictionary equal to
  \code{\{"one": 2, "two": 3\}}:

  \begin{itemize}
    \item \code{dict(\{'one': 2, 'two': 3\})}
    \item \code{dict(\{'one': 2, 'two': 3\}.items())}
    \item \code{dict(\{'one': 2, 'two': 3\}.iteritems())}
    \item \code{dict(zip(('one', 'two'), (2, 3)))}
    \item \code{dict([['two', 3], ['one', 2]])}
    \item \code{dict(one=2, two=3)}
    \item \code{dict([(['one', 'two'][i-2], i) for i in (2, 3)])}
  \end{itemize}

  \versionadded{2.2}
  \versionchanged[Support for building a dictionary from keyword
                  arguments added]{2.3}
\end{funcdesc}

\begin{funcdesc}{dir}{\optional{object}}
  Without arguments, return the list of names in the current local
  symbol table.  With an argument, attempts to return a list of valid
  attributes for that object.  This information is gleaned from the
  object's \member{__dict__} attribute, if defined, and from the class
  or type object.  The list is not necessarily complete.
  If the object is a module object, the list contains the names of the
  module's attributes.
  If the object is a type or class object,
  the list contains the names of its attributes,
  and recursively of the attributes of its bases.
  Otherwise, the list contains the object's attributes' names,
  the names of its class's attributes,
  and recursively of the attributes of its class's base classes.
  The resulting list is sorted alphabetically.
  For example:

\begin{verbatim}
>>> import struct
>>> dir()
['__builtins__', '__doc__', '__name__', 'struct']
>>> dir(struct)
['__doc__', '__name__', 'calcsize', 'error', 'pack', 'unpack']
\end{verbatim}

  \note{Because \function{dir()} is supplied primarily as a convenience
  for use at an interactive prompt,
  it tries to supply an interesting set of names more than it tries to
  supply a rigorously or consistently defined set of names,
  and its detailed behavior may change across releases.}
\end{funcdesc}

\begin{funcdesc}{divmod}{a, b}
  Take two (non complex) numbers as arguments and return a pair of numbers
  consisting of their quotient and remainder when using long division.  With
  mixed operand types, the rules for binary arithmetic operators apply.  For
  plain and long integers, the result is the same as
  \code{(\var{a} // \var{b}, \var{a} \%{} \var{b})}.
  For floating point numbers the result is \code{(\var{q}, \var{a} \%{}
  \var{b})}, where \var{q} is usually \code{math.floor(\var{a} /
  \var{b})} but may be 1 less than that.  In any case \code{\var{q} *
  \var{b} + \var{a} \%{} \var{b}} is very close to \var{a}, if
  \code{\var{a} \%{} \var{b}} is non-zero it has the same sign as
  \var{b}, and \code{0 <= abs(\var{a} \%{} \var{b}) < abs(\var{b})}.

  \versionchanged[Using \function{divmod()} with complex numbers is
                  deprecated]{2.3}
\end{funcdesc}

\begin{funcdesc}{enumerate}{iterable}
  Return an enumerate object. \var{iterable} must be a sequence, an
  iterator, or some other object which supports iteration.  The
  \method{next()} method of the iterator returned by
  \function{enumerate()} returns a tuple containing a count (from
  zero) and the corresponding value obtained from iterating over
  \var{iterable}.  \function{enumerate()} is useful for obtaining an
  indexed series: \code{(0, seq[0])}, \code{(1, seq[1])}, \code{(2,
  seq[2])}, \ldots.
  \versionadded{2.3}
\end{funcdesc}

\begin{funcdesc}{eval}{expression\optional{, globals\optional{, locals}}}
  The arguments are a string and optional globals and locals.  If provided,
  \var{globals} must be a dictionary.  If provided, \var{locals} can be
  any mapping object.  \versionchanged[formerly \var{locals} was required
  to be a dictionary]{2.4}

  The \var{expression} argument is parsed and evaluated as a Python
  expression (technically speaking, a condition list) using the
  \var{globals} and \var{locals} dictionaries as global and local name
  space.  If the \var{globals} dictionary is present and lacks
  '__builtins__', the current globals are copied into \var{globals} before
  \var{expression} is parsed.  This means that \var{expression}
  normally has full access to the standard
  \refmodule[builtin]{__builtin__} module and restricted environments
  are propagated.  If the \var{locals} dictionary is omitted it defaults to
  the \var{globals} dictionary.  If both dictionaries are omitted, the
  expression is executed in the environment where \keyword{eval} is
  called.  The return value is the result of the evaluated expression.
  Syntax errors are reported as exceptions.  Example:

\begin{verbatim}
>>> x = 1
>>> print eval('x+1')
2
\end{verbatim}

  This function can also be used to execute arbitrary code objects
  (such as those created by \function{compile()}).  In this case pass
  a code object instead of a string.  The code object must have been
  compiled passing \code{'eval'} as the \var{kind} argument.

  Hints: dynamic execution of statements is supported by the
  \keyword{exec} statement.  Execution of statements from a file is
  supported by the \function{execfile()} function.  The
  \function{globals()} and \function{locals()} functions returns the
  current global and local dictionary, respectively, which may be
  useful to pass around for use by \function{eval()} or
  \function{execfile()}.
\end{funcdesc}

\begin{funcdesc}{execfile}{filename\optional{, globals\optional{, locals}}}
  This function is similar to the
  \keyword{exec} statement, but parses a file instead of a string.  It
  is different from the \keyword{import} statement in that it does not
  use the module administration --- it reads the file unconditionally
  and does not create a new module.\footnote{It is used relatively
  rarely so does not warrant being made into a statement.}

  The arguments are a file name and two optional dictionaries.  The file is
  parsed and evaluated as a sequence of Python statements (similarly to a
  module) using the \var{globals} and \var{locals} dictionaries as global and
  local namespace. If provided, \var{locals} can be any mapping object.
  \versionchanged[formerly \var{locals} was required to be a dictionary]{2.4}
  If the \var{locals} dictionary is omitted it defaults to the \var{globals}
  dictionary. If both dictionaries are omitted, the expression is executed in
  the environment where \function{execfile()} is called.  The return value is
  \code{None}.

  \warning{The default \var{locals} act as described for function
  \function{locals()} below:  modifications to the default \var{locals}
  dictionary should not be attempted.  Pass an explicit \var{locals}
  dictionary if you need to see effects of the code on \var{locals} after
  function \function{execfile()} returns.  \function{execfile()} cannot
  be used reliably to modify a function's locals.}
\end{funcdesc}

\begin{funcdesc}{file}{filename\optional{, mode\optional{, bufsize}}}
  Return a new file object (described in
  section~\ref{bltin-file-objects}, ``\ulink{File
  Objects}{bltin-file-objects.html}'').
  The first two arguments are the same as for \code{stdio}'s
  \cfunction{fopen()}: \var{filename} is the file name to be opened,
  \var{mode} indicates how the file is to be opened: \code{'r'} for
  reading, \code{'w'} for writing (truncating an existing file), and
  \code{'a'} opens it for appending (which on \emph{some} \UNIX{}
  systems means that \emph{all} writes append to the end of the file,
  regardless of the current seek position).

  Modes \code{'r+'}, \code{'w+'} and \code{'a+'} open the file for
  updating (note that \code{'w+'} truncates the file).  Append
  \code{'b'} to the mode to open the file in binary mode, on systems
  that differentiate between binary and text files (else it is
  ignored).  If the file cannot be opened, \exception{IOError} is
  raised.
  
  In addition to the standard \cfunction{fopen()} values \var{mode}
  may be \code{'U'} or \code{'rU'}. If Python is built with universal
  newline support (the default) the file is opened as a text file, but
  lines may be terminated by any of \code{'\e n'}, the Unix end-of-line
  convention,
  \code{'\e r'}, the Macintosh convention or \code{'\e r\e n'}, the Windows
  convention. All of these external representations are seen as
  \code{'\e n'}
  by the Python program. If Python is built without universal newline support
  \var{mode} \code{'U'} is the same as normal text mode.  Note that
  file objects so opened also have an attribute called
  \member{newlines} which has a value of \code{None} (if no newlines
  have yet been seen), \code{'\e n'}, \code{'\e r'}, \code{'\e r\e n'},
  or a tuple containing all the newline types seen.

  Python enforces that the mode, after stripping \code{'U'}, begins with
  \code{'r'}, \code{'w'} or \code{'a'}.

  If \var{mode} is omitted, it defaults to \code{'r'}.  When opening a
  binary file, you should append \code{'b'} to the \var{mode} value
  for improved portability.  (It's useful even on systems which don't
  treat binary and text files differently, where it serves as
  documentation.)
  \index{line-buffered I/O}\index{unbuffered I/O}\index{buffer size, I/O}
  \index{I/O control!buffering}
  The optional \var{bufsize} argument specifies the
  file's desired buffer size: 0 means unbuffered, 1 means line
  buffered, any other positive value means use a buffer of
  (approximately) that size.  A negative \var{bufsize} means to use
  the system default, which is usually line buffered for tty
  devices and fully buffered for other files.  If omitted, the system
  default is used.\footnote{
    Specifying a buffer size currently has no effect on systems that
    don't have \cfunction{setvbuf()}.  The interface to specify the
    buffer size is not done using a method that calls
    \cfunction{setvbuf()}, because that may dump core when called
    after any I/O has been performed, and there's no reliable way to
    determine whether this is the case.}

  \versionadded{2.2}

  \versionchanged[Restriction on first letter of mode string
                  introduced]{2.5}
\end{funcdesc}

\begin{funcdesc}{filter}{function, list}
  Construct a list from those elements of \var{list} for which
  \var{function} returns true.  \var{list} may be either a sequence, a
  container which supports iteration, or an iterator,  If \var{list}
  is a string or a tuple, the result also has that type; otherwise it
  is always a list.  If \var{function} is \code{None}, the identity
  function is assumed, that is, all elements of \var{list} that are false
  (zero or empty) are removed.

  Note that \code{filter(function, \var{list})} is equivalent to
  \code{[item for item in \var{list} if function(item)]} if function is
  not \code{None} and \code{[item for item in \var{list} if item]} if
  function is \code{None}.
\end{funcdesc}

\begin{funcdesc}{float}{\optional{x}}
  Convert a string or a number to floating point.  If the argument is a
  string, it must contain a possibly signed decimal or floating point
  number, possibly embedded in whitespace. Otherwise, the argument may be a plain
  or long integer or a floating point number, and a floating point
  number with the same value (within Python's floating point
  precision) is returned.  If no argument is given, returns \code{0.0}.

  \note{When passing in a string, values for NaN\index{NaN}
  and Infinity\index{Infinity} may be returned, depending on the
  underlying C library.  The specific set of strings accepted which
  cause these values to be returned depends entirely on the C library
  and is known to vary.}
\end{funcdesc}

\begin{funcdesc}{frozenset}{\optional{iterable}}
  Return a frozenset object whose elements are taken from \var{iterable}.
  Frozensets are sets that have no update methods but can be hashed and
  used as members of other sets or as dictionary keys.  The elements of
  a frozenset must be immutable themselves.  To represent sets of sets,
  the inner sets should also be \class{frozenset} objects.  If
  \var{iterable} is not specified, returns a new empty set,
  \code{frozenset([])}.
  \versionadded{2.4}
\end{funcdesc}

\begin{funcdesc}{getattr}{object, name\optional{, default}}
  Return the value of the named attributed of \var{object}.  \var{name}
  must be a string.  If the string is the name of one of the object's
  attributes, the result is the value of that attribute.  For example,
  \code{getattr(x, 'foobar')} is equivalent to \code{x.foobar}.  If the
  named attribute does not exist, \var{default} is returned if provided,
  otherwise \exception{AttributeError} is raised.
\end{funcdesc}

\begin{funcdesc}{globals}{}
  Return a dictionary representing the current global symbol table.
  This is always the dictionary of the current module (inside a
  function or method, this is the module where it is defined, not the
  module from which it is called).
\end{funcdesc}

\begin{funcdesc}{hasattr}{object, name}
  The arguments are an object and a string.  The result is \code{True} if the
  string is the name of one of the object's attributes, \code{False} if not.
  (This is implemented by calling \code{getattr(\var{object},
  \var{name})} and seeing whether it raises an exception or not.)
\end{funcdesc}

\begin{funcdesc}{hash}{object}
  Return the hash value of the object (if it has one).  Hash values
  are integers.  They are used to quickly compare dictionary
  keys during a dictionary lookup.  Numeric values that compare equal
  have the same hash value (even if they are of different types, as is
  the case for 1 and 1.0).
\end{funcdesc}

\begin{funcdesc}{help}{\optional{object}}
  Invoke the built-in help system.  (This function is intended for
  interactive use.)  If no argument is given, the interactive help
  system starts on the interpreter console.  If the argument is a
  string, then the string is looked up as the name of a module,
  function, class, method, keyword, or documentation topic, and a
  help page is printed on the console.  If the argument is any other
  kind of object, a help page on the object is generated.
  \versionadded{2.2}
\end{funcdesc}

\begin{funcdesc}{hex}{x}
  Convert an integer number (of any size) to a hexadecimal string.
  The result is a valid Python expression.
  \versionchanged[Formerly only returned an unsigned literal]{2.4}
\end{funcdesc}

\begin{funcdesc}{id}{object}
  Return the ``identity'' of an object.  This is an integer (or long
  integer) which is guaranteed to be unique and constant for this
  object during its lifetime.  Two objects with non-overlapping lifetimes
  may have the same \function{id()} value.  (Implementation
  note: this is the address of the object.)
\end{funcdesc}

\begin{funcdesc}{int}{\optional{x\optional{, radix}}}
  Convert a string or number to a plain integer.  If the argument is a
  string, it must contain a possibly signed decimal number
  representable as a Python integer, possibly embedded in whitespace.
  The \var{radix} parameter gives the base for the
  conversion and may be any integer in the range [2, 36], or zero.  If
  \var{radix} is zero, the proper radix is guessed based on the
  contents of string; the interpretation is the same as for integer
  literals.  If \var{radix} is specified and \var{x} is not a string,
  \exception{TypeError} is raised.
  Otherwise, the argument may be a plain or
  long integer or a floating point number.  Conversion of floating
  point numbers to integers truncates (towards zero).
  If the argument is outside the integer range a long object will
  be returned instead.  If no arguments are given, returns \code{0}.
\end{funcdesc}

\begin{funcdesc}{isinstance}{object, classinfo}
  Return true if the \var{object} argument is an instance of the
  \var{classinfo} argument, or of a (direct or indirect) subclass
  thereof.  Also return true if \var{classinfo} is a type object and
  \var{object} is an object of that type.  If \var{object} is not a
  class instance or an object of the given type, the function always
  returns false.  If \var{classinfo} is neither a class object nor a
  type object, it may be a tuple of class or type objects, or may
  recursively contain other such tuples (other sequence types are not
  accepted).  If \var{classinfo} is not a class, type, or tuple of
  classes, types, and such tuples, a \exception{TypeError} exception
  is raised.
  \versionchanged[Support for a tuple of type information was added]{2.2}
\end{funcdesc}

\begin{funcdesc}{issubclass}{class, classinfo}
  Return true if \var{class} is a subclass (direct or indirect) of
  \var{classinfo}.  A class is considered a subclass of itself.
  \var{classinfo} may be a tuple of class objects, in which case every
  entry in \var{classinfo} will be checked. In any other case, a
  \exception{TypeError} exception is raised.
  \versionchanged[Support for a tuple of type information was added]{2.3}
\end{funcdesc}

\begin{funcdesc}{iter}{o\optional{, sentinel}}
  Return an iterator object.  The first argument is interpreted very
  differently depending on the presence of the second argument.
  Without a second argument, \var{o} must be a collection object which
  supports the iteration protocol (the \method{__iter__()} method), or
  it must support the sequence protocol (the \method{__getitem__()}
  method with integer arguments starting at \code{0}).  If it does not
  support either of those protocols, \exception{TypeError} is raised.
  If the second argument, \var{sentinel}, is given, then \var{o} must
  be a callable object.  The iterator created in this case will call
  \var{o} with no arguments for each call to its \method{next()}
  method; if the value returned is equal to \var{sentinel},
  \exception{StopIteration} will be raised, otherwise the value will
  be returned.
  \versionadded{2.2}
\end{funcdesc}

\begin{funcdesc}{len}{s}
  Return the length (the number of items) of an object.  The argument
  may be a sequence (string, tuple or list) or a mapping (dictionary).
\end{funcdesc}

\begin{funcdesc}{list}{\optional{sequence}}
  Return a list whose items are the same and in the same order as
  \var{sequence}'s items.  \var{sequence} may be either a sequence, a
  container that supports iteration, or an iterator object.  If
  \var{sequence} is already a list, a copy is made and returned,
  similar to \code{\var{sequence}[:]}.  For instance,
  \code{list('abc')} returns \code{['a', 'b', 'c']} and \code{list(
  (1, 2, 3) )} returns \code{[1, 2, 3]}.  If no argument is given,
  returns a new empty list, \code{[]}.
\end{funcdesc}

\begin{funcdesc}{locals}{}
  Update and return a dictionary representing the current local symbol table.
  \warning{The contents of this dictionary should not be modified;
  changes may not affect the values of local variables used by the
  interpreter.}
\end{funcdesc}

\begin{funcdesc}{long}{\optional{x\optional{, radix}}}
  Convert a string or number to a long integer.  If the argument is a
  string, it must contain a possibly signed number of
  arbitrary size, possibly embedded in whitespace. The
  \var{radix} argument is interpreted in the same way as for
  \function{int()}, and may only be given when \var{x} is a string.
  Otherwise, the argument may be a plain or
  long integer or a floating point number, and a long integer with
  the same value is returned.    Conversion of floating
  point numbers to integers truncates (towards zero).  If no arguments
  are given, returns \code{0L}.
\end{funcdesc}

\begin{funcdesc}{map}{function, list, ...}
  Apply \var{function} to every item of \var{list} and return a list
  of the results.  If additional \var{list} arguments are passed,
  \var{function} must take that many arguments and is applied to the
  items of all lists in parallel; if a list is shorter than another it
  is assumed to be extended with \code{None} items.  If \var{function}
  is \code{None}, the identity function is assumed; if there are
  multiple list arguments, \function{map()} returns a list consisting
  of tuples containing the corresponding items from all lists (a kind
  of transpose operation).  The \var{list} arguments may be any kind
  of sequence; the result is always a list.
\end{funcdesc}

\begin{funcdesc}{max}{s\optional{, args...}\optional{key}}
  With a single argument \var{s}, return the largest item of a
  non-empty sequence (such as a string, tuple or list).  With more
  than one argument, return the largest of the arguments.

  The optional \var{key} argument specifies a one-argument ordering
  function like that used for \method{list.sort()}.  The \var{key}
  argument, if supplied, must be in keyword form (for example,
  \samp{max(a,b,c,key=func)}).
  \versionchanged[Added support for the optional \var{key} argument]{2.5}
\end{funcdesc}

\begin{funcdesc}{min}{s\optional{, args...}\optional{key}}
  With a single argument \var{s}, return the smallest item of a
  non-empty sequence (such as a string, tuple or list).  With more
  than one argument, return the smallest of the arguments.

  The optional \var{key} argument specifies a one-argument ordering
  function like that used for \method{list.sort()}.  The \var{key}
  argument, if supplied, must be in keyword form (for example,
  \samp{min(a,b,c,key=func)}).
  \versionchanged[Added support for the optional \var{key} argument]{2.5}           
\end{funcdesc}

\begin{funcdesc}{object}{}
  Return a new featureless object.  \class{object} is a base
  for all new style classes.  It has the methods that are common
  to all instances of new style classes.
  \versionadded{2.2}

  \versionchanged[This function does not accept any arguments.
  Formerly, it accepted arguments but ignored them]{2.3}
\end{funcdesc}

\begin{funcdesc}{oct}{x}
  Convert an integer number (of any size) to an octal string.  The
  result is a valid Python expression.
  \versionchanged[Formerly only returned an unsigned literal]{2.4}
\end{funcdesc}

\begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}}
  A wrapper for the \function{file()} function above.  The intent is
  for \function{open()} to be preferred for use as a factory function
  returning a new \class{file} object.  \class{file} is more suited to
  type testing (for example, writing \samp{isinstance(f, file)}).
\end{funcdesc}

\begin{funcdesc}{ord}{c}
  Given a string of length one, return an integer representing the
  Unicode code point of the character when the argument is a unicode object,
  or the value of the byte when the argument is an 8-bit string.
  For example, \code{ord('a')} returns the integer \code{97},
  \code{ord(u'\e u2020')} returns \code{8224}.  This is the inverse of
  \function{chr()} for 8-bit strings and of \function{unichr()} for unicode
  objects.  If a unicode argument is given and Python was built with
  UCS2 Unicode, then the character's code point must be in the range
  [0..65535] inclusive; otherwise the string length is two, and a
  \exception{TypeError} will be raised.
\end{funcdesc}

\begin{funcdesc}{pow}{x, y\optional{, z}}
  Return \var{x} to the power \var{y}; if \var{z} is present, return
  \var{x} to the power \var{y}, modulo \var{z} (computed more
  efficiently than \code{pow(\var{x}, \var{y}) \%\ \var{z}}).
  The two-argument form \code{pow(\var{x}, \var{y})} is equivalent to using
  the power operator: \code{\var{x}**\var{y}}.
  
  The arguments must have numeric types.  With mixed operand types, the
  coercion rules for binary arithmetic operators apply.  For int and
  long int operands, the result has the same type as the operands
  (after coercion) unless the second argument is negative; in that
  case, all arguments are converted to float and a float result is
  delivered.  For example, \code{10**2} returns \code{100}, but
  \code{10**-2} returns \code{0.01}.  (This last feature was added in
  Python 2.2.  In Python 2.1 and before, if both arguments were of integer
  types and the second argument was negative, an exception was raised.)
  If the second argument is negative, the third argument must be omitted.
  If \var{z} is present, \var{x} and \var{y} must be of integer types,
  and \var{y} must be non-negative.  (This restriction was added in
  Python 2.2.  In Python 2.1 and before, floating 3-argument \code{pow()}
  returned platform-dependent results depending on floating-point
  rounding accidents.)
\end{funcdesc}

\begin{funcdesc}{property}{\optional{fget\optional{, fset\optional{,
                           fdel\optional{, doc}}}}}
  Return a property attribute for new-style classes (classes that
  derive from \class{object}).

  \var{fget} is a function for getting an attribute value, likewise
  \var{fset} is a function for setting, and \var{fdel} a function
  for del'ing, an attribute.  Typical use is to define a managed attribute x:

\begin{verbatim}
class C(object):
    def __init__(self): self.__x = None
    def getx(self): return self.__x
    def setx(self, value): self.__x = value
    def delx(self): del self.__x
    x = property(getx, setx, delx, "I'm the 'x' property.")
\end{verbatim}

  If given, \var{doc} will be the docstring of the property attribute.
  Otherwise, the property will copy \var{fget}'s docstring (if it
  exists).

  \versionadded{2.2}
  \versionchanged[Use \var{fget}'s docstring if no \var{doc} given]{2.5}
\end{funcdesc}

\begin{funcdesc}{range}{\optional{start,} stop\optional{, step}}
  This is a versatile function to create lists containing arithmetic
  progressions.  It is most often used in \keyword{for} loops.  The
  arguments must be plain integers.  If the \var{step} argument is
  omitted, it defaults to \code{1}.  If the \var{start} argument is
  omitted, it defaults to \code{0}.  The full form returns a list of
  plain integers \code{[\var{start}, \var{start} + \var{step},
  \var{start} + 2 * \var{step}, \ldots]}.  If \var{step} is positive,
  the last element is the largest \code{\var{start} + \var{i} *
  \var{step}} less than \var{stop}; if \var{step} is negative, the last
  element is the smallest \code{\var{start} + \var{i} * \var{step}}
  greater than \var{stop}.  \var{step} must not be zero (or else
  \exception{ValueError} is raised).  Example:

\begin{verbatim}
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5)
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(0, -10, -1)
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]
\end{verbatim}
\end{funcdesc}

\begin{funcdesc}{reduce}{function, sequence\optional{, initializer}}
  Apply \var{function} of two arguments cumulatively to the items of
  \var{sequence}, from left to right, so as to reduce the sequence to
  a single value.  For example, \code{reduce(lambda x, y: x+y, [1, 2,
  3, 4, 5])} calculates \code{((((1+2)+3)+4)+5)}.  The left argument,
  \var{x}, is the accumulated value and the right argument, \var{y},
  is the update value from the \var{sequence}.  If the optional
  \var{initializer} is present, it is placed before the items of the
  sequence in the calculation, and serves as a default when the
  sequence is empty.  If \var{initializer} is not given and
  \var{sequence} contains only one item, the first item is returned.
\end{funcdesc}

\begin{funcdesc}{reload}{module}
  Reload a previously imported \var{module}.  The
  argument must be a module object, so it must have been successfully
  imported before.  This is useful if you have edited the module
  source file using an external editor and want to try out the new
  version without leaving the Python interpreter.  The return value is
  the module object (the same as the \var{module} argument).

  When \code{reload(module)} is executed:

\begin{itemize}

    \item Python modules' code is recompiled and the module-level code
    reexecuted, defining a new set of objects which are bound to names in
    the module's dictionary.  The \code{init} function of extension
    modules is not called a second time.

    \item As with all other objects in Python the old objects are only
    reclaimed after their reference counts drop to zero.

    \item The names in the module namespace are updated to point to
    any new or changed objects.

    \item Other references to the old objects (such as names external
    to the module) are not rebound to refer to the new objects and
    must be updated in each namespace where they occur if that is
    desired.

\end{itemize}

  There are a number of other caveats:

  If a module is syntactically correct but its initialization fails,
  the first \keyword{import} statement for it does not bind its name
  locally, but does store a (partially initialized) module object in
  \code{sys.modules}.  To reload the module you must first
  \keyword{import} it again (this will bind the name to the partially
  initialized module object) before you can \function{reload()} it.

  When a module is reloaded, its dictionary (containing the module's
  global variables) is retained.  Redefinitions of names will override
  the old definitions, so this is generally not a problem.  If the new
  version of a module does not define a name that was defined by the
  old version, the old definition remains.  This feature can be used
  to the module's advantage if it maintains a global table or cache of
  objects --- with a \keyword{try} statement it can test for the
  table's presence and skip its initialization if desired:

\begin{verbatim}
try:
    cache
except NameError:
    cache = {}
\end{verbatim}


  It is legal though generally not very useful to reload built-in or
  dynamically loaded modules, except for \refmodule{sys},
  \refmodule[main]{__main__} and \refmodule[builtin]{__builtin__}.  In
  many cases, however, extension modules are not designed to be
  initialized more than once, and may fail in arbitrary ways when
  reloaded.

  If a module imports objects from another module using \keyword{from}
  \ldots{} \keyword{import} \ldots{}, calling \function{reload()} for
  the other module does not redefine the objects imported from it ---
  one way around this is to re-execute the \keyword{from} statement,
  another is to use \keyword{import} and qualified names
  (\var{module}.\var{name}) instead.

  If a module instantiates instances of a class, reloading the module
  that defines the class does not affect the method definitions of the
  instances --- they continue to use the old class definition.  The
  same is true for derived classes.
\end{funcdesc}

\begin{funcdesc}{repr}{object}
  Return a string containing a printable representation of an object.
  This is the same value yielded by conversions (reverse quotes).
  It is sometimes useful to be able to access this operation as an
  ordinary function.  For many types, this function makes an attempt
  to return a string that would yield an object with the same value
  when passed to \function{eval()}.
\end{funcdesc}

\begin{funcdesc}{reversed}{seq}
  Return a reverse iterator.  \var{seq} must be an object which
  supports the sequence protocol (the __len__() method and the
  \method{__getitem__()} method with integer arguments starting at
  \code{0}).
  \versionadded{2.4}
\end{funcdesc}

\begin{funcdesc}{round}{x\optional{, n}}
  Return the floating point value \var{x} rounded to \var{n} digits
  after the decimal point.  If \var{n} is omitted, it defaults to zero.
  The result is a floating point number.  Values are rounded to the
  closest multiple of 10 to the power minus \var{n}; if two multiples
  are equally close, rounding is done away from 0 (so. for example,
  \code{round(0.5)} is \code{1.0} and \code{round(-0.5)} is \code{-1.0}).
\end{funcdesc}

\begin{funcdesc}{set}{\optional{iterable}}
  Return a set whose elements are taken from \var{iterable}.  The elements
  must be immutable.  To represent sets of sets, the inner sets should
  be \class{frozenset} objects.  If \var{iterable} is not specified,
  returns a new empty set, \code{set([])}.
  \versionadded{2.4}
\end{funcdesc}

\begin{funcdesc}{setattr}{object, name, value}
  This is the counterpart of \function{getattr()}.  The arguments are an
  object, a string and an arbitrary value.  The string may name an
  existing attribute or a new attribute.  The function assigns the
  value to the attribute, provided the object allows it.  For example,
  \code{setattr(\var{x}, '\var{foobar}', 123)} is equivalent to
  \code{\var{x}.\var{foobar} = 123}.
\end{funcdesc}

\begin{funcdesc}{slice}{\optional{start,} stop\optional{, step}}
  Return a slice object representing the set of indices specified by
  \code{range(\var{start}, \var{stop}, \var{step})}.  The \var{start}
  and \var{step} arguments default to \code{None}.  Slice objects have
  read-only data attributes \member{start}, \member{stop} and
  \member{step} which merely return the argument values (or their
  default).  They have no other explicit functionality; however they
  are used by Numerical Python\index{Numerical Python} and other third
  party extensions.  Slice objects are also generated when extended
  indexing syntax is used.  For example: \samp{a[start:stop:step]} or
  \samp{a[start:stop, i]}.
\end{funcdesc}

\begin{funcdesc}{sorted}{iterable\optional{, cmp\optional{,
                         key\optional{, reverse}}}}
  Return a new sorted list from the items in \var{iterable}.
  The optional arguments \var{cmp}, \var{key}, and \var{reverse}
  have the same meaning as those for the \method{list.sort()} method.
  \versionadded{2.4}
\end{funcdesc}

\begin{funcdesc}{staticmethod}{function}
  Return a static method for \var{function}.

  A static method does not receive an implicit first argument.
  To declare a static method, use this idiom:

\begin{verbatim}
class C:
    @staticmethod
    def f(arg1, arg2, ...): ...
\end{verbatim}

  The \code{@staticmethod} form is a function decorator -- see the description
  of function definitions in chapter 7 of the
  \citetitle[../ref/function.html]{Python Reference Manual} for details.

  It can be called either on the class (such as \code{C.f()}) or on an
  instance (such as \code{C().f()}).  The instance is ignored except
  for its class.

  Static methods in Python are similar to those found in Java or \Cpp.
  For a more advanced concept, see \function{classmethod()} in this
  section.
  
  For more information on static methods, consult the documentation on the
  standard type hierarchy in chapter 3 of the
  \citetitle[../ref/types.html]{Python Reference Manual} (at the bottom).
  \versionadded{2.2}
  \versionchanged[Function decorator syntax added]{2.4}
\end{funcdesc}

\begin{funcdesc}{str}{\optional{object}}
  Return a string containing a nicely printable representation of an
  object.  For strings, this returns the string itself.  The
  difference with \code{repr(\var{object})} is that
  \code{str(\var{object})} does not always attempt to return a string
  that is acceptable to \function{eval()}; its goal is to return a
  printable string.  If no argument is given, returns the empty
  string, \code{''}.
\end{funcdesc}

\begin{funcdesc}{sum}{sequence\optional{, start}}
  Sums \var{start} and the items of a \var{sequence}, from left to
  right, and returns the total.  \var{start} defaults to \code{0}.
  The \var{sequence}'s items are normally numbers, and are not allowed
  to be strings.  The fast, correct way to concatenate sequence of
  strings is by calling \code{''.join(\var{sequence})}.
  Note that \code{sum(range(\var{n}), \var{m})} is equivalent to
  \code{reduce(operator.add, range(\var{n}), \var{m})}
  \versionadded{2.3}
\end{funcdesc}

\begin{funcdesc}{super}{type\optional{, object-or-type}}
  Return the superclass of \var{type}.  If the second argument is omitted
  the super object returned is unbound.  If the second argument is an
  object, \code{isinstance(\var{obj}, \var{type})} must be true.  If
  the second argument is a type, \code{issubclass(\var{type2},
  \var{type})} must be true.
  \function{super()} only works for new-style classes.

  A typical use for calling a cooperative superclass method is:
\begin{verbatim}
class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)
\end{verbatim}

  Note that \function{super} is implemented as part of the binding process for
  explicit dotted attribute lookups such as
  \samp{super(C, self).__getitem__(name)}.  Accordingly, \function{super} is
  undefined for implicit lookups using statements or operators such as
  \samp{super(C, self)[name]}.
\versionadded{2.2}
\end{funcdesc}

\begin{funcdesc}{tuple}{\optional{sequence}}
  Return a tuple whose items are the same and in the same order as
  \var{sequence}'s items.  \var{sequence} may be a sequence, a
  container that supports iteration, or an iterator object.
  If \var{sequence} is already a tuple, it
  is returned unchanged.  For instance, \code{tuple('abc')} returns
  \code{('a', 'b', 'c')} and \code{tuple([1, 2, 3])} returns
  \code{(1, 2, 3)}.  If no argument is given, returns a new empty
  tuple, \code{()}.
\end{funcdesc}

\begin{funcdesc}{type}{object}
  Return the type of an \var{object}.  The return value is a
  type\obindex{type} object.  The \function{isinstance()} built-in
  function is recommended for testing the type of an object.

  With three arguments, \function{type} functions as a constructor
  as detailed below.
\end{funcdesc}

\begin{funcdesc}{type}{name, bases, dict}
  Return a new type object.  This is essentially a dynamic form of the
  \keyword{class} statement. The \var{name} string is the class name
  and becomes the \member{__name__} attribute; the \var{bases} tuple
  itemizes the base classes and becomes the \member{__bases__}
  attribute; and the \var{dict} dictionary is the namespace containing
  definitions for class body and becomes the \member{__dict__}
  attribute.  For example, the following two statements create
  identical \class{type} objects:

\begin{verbatim}
  >>> class X(object):
  ...     a = 1
  ...     
  >>> X = type('X', (object,), dict(a=1))
\end{verbatim}
\versionadded{2.2}          
\end{funcdesc}

\begin{funcdesc}{unichr}{i}
  Return the Unicode string of one character whose Unicode code is the
  integer \var{i}.  For example, \code{unichr(97)} returns the string
  \code{u'a'}.  This is the inverse of \function{ord()} for Unicode
  strings.  The valid range for the argument depends how Python was
  configured -- it may be either UCS2 [0..0xFFFF] or UCS4 [0..0x10FFFF].
  \exception{ValueError} is raised otherwise.
  \versionadded{2.0}
\end{funcdesc}

\begin{funcdesc}{unicode}{\optional{object\optional{, encoding
				    \optional{, errors}}}}
  Return the Unicode string version of \var{object} using one of the
  following modes:

  If \var{encoding} and/or \var{errors} are given, \code{unicode()}
  will decode the object which can either be an 8-bit string or a
  character buffer using the codec for \var{encoding}. The
  \var{encoding} parameter is a string giving the name of an encoding;
  if the encoding is not known, \exception{LookupError} is raised.
  Error handling is done according to \var{errors}; this specifies the
  treatment of characters which are invalid in the input encoding.  If
  \var{errors} is \code{'strict'} (the default), a
  \exception{ValueError} is raised on errors, while a value of
  \code{'ignore'} causes errors to be silently ignored, and a value of
  \code{'replace'} causes the official Unicode replacement character,
  \code{U+FFFD}, to be used to replace input characters which cannot
  be decoded.  See also the \refmodule{codecs} module.

  If no optional parameters are given, \code{unicode()} will mimic the
  behaviour of \code{str()} except that it returns Unicode strings
  instead of 8-bit strings. More precisely, if \var{object} is a
  Unicode string or subclass it will return that Unicode string without
  any additional decoding applied.

  For objects which provide a \method{__unicode__()} method, it will
  call this method without arguments to create a Unicode string. For
  all other objects, the 8-bit string version or representation is
  requested and then converted to a Unicode string using the codec for
  the default encoding in \code{'strict'} mode.

  \versionadded{2.0}
  \versionchanged[Support for \method{__unicode__()} added]{2.2}
\end{funcdesc}

\begin{funcdesc}{vars}{\optional{object}}
  Without arguments, return a dictionary corresponding to the current
  local symbol table.  With a module, class or class instance object
  as argument (or anything else that has a \member{__dict__}
  attribute), returns a dictionary corresponding to the object's
  symbol table.  The returned dictionary should not be modified: the
  effects on the corresponding symbol table are undefined.\footnote{
    In the current implementation, local variable bindings cannot
    normally be affected this way, but variables retrieved from
    other scopes (such as modules) can be.  This may change.}
\end{funcdesc}

\begin{funcdesc}{xrange}{\optional{start,} stop\optional{, step}}
  This function is very similar to \function{range()}, but returns an
  ``xrange object'' instead of a list.  This is an opaque sequence
  type which yields the same values as the corresponding list, without
  actually storing them all simultaneously.  The advantage of
  \function{xrange()} over \function{range()} is minimal (since
  \function{xrange()} still has to create the values when asked for
  them) except when a very large range is used on a memory-starved
  machine or when all of the range's elements are never used (such as
  when the loop is usually terminated with \keyword{break}).

  \note{\function{xrange()} is intended to be simple and fast.
        Implementations may impose restrictions to achieve this.
        The C implementation of Python restricts all arguments to
        native C longs ("short" Python integers), and also requires
        that the number of elements fit in a native C long.}
\end{funcdesc}

\begin{funcdesc}{zip}{\optional{iterable, \moreargs}}
  This function returns a list of tuples, where the \var{i}-th tuple contains
  the \var{i}-th element from each of the argument sequences or iterables.
  The returned list is truncated in length to the length of
  the shortest argument sequence.  When there are multiple arguments
  which are all of the same length, \function{zip()} is
  similar to \function{map()} with an initial argument of \code{None}.
  With a single sequence argument, it returns a list of 1-tuples.
  With no arguments, it returns an empty list.
  \versionadded{2.0}

  \versionchanged[Formerly, \function{zip()} required at least one argument
  and \code{zip()} raised a \exception{TypeError} instead of returning
  an empty list]{2.4}
\end{funcdesc}


% ---------------------------------------------------------------------------


\section{Non-essential Built-in Functions \label{non-essential-built-in-funcs}}

There are several built-in functions that are no longer essential to learn,
know or use in modern Python programming.  They have been kept here to
maintain backwards compatibility with programs written for older versions
of Python.

Python programmers, trainers, students and bookwriters should feel free to
bypass these functions without concerns about missing something important.


\setindexsubitem{(non-essential built-in functions)}

\begin{funcdesc}{buffer}{object\optional{, offset\optional{, size}}}
  The \var{object} argument must be an object that supports the buffer
  call interface (such as strings, arrays, and buffers).  A new buffer
  object will be created which references the \var{object} argument.
  The buffer object will be a slice from the beginning of \var{object}
  (or from the specified \var{offset}). The slice will extend to the
  end of \var{object} (or will have a length given by the \var{size}
  argument).
\end{funcdesc}

\begin{funcdesc}{coerce}{x, y}
  Return a tuple consisting of the two numeric arguments converted to
  a common type, using the same rules as used by arithmetic
  operations. If coercion is not possible, raise \exception{TypeError}.
\end{funcdesc}

\begin{funcdesc}{intern}{string}
  Enter \var{string} in the table of ``interned'' strings and return
  the interned string -- which is \var{string} itself or a copy.
  Interning strings is useful to gain a little performance on
  dictionary lookup -- if the keys in a dictionary are interned, and
  the lookup key is interned, the key comparisons (after hashing) can
  be done by a pointer compare instead of a string compare.  Normally,
  the names used in Python programs are automatically interned, and
  the dictionaries used to hold module, class or instance attributes
  have interned keys.  \versionchanged[Interned strings are not
  immortal (like they used to be in Python 2.2 and before);
  you must keep a reference to the return value of \function{intern()}
  around to benefit from it]{2.3}
\end{funcdesc}
