\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{arg}}
  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 \var{arg} 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}}}
  Constructor function for the \class{file} type, described further 
  in section~\ref{bltin-file-objects}, ``\ulink{File
  Objects}{bltin-file-objects.html}''.  The constructor's arguments
  are the same as those of the \function{open()} built-in function
  described below.

  When opening a file, it's preferable to use \function{open()} instead of 
  invoking this constructor directly.  \class{file} is more suited to
  type testing (for example, writing \samp{isinstance(f, file)}).

  \versionadded{2.2}
\end{funcdesc}

\begin{funcdesc}{filter}{function, iterable}
  Construct a list from those elements of \var{iterable} for which
  \var{function} returns true.  \var{iterable} may be either a sequence, a
  container which supports iteration, or an iterator,  If \var{iterable}
  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{iterable} that are false are removed.

  Note that \code{filter(function, \var{iterable})} is equivalent to
  \code{[item for item in \var{iterable} if function(item)]} if function is
  not \code{None} and \code{[item for item in \var{iterable} 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}{input}{\optional{prompt}}
  Equivalent to \code{eval(raw_input(\var{prompt}))}.
  \warning{This function is not safe from user errors!  It
  expects a valid Python expression as input; if the input is not
  syntactically valid, a \exception{SyntaxError} will be raised.
  Other exceptions may be raised if there is an error during
  evaluation.  (On the other hand, sometimes this is exactly what you
  need when writing a quick script for expert use.)}

  If the \refmodule{readline} module was loaded, then
  \function{input()} will use it to provide elaborate line editing and
  history features.

  Consider using the \function{raw_input()} function for general input
  from users.
\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 (which is 10 by default) 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
  (new-style class) and \var{object} is an object of that type or of a
  (direct or indirect) subclass thereof.  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{iterable}}
  Return a list whose items are the same and in the same order as
  \var{iterable}'s items.  \var{iterable} may be either a sequence, a
  container that supports iteration, or an iterator object.  If
  \var{iterable} is already a list, a copy is made and returned,
  similar to \code{\var{iterable}[:]}.  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, iterable, ...}
  Apply \var{function} to every item of \var{iterable} and return a list
  of the results.  If additional \var{iterable} arguments are passed,
  \var{function} must take that many arguments and is applied to the
  items from all iterables in parallel.  If one iterable 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 arguments, \function{map()} returns a list consisting
  of tuples containing the corresponding items from all iterables (a kind
  of transpose operation).  The \var{iterable} arguments may be a sequence 
  or any iterable object; the result is always a list.
\end{funcdesc}

\begin{funcdesc}{max}{iterable\optional{, args...}\optional{key}}
  With a single argument \var{iterable}, return the largest item of a
  non-empty iterable (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}{iterable\optional{, args...}\optional{key}}
  With a single argument \var{iterable}, return the smallest item of a
  non-empty iterable (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}}}
  Open a file, returning an object of the \class{file} type described
  in section~\ref{bltin-file-objects}, ``\ulink{File
  Objects}{bltin-file-objects.html}''.  If the file cannot be opened,
  \exception{IOError} is raised.  When opening a file, it's
  preferable to use \function{open()} instead of invoking the
  \class{file} constructor directly.

  The first two arguments are the same as for \code{stdio}'s
  \cfunction{fopen()}: \var{filename} is the file name to be opened,
  and \var{mode} is a string indicating how the file is to be opened.

  The most commonly-used values of \var{mode} are \code{'r'} for
  reading, \code{'w'} for writing (truncating the file if it already
  exists), and \code{'a'} 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).  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 to open the file in binary
  mode, which will improve portability.  (Appending \code{'b'} is
  useful even on systems that don't treat binary and text files
  differently, where it serves as documentation.)  See below for more
  possible values of \var{mode}.

  \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.}

  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; on systems
  that don't have this distinction, adding the \code{'b'} has no effect.
  
  In addition to the standard \cfunction{fopen()} values \var{mode}
  may be \code{'U'} or \code{'rU'}.  Python is usually built with universal
  newline support; supplying \code{'U'} opens the file as a text file, but
  lines may be terminated by any of the following: the \UNIX{} end-of-line
  convention \code{'\e n'}, 
  the Macintosh convention \code{'\e r'}, or the Windows
  convention \code{'\e r\e n'}. All of these external representations are seen as
  \code{'\e n'}
  by the Python program. If Python is built without universal newline support
  a \var{mode} with \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'}.

  \versionchanged[Restriction on first letter of mode string
                  introduced]{2.5}
