\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}}}}
  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(), [])}; the statement \samp{from spam.ham import eggs}
  results in \samp{__import__('spam.ham', globals(), locals(),
  ['eggs'])}.  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}
\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.
  \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.

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

  The \function{file()} constructor is new in Python 2.2 and is an
  alias for \function{open()}.  Both spellings are equivalent.  The
  intent is for \function{open()} to continue to be preferred for use
  as a factory function which returns a new \class{file} object.  The
  spelling, \class{file} is more suited to type testing (for example,
  writing \samp{isinstance(f, file)}).
\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}{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 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...}}
  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.  \function{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}}}
  An alias for the \function{file()} function above.
\end{funcdesc}

\begin{funcdesc}{ord}{c}
  Return the \ASCII{} value of a string of one character or a Unicode
  character.  E.g., \code{ord('a')} returns the integer \code{97},
  \code{ord(u'\e u2020')} returns \code{8224}.  This is the inverse of
  \function{chr()} for strings and of \function{unichr()} for Unicode
  characters.
\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
  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 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}

  \versionadded{2.2}
\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 largest \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, 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/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.

  Static methods in Python are similar to those found in Java or \Cpp.
  For a more advanced concept, see \function{classmethod()} in this
  section.
  \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 standard module
  \module{types}\refstmodindex{types} defines names for all built-in
  types that don't already have built-in names.
  For instance:

\begin{verbatim}
>>> import types
>>> x = 'abc'
>>> if type(x) is str: print "It's a string"
...
It's a string
>>> def f(): pass
...
>>> if type(f) is types.FunctionType: print "It's a function"
...
It's a function
\end{verbatim}

  The \function{isinstance()} built-in function is recommended for
  testing the type of an object.
\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 argument must be in the range [0..65535], inclusive.
  \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{seq1, \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.
  The returned list is truncated in length to the length of
  the shortest argument sequence.  When there are multiple argument
  sequences 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 compatability 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 equivalent
  to \code{\var{function}(*\var{args}, **\var{keywords})}.
  Use of \function{apply()} is not necessary since the ``extended call
  syntax,'' as used in the last example, is completely equivalent.

  \deprecated{2.3}{Use the extended call syntax instead, as described
                   above.}
\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}
