Commits

Robert Kern committed 6c49bc9

Initial commit.

Comments (0)

Files changed (10)

_line_profiler.pyx

+from python25 cimport PyFrameObject, PyObject, PyStringObject
+
+from cProfile import label
+
+cdef extern from "frameobject.h":
+    ctypedef int (*Py_tracefunc)(object self, PyFrameObject *py_frame, int what, object arg)
+
+cdef extern from "Python.h":
+    ctypedef long long PY_LONG_LONG
+    cdef bint PyCFunction_Check(object obj)
+
+    cdef void PyEval_SetProfile(Py_tracefunc func, object arg)
+    cdef void PyEval_SetTrace(Py_tracefunc func, object arg)
+
+    ctypedef object (*PyCFunction)(object self, object args)
+
+    ctypedef struct PyMethodDef:
+        char *ml_name
+        PyCFunction ml_meth
+        int ml_flags
+        char *ml_doc
+
+    ctypedef struct PyCFunctionObject:
+        PyMethodDef *m_ml
+        PyObject *m_self
+        PyObject *m_module
+
+    # They're actually #defines, but whatever.
+    cdef int PyTrace_CALL
+    cdef int PyTrace_EXCEPTION
+    cdef int PyTrace_LINE
+    cdef int PyTrace_RETURN
+    cdef int PyTrace_C_CALL
+    cdef int PyTrace_C_EXCEPTION
+    cdef int PyTrace_C_RETURN
+
+cdef extern from "timers.h":
+    PY_LONG_LONG hpTimer()
+    double hpTimerUnit()
+
+
+cdef class LineTiming:
+    """ The timing for a single line.
+    """
+    cdef public object code
+    cdef public int lineno
+    cdef public PY_LONG_LONG total_time
+    cdef public long nhits
+
+    def __init__(self, object code, int lineno):
+        self.code = code
+        self.lineno = lineno
+        self.total_time = 0
+        self.nhits = 0
+
+    def hit(self, PY_LONG_LONG dt):
+        """ Record a line timing.
+        """
+        self.nhits += 1
+        self.total_time += dt
+
+    def astuple(self):
+        """ Convert to a tuple of (lineno, nhits, total_time).
+        """
+        return (self.lineno, self.nhits, <long>self.total_time)
+
+    def __repr__(self):
+        return '<LineTiming for %r\n  lineno: %r\n  nhits: %r\n  total_time: %r>' % (self.code, self.lineno, self.nhits, <long>self.total_time)
+
+
+cdef class LineProfiler:
+    """ Time the execution of lines of Python code.
+    """
+    cdef public object functions
+    cdef public object code_map
+    cdef public object last_time
+    cdef public double timer_unit
+    cdef public long enable_count
+
+    def __init__(self, *functions):
+        self.functions = []
+        self.code_map = {}
+        self.last_time = {}
+        self.timer_unit = hpTimerUnit()
+        self.enable_count = 0
+        for func in functions:
+            self.add_function(func)
+
+    def add_function(self, func):
+        code = func.func_code
+        if code not in self.code_map:
+            self.code_map[code] = {}
+            self.functions.append(func)
+
+    def enable_by_count(self):
+        """ Enable the profiler if it hasn't been enabled before.
+        """
+        if self.enable_count == 0:
+            self.enable()
+        self.enable_count += 1
+
+    def disable_by_count(self):
+        """ Disable the profiler if the number of disable requests matches the
+        number of enable requests.
+        """
+        if self.enable_count > 0:
+            self.enable_count -= 1
+            if self.enable_count == 0:
+                self.disable()
+
+    def __enter__(self):
+        self.enable_by_count()
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.disable_by_count()
+
+    def enable(self):
+        PyEval_SetTrace(python_trace_callback, self)
+
+    def disable(self):
+        self.last_time = {}
+        PyEval_SetTrace(NULL, <object>NULL)
+
+    def get_stats(self):
+        """ Return a serializable dictionary of the profiling data along with
+        the timer unit.
+
+        Returns
+        -------
+        stats : dict
+            Mapping from (filename, first_lineno, function_name) of the profiled
+            function to a list of (lineno, nhits, total_time) tuples for each
+            profiled line. total_time is an integer in the native units of the
+            timer.
+        timer_unit : float
+            The number of seconds per timer unit.
+        """
+        stats = {}
+        for code in self.code_map:
+            entries = self.code_map[code].values()
+            key = label(code)
+            stats[key] = [e.astuple() for e in entries]
+            stats[key].sort()
+        return stats, self.timer_unit
+
+
+cdef class LastTime:
+    """ Record the last callback call for a given line.
+    """
+    cdef int f_lineno
+    cdef PY_LONG_LONG time
+
+    def __cinit__(self, int f_lineno, PY_LONG_LONG time):
+        self.f_lineno = f_lineno
+        self.time = time
+
+
+cdef int python_trace_callback(object self, PyFrameObject *py_frame, int what,
+    object arg):
+    """ The PyEval_SetTrace() callback.
+    """
+    cdef object code, line_entries, key
+    cdef LineTiming entry
+    cdef LastTime old
+    cdef PY_LONG_LONG time
+
+    if what == PyTrace_LINE or what == PyTrace_RETURN:
+        code = <object>py_frame.f_code
+        if code in self.code_map:
+            time = hpTimer()
+            if code in self.last_time:
+                old = self.last_time[code]
+                line_entries = self.code_map[code]
+                key = old.f_lineno
+                if key not in line_entries:
+                    entry = LineTiming(code, old.f_lineno)
+                    line_entries[key] = entry
+                else:
+                    entry = line_entries[key]
+                entry.hit(time - old.time)
+            if what == PyTrace_LINE:
+                # Get the time again. This way, we don't record much time wasted
+                # in this function.
+                self.last_time[code] = LastTime(py_frame.f_lineno, hpTimer())
+            else:
+                # We are returning from a function, not executing a line. Delete
+                # the last_time record.
+                del self.last_time[code]
+
+    return 0
+
+
+from cProfile import label
+import marshal
+
+from _line_profiler import LineProfiler as CLineProfiler
+
+
+class LineProfiler(CLineProfiler):
+    """ A subclass of the C version solely to provide a decorator since Cython
+    does not have closures.
+    """
+
+    def __call__(self, func):
+        """ Decorate a function to start the profiler on function entry and stop
+        it on function exit.
+        """
+        def f(*args, **kwds):
+            self.add_function(func)
+            self.enable_by_count()
+            try:
+                result = func(*args, **kwds)
+            finally:
+                self.disable_by_count()
+            return result
+        f.__name__ = func.__name__
+        f.__doc__ = func.__doc__
+        f.__dict__.update(func.__dict__)
+        return f
+
+    def dump_stats(self, filename):
+        """ Dump a representation of the data to a file as a marshalled
+        dictionary from `get_stats()`.
+        """
+        stats = self.get_stats()
+        f = open(filename, 'wb')
+        try:
+            marshal.dump(stats, f)
+        finally:
+            f.close()
+
+import pystone
+
+from line_profiler import LineProfiler
+
+
+lp = LineProfiler(pystone.Proc0)
+lp.enable()
+pystone.pystones()
+lp.disable()
+code = lp.code_map.keys()[0]
+
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+""" Script to conveniently run the profiler on code in a variety of
+circumstances.
+"""
+
+import cProfile
+import optparse
+import os
+import sys
+
+def find_script(script_name):
+    """ Find the script.
+
+    If the input is not a file, then $PATH will be searched.
+    """
+    if os.path.isfile(script_name):
+        return script_name
+    path = os.getenv('PATH', os.defpath).split(os.pathsep)
+    for dir in path:
+        if dir == '':
+            continue
+        fn = os.path.join(dir, script_name)
+        if os.path.isfile(fn):
+            return fn
+
+    print >>sys.stderr, 'Could not find script %s' % script_name
+    raise SystemExit(1)
+
+class ContextualProfile(cProfile.Profile):
+    """ A subclass of cProfile.Profile that adds a context manager for Python
+    2.5 with: statements and a decorator.
+    """
+
+    def __init__(self, *args, **kwds):
+        super(ContextualProfile, self).__init__(*args, **kwds)
+        self.enable_count = 0
+
+    def enable_by_count(self, subcalls=True, builtins=True):
+        """ Enable the profiler if it hasn't been enabled before.
+        """
+        if self.enable_count == 0:
+            self.enable(subcalls=subcalls, builtins=builtins)
+        self.enable_count += 1
+
+    def disable_by_count(self):
+        """ Disable the profiler if the number of disable requests matches the
+        number of enable requests.
+        """
+        if self.enable_count > 0:
+            self.enable_count -= 1
+            if self.enable_count == 0:
+                self.disable()
+
+    def __call__(self, func):
+        """ Decorate a function to start the profiler on function entry and stop
+        it on function exit.
+        """
+        def f(*args, **kwds):
+            self.enable_by_count()
+            try:
+                result = func(*args, **kwds)
+            finally:
+                self.disable_by_count()
+            return result
+        f.__name__ = func.__name__
+        f.__doc__ = func.__doc__
+        f.__dict__.update(func.__dict__)
+        return f
+
+    def __enter__(self):
+        self.enable_by_count()
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.disable_by_count()
+
+
+def main(args):
+    usage = "%s [-s setupfile] [-o output_file_path] scriptfile [arg] ..."
+    parser = optparse.OptionParser(usage=usage % sys.argv[0])
+    parser.allow_interspersed_args = False
+    parser.add_option('-l', '--line-by-line', action='store_true',
+        help="Use the line-by-line profiler from the line_profiler module "
+        "instead of cProfile. Implies --builtin.")
+    parser.add_option('-b', '--builtin', action='store_true',
+        help="Put 'profile' in the builtins. Use 'profile.enable()' and "
+            "'profile.disable()' in your code to turn it on and off, or "
+            "'@profile' to decorate a single function, or 'with profile:' "
+            "to profile a single section of code.")
+    parser.add_option('-o', '--outfile', default=None,
+        help="Save stats to <outfile>")
+    parser.add_option('-s', '--setup', default=None,
+       help="Code to execute before the code to profile")
+
+    if not sys.argv[1:]:
+        parser.print_usage()
+        sys.exit(2)
+
+    options, args = parser.parse_args()
+
+    if not options.outfile:
+        options.outfile = '%s.prof' % os.path.basename(args[0])
+
+    sys.argv[:] = args
+    if options.setup is not None:
+        # Run some setup code outside of the profiler. This is good for large
+        # imports.
+        setup_file = find_script(options.setup)
+        __file__ = setup_file
+        __name__ = '__main__'
+        # Make sure the script's directory is on sys.path instead of just
+        # lsprof.py's.
+        sys.path.insert(0, os.path.dirname(setup_file))
+        execfile(setup_file)
+
+    script_file = find_script(sys.argv[0])
+    __file__ = script_file
+    __name__ = '__main__'
+    # Make sure the script's directory is on sys.path instead of just
+    # lsprof.py's.
+    sys.path.insert(0, os.path.dirname(script_file))
+
+    if options.line_by_line:
+        import line_profiler
+        prof = line_profiler.LineProfiler()
+        options.builtin = True
+    else:
+        prof = ContextualProfile()
+    if options.builtin:
+        import __builtin__
+        __builtin__.__dict__['profile'] = prof
+
+    try:
+        try:
+            if options.builtin:
+                execfile(script_file)
+            else:
+                prof.run('execfile(%r)' % (script_file,))
+        except (KeyboardInterrupt, SystemExit):
+            pass
+    finally:
+        prof.dump_stats(options.outfile)
+        print 'Wrote profile results to %s' % options.outfile
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
+
+#!/usr/bin/env python
+
+import os
+import pystone
+
+#import lineprof
+
+print os.getpid()
+#lineprof.enable()
+
+while True:
+    pystone.pystones()
+#! /usr/bin/env python
+
+"""
+"PYSTONE" Benchmark Program
+
+Version:        Python/1.1 (corresponds to C/1.1 plus 2 Pystone fixes)
+
+Author:         Reinhold P. Weicker,  CACM Vol 27, No 10, 10/84 pg. 1013.
+
+                Translated from ADA to C by Rick Richardson.
+                Every method to preserve ADA-likeness has been used,
+                at the expense of C-ness.
+
+                Translated from C to Python by Guido van Rossum.
+
+Version History:
+
+                Version 1.1 corrects two bugs in version 1.0:
+
+                First, it leaked memory: in Proc1(), NextRecord ends
+                up having a pointer to itself.  I have corrected this
+                by zapping NextRecord.PtrComp at the end of Proc1().
+
+                Second, Proc3() used the operator != to compare a
+                record to None.  This is rather inefficient and not
+                true to the intention of the original benchmark (where
+                a pointer comparison to None is intended; the !=
+                operator attempts to find a method __cmp__ to do value
+                comparison of the record).  Version 1.1 runs 5-10
+                percent faster than version 1.0, so benchmark figures
+                of different versions can't be compared directly.
+
+"""
+
+LOOPS = 50000
+
+from time import clock
+
+__version__ = "1.1"
+
+[Ident1, Ident2, Ident3, Ident4, Ident5] = range(1, 6)
+
+class Record:
+
+    def __init__(self, PtrComp = None, Discr = 0, EnumComp = 0,
+                       IntComp = 0, StringComp = 0):
+        self.PtrComp = PtrComp
+        self.Discr = Discr
+        self.EnumComp = EnumComp
+        self.IntComp = IntComp
+        self.StringComp = StringComp
+
+    def copy(self):
+        return Record(self.PtrComp, self.Discr, self.EnumComp,
+                      self.IntComp, self.StringComp)
+
+TRUE = 1
+FALSE = 0
+
+def main(loops=LOOPS):
+    benchtime, stones = pystones(loops)
+    print "Pystone(%s) time for %d passes = %g" % \
+          (__version__, loops, benchtime)
+    print "This machine benchmarks at %g pystones/second" % stones
+
+
+def pystones(loops=LOOPS):
+    return Proc0(loops)
+
+IntGlob = 0
+BoolGlob = FALSE
+Char1Glob = '\0'
+Char2Glob = '\0'
+Array1Glob = [0]*51
+Array2Glob = map(lambda x: x[:], [Array1Glob]*51)
+PtrGlb = None
+PtrGlbNext = None
+
+@profile
+def Proc0(loops=LOOPS):
+    global IntGlob
+    global BoolGlob
+    global Char1Glob
+    global Char2Glob
+    global Array1Glob
+    global Array2Glob
+    global PtrGlb
+    global PtrGlbNext
+
+    starttime = clock()
+    for i in range(loops):
+        pass
+    nulltime = clock() - starttime
+
+    PtrGlbNext = Record()
+    PtrGlb = Record()
+    PtrGlb.PtrComp = PtrGlbNext
+    PtrGlb.Discr = Ident1
+    PtrGlb.EnumComp = Ident3
+    PtrGlb.IntComp = 40
+    PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING"
+    String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING"
+    Array2Glob[8][7] = 10
+
+    starttime = clock()
+
+    for i in range(loops):
+        Proc5()
+        Proc4()
+        IntLoc1 = 2
+        IntLoc2 = 3
+        String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING"
+        EnumLoc = Ident2
+        BoolGlob = not Func2(String1Loc, String2Loc)
+        while IntLoc1 < IntLoc2:
+            IntLoc3 = 5 * IntLoc1 - IntLoc2
+            IntLoc3 = Proc7(IntLoc1, IntLoc2)
+            IntLoc1 = IntLoc1 + 1
+        Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3)
+        PtrGlb = Proc1(PtrGlb)
+        CharIndex = 'A'
+        while CharIndex <= Char2Glob:
+            if EnumLoc == Func1(CharIndex, 'C'):
+                EnumLoc = Proc6(Ident1)
+            CharIndex = chr(ord(CharIndex)+1)
+        IntLoc3 = IntLoc2 * IntLoc1
+        IntLoc2 = IntLoc3 / IntLoc1
+        IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1
+        IntLoc1 = Proc2(IntLoc1)
+
+    benchtime = clock() - starttime - nulltime
+    return benchtime, (loops / benchtime)
+
+def Proc1(PtrParIn):
+    PtrParIn.PtrComp = NextRecord = PtrGlb.copy()
+    PtrParIn.IntComp = 5
+    NextRecord.IntComp = PtrParIn.IntComp
+    NextRecord.PtrComp = PtrParIn.PtrComp
+    NextRecord.PtrComp = Proc3(NextRecord.PtrComp)
+    if NextRecord.Discr == Ident1:
+        NextRecord.IntComp = 6
+        NextRecord.EnumComp = Proc6(PtrParIn.EnumComp)
+        NextRecord.PtrComp = PtrGlb.PtrComp
+        NextRecord.IntComp = Proc7(NextRecord.IntComp, 10)
+    else:
+        PtrParIn = NextRecord.copy()
+    NextRecord.PtrComp = None
+    return PtrParIn
+
+def Proc2(IntParIO):
+    IntLoc = IntParIO + 10
+    while 1:
+        if Char1Glob == 'A':
+            IntLoc = IntLoc - 1
+            IntParIO = IntLoc - IntGlob
+            EnumLoc = Ident1
+        if EnumLoc == Ident1:
+            break
+    return IntParIO
+
+def Proc3(PtrParOut):
+    global IntGlob
+
+    if PtrGlb is not None:
+        PtrParOut = PtrGlb.PtrComp
+    else:
+        IntGlob = 100
+    PtrGlb.IntComp = Proc7(10, IntGlob)
+    return PtrParOut
+
+def Proc4():
+    global Char2Glob
+
+    BoolLoc = Char1Glob == 'A'
+    BoolLoc = BoolLoc or BoolGlob
+    Char2Glob = 'B'
+
+def Proc5():
+    global Char1Glob
+    global BoolGlob
+
+    Char1Glob = 'A'
+    BoolGlob = FALSE
+
+def Proc6(EnumParIn):
+    EnumParOut = EnumParIn
+    if not Func3(EnumParIn):
+        EnumParOut = Ident4
+    if EnumParIn == Ident1:
+        EnumParOut = Ident1
+    elif EnumParIn == Ident2:
+        if IntGlob > 100:
+            EnumParOut = Ident1
+        else:
+            EnumParOut = Ident4
+    elif EnumParIn == Ident3:
+        EnumParOut = Ident2
+    elif EnumParIn == Ident4:
+        pass
+    elif EnumParIn == Ident5:
+        EnumParOut = Ident3
+    return EnumParOut
+
+def Proc7(IntParI1, IntParI2):
+    IntLoc = IntParI1 + 2
+    IntParOut = IntParI2 + IntLoc
+    return IntParOut
+
+def Proc8(Array1Par, Array2Par, IntParI1, IntParI2):
+    global IntGlob
+
+    IntLoc = IntParI1 + 5
+    Array1Par[IntLoc] = IntParI2
+    Array1Par[IntLoc+1] = Array1Par[IntLoc]
+    Array1Par[IntLoc+30] = IntLoc
+    for IntIndex in range(IntLoc, IntLoc+2):
+        Array2Par[IntLoc][IntIndex] = IntLoc
+    Array2Par[IntLoc][IntLoc-1] = Array2Par[IntLoc][IntLoc-1] + 1
+    Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc]
+    IntGlob = 5
+
+def Func1(CharPar1, CharPar2):
+    CharLoc1 = CharPar1
+    CharLoc2 = CharLoc1
+    if CharLoc2 != CharPar2:
+        return Ident1
+    else:
+        return Ident2
+
+def Func2(StrParI1, StrParI2):
+    IntLoc = 1
+    while IntLoc <= 1:
+        if Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1:
+            CharLoc = 'A'
+            IntLoc = IntLoc + 1
+    if CharLoc >= 'W' and CharLoc <= 'Z':
+        IntLoc = 7
+    if CharLoc == 'X':
+        return TRUE
+    else:
+        if StrParI1 > StrParI2:
+            IntLoc = IntLoc + 7
+            return TRUE
+        else:
+            return FALSE
+
+def Func3(EnumParIn):
+    EnumLoc = EnumParIn
+    if EnumLoc == Ident3: return TRUE
+    return FALSE
+
+if __name__ == '__main__':
+    import sys
+    def error(msg):
+        print >>sys.stderr, msg,
+        print >>sys.stderr, "usage: %s [number_of_loops]" % sys.argv[0]
+        sys.exit(100)
+    nargs = len(sys.argv) - 1
+    if nargs > 1:
+        error("%d arguments are too many;" % nargs)
+    elif nargs == 1:
+        try: loops = int(sys.argv[1])
+        except ValueError:
+            error("Invalid argument %r;" % sys.argv[1])
+    else:
+        loops = LOOPS
+    main(loops)
+# From: Eric Huss <e-huss@netmeridian.com>
+#
+# Here is my latest copy.  It does not cover 100% of the API.  It should be
+# current up to 2.5.
+#
+# -Eric
+
+
+
+
+# XXX:
+# - Need to support "long long" definitions that are different for different platforms.
+# - Support unicode platform dependencies.
+# - Add unicode calls.
+# - Add setobject calls.
+
+cdef extern from "sys/types.h":
+    ctypedef unsigned int size_t
+
+cdef extern from "stdio.h":
+    ctypedef struct FILE:
+        pass
+
+cdef extern from "Python.h":
+
+    # XXX: This is platform dependent.
+    ctypedef unsigned short Py_UNICODE
+
+    ctypedef struct PyTypeObject:
+        pass
+
+    ctypedef struct PyObject:
+        Py_ssize_t ob_refcnt
+        PyTypeObject * ob_type
+
+    ###############################################################################################
+    # bool
+    ###############################################################################################
+    PyObject * Py_False
+    PyObject * Py_True
+    PyTypeObject PyBool_Type
+    int                 PyBool_Check                    (object)                    # Always succeeds.
+    object              PyBool_FromLong                 (long)
+
+    ###############################################################################################
+    # buffer
+    ###############################################################################################
+    PyTypeObject PyBuffer_Type
+    int Py_END_OF_BUFFER
+    int                 PyBuffer_Check                  (object)                    # Always succeeds.
+    object              PyBuffer_FromMemory             (void *, Py_ssize_t)
+    object              PyBuffer_FromObject             (object, Py_ssize_t, Py_ssize_t)
+    object              PyBuffer_FromReadWriteMemory    (void *, Py_ssize_t)
+    object              PyBuffer_FromReadWriteObject    (object, Py_ssize_t, Py_ssize_t)
+    object              PyBuffer_New                    (Py_ssize_t)
+    int                 PyObject_AsCharBuffer           (object, char **, Py_ssize_t *)    except -1
+    int                 PyObject_AsReadBuffer           (object, void **, Py_ssize_t *)    except -1
+    int                 PyObject_AsWriteBuffer          (object, void **, Py_ssize_t *)    except -1
+    int                 PyObject_CheckReadBuffer        (object)                    # Always succeeds.
+
+    ###############################################################################################
+    # cobject
+    ###############################################################################################
+    PyTypeObject PyCObject_Type
+
+    int                 PyCObject_Check(object)                                     # Always succeeds.
+    object              PyCObject_FromVoidPtr(void *, void (*)(void*))
+    object              PyCObject_FromVoidPtrAndDesc(void *, void *, void (*)(void*,void*))
+    void *              PyCObject_AsVoidPtr(object)                                 except NULL
+    void *              PyCObject_GetDesc(object)                                   except NULL
+    void *              PyCObject_Import(char *, char *)                            except NULL
+
+    ###############################################################################################
+    # compile
+    ###############################################################################################
+
+    ctypedef struct PyCodeObject:
+        int       co_argcount
+        int       co_nlocals
+        int       co_stacksize
+        int       co_flags
+        PyObject *co_code
+        PyObject *co_consts
+        PyObject *co_names
+        PyObject *co_varnames
+        PyObject *co_freevars
+        PyObject *co_cellvars
+        PyObject *co_filename
+        PyObject *co_name
+        int       co_firstlineno
+        PyObject *co_lnotab
+
+    int PyCode_Addr2Line(PyCodeObject *, int)
+
+    ###############################################################################################
+    # complex
+    ###############################################################################################
+    ctypedef struct Py_complex:
+        double real
+        double imag
+
+    PyTypeObject PyComplex_Type
+
+    Py_complex          PyComplex_AsCComplex            (object)                    # Always succeeds.
+    int                 PyComplex_Check                 (object)                    # Always succeeds.
+    int                 PyComplex_CheckExact            (object)                    # Always succeeds.
+    object              PyComplex_FromCComplex          (Py_complex)
+    object              PyComplex_FromDoubles           (double, double)
+    double              PyComplex_ImagAsDouble          (object)                    except? -1
+    double              PyComplex_RealAsDouble          (object)                    except? -1
+    Py_complex          _Py_c_diff                      (Py_complex, Py_complex)
+    Py_complex          _Py_c_neg                       (Py_complex)
+    Py_complex          _Py_c_pow                       (Py_complex, Py_complex)
+    Py_complex          _Py_c_prod                      (Py_complex, Py_complex)
+    Py_complex          _Py_c_quot                      (Py_complex, Py_complex)
+    Py_complex          _Py_c_sum                       (Py_complex, Py_complex)
+
+    ###############################################################################################
+    # dict
+    ###############################################################################################
+    PyTypeObject PyDict_Type
+
+    int                 PyDict_Check                    (object)                    # Always succeeds.
+    int                 PyDict_CheckExact               (object)                    # Always succeeds.
+    void                PyDict_Clear                    (object)
+    int                 PyDict_Contains                 (object, object)            except -1
+    object              PyDict_Copy                     (object)
+    int                 PyDict_DelItem                  (object, object)            except -1
+    int                 PyDict_DelItemString            (object, char *)            except -1
+    object              PyDict_Items                    (object)
+    object              PyDict_Keys                     (object)
+    int                 PyDict_Merge                    (object, object, int)       except -1
+    int                 PyDict_MergeFromSeq2            (object, object, int)       except -1
+    object              PyDict_New                      ()
+    # XXX: Pyrex doesn't support pointer to a python object?
+    #int                 PyDict_Next                     (object, Py_ssize_t *, object *, object *) # Always succeeds.
+    int                 PyDict_SetItem                  (object, object, object)    except -1
+    int                 PyDict_SetItemString            (object, char *, object)    except -1
+    Py_ssize_t          PyDict_Size                     (object)                    except -1
+    int                 PyDict_Update                   (object, object)            except -1
+    object              PyDict_Values                   (object)
+    # XXX: Borrowed reference.  No exception on NULL.
+    #object              PyDict_GetItem                  (object, object)
+    # XXX: Borrowed reference.  No exception on NULL
+    #object              PyDict_GetItemString            (object, char *)
+
+
+    ###############################################################################################
+    # float
+    ###############################################################################################
+    PyTypeObject PyFloat_Type
+    int                 _PyFloat_Pack4                  (double, unsigned char *, int)  except -1
+    int                 _PyFloat_Pack8                  (double, unsigned char *, int)  except -1
+    double              _PyFloat_Unpack4                (unsigned char *, int)      except? -1
+    double              _PyFloat_Unpack8                (unsigned char *, int)      except? -1
+    double              PyFloat_AS_DOUBLE               (object)
+    double              PyFloat_AsDouble                (object)                    except? -1
+    void                PyFloat_AsReprString            (char*, object)
+    void                PyFloat_AsString                (char*, object)
+    int                 PyFloat_Check                   (object)                    # Always succeeds.
+    int                 PyFloat_CheckExact              (object)                    # Always succeeds.
+    object              PyFloat_FromDouble              (double)
+    object              PyFloat_FromString              (object, char**)
+
+    ###############################################################################################
+    # frame
+    ###############################################################################################
+
+    ctypedef struct PyFrameObject:
+        PyFrameObject *f_back
+        PyCodeObject  *f_code
+        PyObject *f_builtins
+        PyObject *f_globals
+        PyObject *f_locals
+        PyObject *f_trace
+        PyObject *f_exc_type
+        PyObject *f_exc_value
+        PyObject *f_exc_traceback
+        int f_lasti
+        int f_lineno
+        int f_restricted
+        int f_iblock
+        int f_nlocals
+        int f_ncells
+        int f_nfreevars
+        int f_stacksize
+
+    ###############################################################################################
+    # int
+    ###############################################################################################
+    PyTypeObject PyInt_Type
+    long                PyInt_AS_LONG                   (object)                    # Always succeeds.
+    long                PyInt_AsLong                    (object)                    except? -1
+    Py_ssize_t          PyInt_AsSsize_t                 (object)                    except? -1
+    unsigned long long  PyInt_AsUnsignedLongLongMask    (object)                    except? -1
+    unsigned long       PyInt_AsUnsignedLongMask        (object)                    except? -1
+    int                 PyInt_Check                     (object)                    # Always succeeds.
+    int                 PyInt_CheckExact                (object)                    # Always succeeds.
+    object              PyInt_FromLong                  (long)
+    object              PyInt_FromSsize_t               (Py_ssize_t)
+    object              PyInt_FromString                (char*, char**, int)
+    object              PyInt_FromUnicode               (Py_UNICODE*, Py_ssize_t, int)
+    long                PyInt_GetMax                    ()                      # Always succeeds.
+
+    ###############################################################################################
+    # iterator
+    ###############################################################################################
+    int                 PyIter_Check                    (object)                    # Always succeeds.
+    object              PyIter_Next                     (object)
+
+    ###############################################################################################
+    # list
+    ###############################################################################################
+    PyTypeObject PyList_Type
+    int                 PyList_Append                   (object, object)            except -1
+    object              PyList_AsTuple                  (object)
+    int                 PyList_Check                    (object)                    # Always succeeds.
+    int                 PyList_CheckExact               (object)                    # Always succeeds.
+    int                 PyList_GET_SIZE                 (object)                    # Always suceeds.
+    object              PyList_GetSlice                 (object, Py_ssize_t, Py_ssize_t)
+    int                 PyList_Insert                   (object, Py_ssize_t, object)       except -1
+    object              PyList_New                      (Py_ssize_t)
+    int                 PyList_Reverse                  (object)                    except -1
+    int                 PyList_SetSlice                 (object, Py_ssize_t, Py_ssize_t, object)  except -1
+    Py_ssize_t          PyList_Size                     (object)                    except -1
+    int                 PyList_Sort                     (object)                    except -1
+
+    ###############################################################################################
+    # long
+    ###############################################################################################
+    PyTypeObject PyLong_Type
+    int                 _PyLong_AsByteArray             (object, unsigned char *, size_t, int, int) except -1
+    object              _PyLong_FromByteArray           (unsigned char *, size_t, int, int)
+    size_t              _PyLong_NumBits                 (object)                    except -1
+    int                 _PyLong_Sign                    (object)                    # No error.
+    long                PyLong_AsLong                   (object)                    except? -1
+    long long           PyLong_AsLongLong               (object)                    except? -1
+    unsigned long       PyLong_AsUnsignedLong           (object)                    except? -1
+    unsigned long       PyLong_AsUnsignedLongMask       (object)                    except? -1
+    unsigned long long  PyLong_AsUnsignedLongLong       (object)                    except? -1
+    unsigned long long  PyLong_AsUnsignedLongLongMask   (object)                    except? -1
+    int                 PyLong_Check                    (object)                    # Always succeeds.
+    int                 PyLong_CheckExact               (object)                    # Always succeeds.
+    object              PyLong_FromDouble               (double)
+    object              PyLong_FromLong                 (long)
+    object              PyLong_FromLongLong             (long long)
+    object              PyLong_FromUnsignedLong         (unsigned long)
+    object              PyLong_FromUnsignedLongLong     (unsigned long long)
+    double              PyLong_AsDouble                 (object)                    except? -1
+    object              PyLong_FromVoidPtr              (void *)
+    void *              PyLong_AsVoidPtr                (object)                    except NULL
+    object              PyLong_FromString               (char *, char **, int)
+    object              PyLong_FromUnicode              (Py_UNICODE*, Py_ssize_t, int)
+
+    ###############################################################################################
+    # mapping
+    ###############################################################################################
+    int                 PyMapping_Check                 (object)                    # Always succeeds.
+    int                 PyMapping_DelItem               (object, object)            except -1
+    int                 PyMapping_DelItemString         (object, char *)            except -1
+    object              PyMapping_GetItemString         (object, char *)
+    int                 PyMapping_HasKey                (object, object)            # Always succeeds.
+    int                 PyMapping_HasKeyString          (object, char *)            # Always succeeds.
+    object              PyMapping_Items                 (object)
+    object              PyMapping_Keys                  (object)
+    Py_ssize_t          PyMapping_Length                (object)                    except -1
+    int                 PyMapping_SetItemString         (object, char *, object)    except -1
+    Py_ssize_t          PyMapping_Size                  (object)                    except -1
+    object              PyMapping_Values                (object)
+
+    ###############################################################################################
+    # mem
+    ###############################################################################################
+    void                PyMem_Free                      (void * p)
+    void *              PyMem_Malloc                    (size_t n)
+    void *              PyMem_Realloc                   (void *, size_t)
+
+    ###############################################################################################
+    # modsupport
+    ###############################################################################################
+    object              Py_BuildValue                   (char *, ...)
+    object              Py_VaBuildValue                 (char *, va_list)
+
+    ###############################################################################################
+    # number
+    ###############################################################################################
+    object              PyNumber_Absolute               (object)
+    object              PyNumber_Add                    (object, object)
+    object              PyNumber_And                    (object, object)
+    Py_ssize_t          PyNumber_AsSsize_t              (object, object)    except? -1
+    int                 PyNumber_Check                  (object)                    # Always succeeds.
+    # XXX: Pyrex doesn't support pointer to python object?
+    #int                 PyNumber_Coerce                 (object*, object*)          except -1
+    object              PyNumber_Divide                 (object, object)
+    object              PyNumber_Divmod                 (object, object)
+    object              PyNumber_Float                  (object)
+    object              PyNumber_FloorDivide            (object, object)
+    object              PyNumber_InPlaceAdd             (object, object)
+    object              PyNumber_InPlaceAnd             (object, object)
+    object              PyNumber_InPlaceDivide          (object, object)
+    object              PyNumber_InPlaceFloorDivide     (object, object)
+    object              PyNumber_InPlaceLshift          (object, object)
+    object              PyNumber_InPlaceMultiply        (object, object)
+    object              PyNumber_InPlaceOr              (object, object)
+    object              PyNumber_InPlacePower           (object, object, object)
+    object              PyNumber_InPlaceRemainder       (object, object)
+    object              PyNumber_InPlaceRshift          (object, object)
+    object              PyNumber_InPlaceSubtract        (object, object)
+    object              PyNumber_InPlaceTrueDivide      (object, object)
+    object              PyNumber_InPlaceXor             (object, object)
+    object              PyNumber_Int                    (object)
+    object              PyNumber_Invert                 (object)
+    object              PyNumber_Long                   (object)
+    object              PyNumber_Lshift                 (object, object)
+    object              PyNumber_Multiply               (object, object)
+    object              PyNumber_Negative               (object)
+    object              PyNumber_Or                     (object, object)
+    object              PyNumber_Positive               (object)
+    object              PyNumber_Power                  (object, object, object)
+    object              PyNumber_Remainder              (object, object)
+    object              PyNumber_Rshift                 (object, object)
+    object              PyNumber_Subtract               (object, object)
+    object              PyNumber_TrueDivide             (object, object)
+    object              PyNumber_Xor                    (object, object)
+
+    ###############################################################################################
+    # object
+    ###############################################################################################
+    int                 PyCallable_Check                (object)                    # Always succeeds.
+    int                 PyObject_AsFileDescriptor       (object)                    except -1
+    object              PyObject_Call                   (object, object, object)
+    object              PyObject_CallFunction           (object, char *, ...)
+    object              PyObject_CallFunctionObjArgs    (object, ...)
+    object              PyObject_CallMethod             (object, char *, char *, ...)
+    object              PyObject_CallMethodObjArgs      (object, object, ...)
+    object              PyObject_CallObject             (object, object)
+    int                 PyObject_Cmp                    (object, object, int *result)   except -1
+    # Use PyObject_Cmp instead.
+    #int                 PyObject_Compare                (object, object)
+    int                 PyObject_DelAttr                (object, object)            except -1
+    int                 PyObject_DelAttrString          (object, char *)            except -1
+    int                 PyObject_DelItem                (object, object)            except -1
+    int                 PyObject_DelItemString          (object, char *)            except -1
+    object              PyObject_Dir                    (object)
+    object              PyObject_GetAttr                (object, object)
+    object              PyObject_GetAttrString          (object, char *)
+    object              PyObject_GetItem                (object, object)
+    object              PyObject_GetIter                (object)
+    int                 PyObject_HasAttr                (object, object)            # Always succeeds.
+    int                 PyObject_HasAttrString          (object, char *)            # Always succeeds.
+    long                PyObject_Hash                   (object)                    except -1
+    int                 PyObject_IsInstance             (object, object)            except -1
+    int                 PyObject_IsSubclass             (object, object)            except -1
+    int                 PyObject_IsTrue                 (object)                    except -1
+    Py_ssize_t          PyObject_Length                 (object)                    except -1
+    int                 PyObject_Not                    (object)                    except -1
+    int                 PyObject_Print                  (object, FILE *, int)       except -1
+    object              PyObject_Repr                   (object)
+    object              PyObject_RichCompare            (object, object, int)
+    int                 PyObject_RichCompareBool        (object, object, int)       except -1
+    int                 PyObject_SetAttr                (object, object, object)    except -1
+    int                 PyObject_SetAttrString          (object, char *, object)    except -1
+    int                 PyObject_SetItem                (object, object, object)    except -1
+    Py_ssize_t          PyObject_Size                   (object)                    except -1
+    object              PyObject_Str                    (object)
+    object              PyObject_Type                   (object)
+    int                 PyObject_TypeCheck              (object, object)            # Always succeeds.
+    object              PyObject_Unicode                (object)
+
+    ###############################################################################################
+    # pyerrors
+    ###############################################################################################
+    int                 PyErr_BadArgument               ()
+    void                PyErr_BadInternalCall           ()
+    int                 PyErr_CheckSignals              ()
+    void                PyErr_Clear                     ()
+    int                 PyErr_ExceptionMatches          (object)
+    object              PyErr_Format                    (object, char *, ...)
+    int                 PyErr_GivenExceptionMatches     (object, object)
+    object              PyErr_NoMemory                  ()
+    object              PyErr_Occurred                  ()
+    void                PyErr_Restore                   (object, object, object)
+    object              PyErr_SetFromErrno              (object)
+    object              PyErr_SetFromErrnoWithFilename  (object, char *)
+    object              PyErr_SetFromErrnoWithFilenameObject    (object, object)
+    void                PyErr_SetInterrupt              ()
+    void                PyErr_SetNone                   (object)
+    void                PyErr_SetObject                 (object, object)
+    void                PyErr_SetString                 (object, char *)
+    int                 PyErr_Warn                      (object, char *)
+    int                 PyErr_WarnExplicit              (object, char *, char *, int, char *, object)
+    void                PyErr_WriteUnraisable           (object)
+
+    ###############################################################################################
+    # pyeval
+    # Be extremely careful with these functions.
+    ###############################################################################################
+
+    ctypedef struct PyThreadState:
+        PyFrameObject * frame
+        int recursion_depth
+        void * curexc_type, * curexc_value, * curexc_traceback
+        void * exc_type, * exc_value, * exc_traceback
+
+    void                PyEval_AcquireLock              ()
+    void                PyEval_ReleaseLock              ()
+    void                PyEval_AcquireThread            (PyThreadState *)
+    void                PyEval_ReleaseThread            (PyThreadState *)
+    PyThreadState*      PyEval_SaveThread               ()
+    void                PyEval_RestoreThread            (PyThreadState *)
+
+    ###############################################################################################
+    # pystate
+    # Be extremely careful with these functions.  Read PEP 311 for more detail.
+    ###############################################################################################
+
+    ctypedef int PyGILState_STATE
+    PyGILState_STATE    PyGILState_Ensure               ()
+    void                PyGILState_Release              (PyGILState_STATE)
+
+    ctypedef struct PyInterpreterState:
+        pass
+
+    PyThreadState*      PyThreadState_New               (PyInterpreterState *)
+    void                PyThreadState_Clear             (PyThreadState *)
+    void                PyThreadState_Delete            (PyThreadState *)
+    PyThreadState*      PyThreadState_Get               ()
+    PyThreadState*      PyThreadState_Swap              (PyThreadState *tstate)
+    # XXX: Borrowed reference.
+    #object              PyThreadState_GetDict          ()
+
+    ###############################################################################################
+    # run
+    # Functions for embedded interpreters are not included.
+    ###############################################################################################
+    ctypedef struct PyCompilerFlags:
+        int cf_flags
+
+    ctypedef struct _node:
+        pass
+
+    ctypedef void (*PyOS_sighandler_t)(int)
+
+    void                PyErr_Display                   (object, object, object)
+    void                PyErr_Print                     ()
+    void                PyErr_PrintEx                   (int)
+    char *              PyOS_Readline                   (FILE *, FILE *, char *)
+    PyOS_sighandler_t   PyOS_getsig                     (int)
+    PyOS_sighandler_t   PyOS_setsig                     (int, PyOS_sighandler_t)
+    _node *             PyParser_SimpleParseFile        (FILE *, char *, int)       except NULL
+    _node *             PyParser_SimpleParseFileFlags   (FILE *, char *, int,
+                                                         int)                       except NULL
+    _node *             PyParser_SimpleParseString      (char *, int)               except NULL
+    _node *             PyParser_SimpleParseStringFlagsFilename(char *, char *,
+                                                         int, int)                  except NULL
+    _node *             PyParser_SimpleParseStringFlags (char *, int, int)          except NULL
+    int                 PyRun_AnyFile                   (FILE *, char *)            except -1
+    int                 PyRun_AnyFileEx                 (FILE *, char *, int)       except -1
+    int                 PyRun_AnyFileExFlags            (FILE *, char *, int,
+                                                         PyCompilerFlags *)         except -1
+    int                 PyRun_AnyFileFlags              (FILE *, char *,
+                                                         PyCompilerFlags *)         except -1
+    object              PyRun_File                      (FILE *, char *, int,
+                                                         object, object)
+    object              PyRun_FileEx                    (FILE *, char *, int,
+                                                         object, object, int)
+    object              PyRun_FileExFlags               (FILE *, char *, int,
+                                                         object, object, int,
+                                                         PyCompilerFlags *)
+    object              PyRun_FileFlags                 (FILE *, char *, int,
+                                                         object, object,
+                                                         PyCompilerFlags *)
+    int                 PyRun_InteractiveLoop           (FILE *, char *)            except -1
+    int                 PyRun_InteractiveLoopFlags      (FILE *, char *,
+                                                         PyCompilerFlags *)         except -1
+    int                 PyRun_InteractiveOne            (FILE *, char *)            except -1
+    int                 PyRun_InteractiveOneFlags       (FILE *, char *,
+                                                         PyCompilerFlags *)         except -1
+    int                 PyRun_SimpleFile                (FILE *, char *)            except -1
+    int                 PyRun_SimpleFileEx              (FILE *, char *, int)       except -1
+    int                 PyRun_SimpleFileExFlags         (FILE *, char *, int,
+                                                         PyCompilerFlags *)         except -1
+    int                 PyRun_SimpleString              (char *)                    except -1
+    int                 PyRun_SimpleStringFlags         (char *, PyCompilerFlags *) except -1
+    object              PyRun_String                    (char *, int, object,
+                                                         object)
+    object              PyRun_StringFlags               (char *, int, object,
+                                                         object, PyCompilerFlags *)
+    int                 Py_AtExit                       (void (*func)())
+    object              Py_CompileString                (char *, char *, int)
+    object              Py_CompileStringFlags           (char *, char *, int, PyCompilerFlags *)
+    void                Py_Exit                         (int)
+    int                 Py_FdIsInteractive              (FILE *, char *)            # Always succeeds.
+    char *              Py_GetBuildInfo                 ()
+    char *              Py_GetCompiler                  ()
+    char *              Py_GetCopyright                 ()
+    char *              Py_GetExecPrefix                ()
+    char *              Py_GetPath                      ()
+    char *              Py_GetPlatform                  ()
+    char *              Py_GetPrefix                    ()
+    char *              Py_GetProgramFullPath           ()
+    char *              Py_GetProgramName               ()
+    char *              Py_GetPythonHome                ()
+    char *              Py_GetVersion                   ()
+
+    ###############################################################################################
+    # sequence
+    ###############################################################################################
+    int                 PySequence_Check                (object)                    # Always succeeds.
+    object              PySequence_Concat               (object, object)
+    int                 PySequence_Contains             (object, object)            except -1
+    Py_ssize_t          PySequence_Count                (object, object)            except -1
+    int                 PySequence_DelItem              (object, Py_ssize_t)        except -1
+    int                 PySequence_DelSlice             (object, Py_ssize_t, Py_ssize_t) except -1
+    object              PySequence_Fast                 (object, char *)
+    int                 PySequence_Fast_GET_SIZE        (object)
+    object              PySequence_GetItem              (object, Py_ssize_t)
+    object              PySequence_GetSlice             (object, Py_ssize_t, Py_ssize_t)
+    object              PySequence_ITEM                 (object, int)
+    int                 PySequence_In                   (object, object)            except -1
+    object              PySequence_InPlaceConcat        (object, object)
+    object              PySequence_InPlaceRepeat        (object, Py_ssize_t)
+    Py_ssize_t          PySequence_Index                (object, object)            except -1
+    Py_ssize_t          PySequence_Length               (object)                    except -1
+    object              PySequence_List                 (object)
+    object              PySequence_Repeat               (object, Py_ssize_t)
+    int                 PySequence_SetItem              (object, Py_ssize_t, object) except -1
+    int                 PySequence_SetSlice             (object, Py_ssize_t, Py_ssize_t, object) except -1
+    Py_ssize_t          PySequence_Size                 (object)                    except -1
+    object              PySequence_Tuple                (object)
+
+    ###############################################################################################
+    # string
+    ###############################################################################################
+    PyTypeObject PyString_Type
+    # Pyrex cannot support resizing because you have no choice but to use
+    # realloc which may call free() on the object, and there's no way to tell
+    # Pyrex to "forget" reference counting for the object.
+    #int                 _PyString_Resize                (object *, Py_ssize_t)             except -1
+    char *              PyString_AS_STRING              (object)                    # Always succeeds.
+    object              PyString_AsDecodedObject        (object, char *, char *)
+    object              PyString_AsEncodedObject        (object, char *, char *)
+    object              PyString_AsEncodedString        (object, char *, char *)
+    char *              PyString_AsString               (object)                    except NULL
+    int                 PyString_AsStringAndSize        (object, char **, Py_ssize_t *)    except -1
+    int                 PyString_Check                  (object)                    # Always succeeds.
+    int                 PyString_CHECK_INTERNED         (object)                    # Always succeeds.
+    int                 PyString_CheckExact             (object)                    # Always succeeds.
+    # XXX: Pyrex doesn't support pointer to a python object?
+    #void                PyString_Concat                 (object *, object)
+    # XXX: Pyrex doesn't support pointer to a python object?
+    #void                PyString_ConcatAndDel           (object *, object)
+    object              PyString_Decode                 (char *, int, char *, char *)
+    object              PyString_DecodeEscape           (char *, int, char *, int, char *)
+    object              PyString_Encode                 (char *, int, char *, char *)
+    object              PyString_Format                 (object, object)
+    object              PyString_FromFormat             (char*, ...)
+    object              PyString_FromFormatV            (char*, va_list)
+    object              PyString_FromString             (char *)
+    object              PyString_FromStringAndSize      (char *, Py_ssize_t)
+    Py_ssize_t          PyString_GET_SIZE               (object)                    # Always succeeds.
+    object              PyString_InternFromString       (char *)
+    # XXX: Pyrex doesn't support pointer to a python object?
+    #void                PyString_InternImmortal         (object*)
+    # XXX: Pyrex doesn't support pointer to a python object?
+    #void                PyString_InternInPlace          (object*)
+    object              PyString_Repr                   (object, int)
+    Py_ssize_t          PyString_Size                   (object)                    except -1
+
+    # Disgusting hack to access internal object values.
+    ctypedef struct PyStringObject:
+        int ob_refcnt
+        PyTypeObject * ob_type
+        int ob_size
+        long ob_shash
+        int ob_sstate
+        char * ob_sval
+
+    ###############################################################################################
+    # tuple
+    ###############################################################################################
+    PyTypeObject PyTuple_Type
+    # See PyString_Resize note about resizing.
+    #int                 _PyTuple_Resize                 (object*, Py_ssize_t)              except -1
+    int                 PyTuple_Check                   (object)                    # Always succeeds.
+    int                 PyTuple_CheckExact              (object)                    # Always succeeds.
+    Py_ssize_t          PyTuple_GET_SIZE                (object)                    # Always succeeds.
+    object              PyTuple_GetSlice                (object, Py_ssize_t, Py_ssize_t)
+    object              PyTuple_New                     (Py_ssize_t)
+    object              PyTuple_Pack                    (Py_ssize_t, ...)
+    Py_ssize_t          PyTuple_Size                    (object)                    except -1
+
+    ###############################################################################################
+    # Dangerous things!
+    # Do not use these unless you really, really know what you are doing.
+    ###############################################################################################
+    void                Py_INCREF                       (object)
+    void                Py_XINCREF                      (object)
+    void                Py_DECREF                       (object)
+    void                Py_XDECREF                      (object)
+    void                Py_CLEAR                        (object)
+
+    # XXX: Stolen reference.
+    void                PyTuple_SET_ITEM                (object, Py_ssize_t, value)
+    # XXX: Borrowed reference.
+    object              PyTuple_GET_ITEM                (object, Py_ssize_t)
+    # XXX: Borrowed reference.
+    object              PyTuple_GetItem                 (object, Py_ssize_t)
+    # XXX: Stolen reference.
+    int                 PyTuple_SetItem                 (object, Py_ssize_t, object)       except -1
+
+    # XXX: Steals reference.
+    int                 PyList_SetItem                  (object, Py_ssize_t, object)       except -1
+    # XXX: Borrowed reference
+    object              PyList_GetItem                  (object, Py_ssize_t)
+    # XXX: Borrowed reference, no NULL on error.
+    object              PyList_GET_ITEM                 (object, Py_ssize_t)
+    # XXX: Stolen reference.
+    void                PyList_SET_ITEM                 (object, Py_ssize_t, object)
+
+    # XXX: Borrowed reference.
+    object              PySequence_Fast_GET_ITEM        (object, Py_ssize_t)
+
+    # First parameter _must_ be a PyStringObject.
+    object              _PyString_Join                  (object, object)
+from distutils.core import setup
+from distutils.extension import Extension
+from Cython.Distutils import build_ext
+
+setup(
+    name = 'line_profiler',
+    ext_modules=[ 
+        Extension('_line_profiler',
+                  sources=['_line_profiler.pyx', 'timers.c'],
+                  extra_compile_args=['-fno-inline'],
+        ),
+    ],
+    py_modules=['line_profiler'],
+    cmdclass = {'build_ext': build_ext},
+)
+
+#include "Python.h"
+
+/* The following timer code comes from Python 2.5.2's _lsprof.c */
+
+#if !defined(HAVE_LONG_LONG)
+#error "This module requires long longs!"
+#endif
+
+/*** Selection of a high-precision timer ***/
+
+#ifdef MS_WINDOWS
+
+#include <windows.h>
+
+PY_LONG_LONG
+hpTimer(void)
+{
+        LARGE_INTEGER li;
+        QueryPerformanceCounter(&li);
+        return li.QuadPart;
+}
+
+double
+hpTimerUnit(void)
+{
+        LARGE_INTEGER li;
+        if (QueryPerformanceFrequency(&li))
+                return 1.0 / li.QuadPart;
+        else
+                return 0.000001;  /* unlikely */
+}
+
+#else  /* !MS_WINDOWS */
+
+#ifndef HAVE_GETTIMEOFDAY
+#error "This module requires gettimeofday() on non-Windows platforms!"
+#endif
+
+#if (defined(PYOS_OS2) && defined(PYCC_GCC))
+#include <sys/time.h>
+#else
+#include <sys/resource.h>
+#include <sys/times.h>
+#endif
+
+PY_LONG_LONG
+hpTimer(void)
+{
+        struct timeval tv;
+        PY_LONG_LONG ret;
+#ifdef GETTIMEOFDAY_NO_TZ
+        gettimeofday(&tv);
+#else
+        gettimeofday(&tv, (struct timezone *)NULL);
+#endif
+        ret = tv.tv_sec;
+        ret = ret * 1000000 + tv.tv_usec;
+        return ret;
+}
+
+double
+hpTimerUnit(void)
+{
+        return 0.000001;
+}
+
+#endif  /* MS_WINDOWS */
+
+#include "Python.h"
+
+PY_LONG_LONG hpTimer(void);
+double hpTimerUnit(void);