\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).  This makes it possible to create read-only properties
  easily using \function{property()} as a decorator:

\begin{verbatim}
class Parrot(object):
    def __init__(self):
        self._voltage = 100000

    @property
    def voltage(self):
        """Get the current voltage."""
        return self._voltage
\end{verbatim}

  turns the \method{voltage()} method into a ``getter'' for a read-only
  attribute with the same name.

  \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}{raw_input}{\optional{prompt}}
  If the \var{prompt} argument is present, it is written to standard output
  without a trailing newline.  The function then reads a line from input,
  converts it to a string (stripping a trailing newline), and returns that.
  When \EOF{} is read, \exception{EOFError} is raised. Example:

\begin{verbatim}
>>> s = raw_input('--> ')
--> Monty Python's Flying Circus
>>> s
"Monty Python's Flying Circus"
\end{verbatim}

  If the \refmodule{readline} module was loaded, then
  \function{raw_input()} will use it to provide elaborate
  line editing and history features.
\end{funcdesc}

\begin{funcdesc}{reduce}{function, iterable\optional{, initializer}}
  Apply \var{function} of two arguments cumulatively to the items of
  \var{iterable}, from left to right, so as to reduce the iterable 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{iterable}.  If the optional
  \var{initializer} is present, it is placed before the items of the
  iterable in the calculation, and serves as a default when the
  iterable is empty.  If \var{initializer} is not given and
  \var{iterable} 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 \method{__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
  (described in section~\ref{typesseq-mutable}).

  \var{cmp} specifies a custom comparison function of two arguments
  (iterable elements) which should return a negative, zero or positive
  number depending on whether the first argument is considered smaller
  than, equal to, or larger than the second argument:
  \samp{\var{cmp}=\keyword{lambda} \var{x},\var{y}:
  \function{cmp}(x.lower(), y.lower())}
     
  \var{key} specifies a function of one argument that is used to
     extract a comparison key from each list element:
     \samp{\var{key}=\function{str.lower}}

  \var{reverse} is a boolean value.  If set to \code{True}, then the
     list elements are sorted as if each comparison were reversed.

  In general, the \var{key} and \var{reverse} conversion processes are
  much faster than specifying an equivalent \var{cmp} function.  This is
  because \var{cmp} is called multiple times for each list element while
  \var{key} and \var{reverse} touch each element only once.

  \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}{iterable\optional{, start}}
  Sums \var{start} and the items of an \var{iterable} from left to
  right and returns the total.  \var{start} defaults to \code{0}.
  The \var{iterable}'s items are normally numbers, and are not allowed
  to be strings.  The fast, correct way to concatenate a 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{iterable}}
  Return a tuple whose items are the same and in the same order as
  \var{iterable}'s items.  \var{iterable} may be a sequence, a
  container that supports iteration, or an iterator object.
  If \var{iterable} 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}{apply}{function, args\optional{, keywords}}
  The \var{function} argument must be a callable object (a
  user-defined or built-in function or method, or a class object) and
  the \var{args} argument must be a sequence.  The \var{function} is
  called with \var{args} as the argument list; the number of arguments
  is the length of the tuple.
  If the optional \var{keywords} argument is present, it must be a
  dictionary whose keys are strings.  It specifies keyword arguments
  to be added to the end of the argument list.
  Calling \function{apply()} is different from just calling
  \code{\var{function}(\var{args})}, since in that case there is always
  exactly one argument.  The use of \function{apply()} is exactly
  equivalent to \code{\var{function}(*\var{args}, **\var{keywords})}.

  \deprecated{2.3}{Use the extended call syntax with \code{*args}
  and \code{**keywords} instead.}
\end{funcdesc}

\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}
