diff -ur profilePy3k/Lib/profile.py profileNEW/Lib/profile.py
--- profilePy3k/Lib/profile.py	2009-05-31 13:16:39.000000000 -0700
+++ profileNEW/Lib/profile.py	2009-05-31 11:52:19.000000000 -0700
@@ -1,451 +1,146 @@
 #! /usr/bin/env python
-#
-# Class for profiling python code. rev 1.0  6/2/94
-#
-# Based on prior profile module by Sjoerd Mullender...
-#   which was hacked somewhat by: Guido van Rossum
-
-"""Class for profiling Python code."""
-
-# Copyright 1994, by InfoSeek Corporation, all rights reserved.
-# Written by James Roskind
-#
-# Permission to use, copy, modify, and distribute this Python software
-# and its associated documentation for any purpose (subject to the
-# restriction in the following sentence) without fee is hereby granted,
-# provided that the above copyright notice appears in all copies, and
-# that both that copyright notice and this permission notice appear in
-# supporting documentation, and that the name of InfoSeek not be used in
-# advertising or publicity pertaining to distribution of the software
-# without specific, written prior permission.  This permission is
-# explicitly restricted to the copying and modification of the software
-# to remain in Python, compiled Python, or other languages (such as C)
-# wherein the modified or derived code is exclusively imported into a
-# Python module.
-#
-# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
-# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
-# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
-# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
-# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-
-
-import sys
-import os
-import time
-import marshal
-from optparse import OptionParser
+"""Python interface for the fast, high-resolution '_profile' module.
+"""
 
 __all__ = ["run", "runctx", "help", "Profile"]
 
-# Sample timer for use with
-#i_count = 0
-#def integer_timer():
-#       global i_count
-#       i_count = i_count + 1
-#       return i_count
-#itimes = integer_timer # replace with C coded timer returning integers
-
-#**************************************************************************
-# The following are the static member functions for the profiler class
-# Note that an instance of Profile() is *not* needed to call them.
-#**************************************************************************
+import _profile
+
+# ____________________________________________________________
+# Simple interface
 
 def run(statement, filename=None, sort=-1):
-    """Run statement under profiler optionally saving results in filename
+    """Run statement under profiler optionally saving results in filename.
 
     This function takes a single argument that can be passed to the
     "exec" statement, and an optional file name.  In all cases this
     routine attempts to "exec" its first argument and gather profiling
-    statistics from the execution. If no file name is present, then this
-    function automatically prints a simple profiling report, sorted by the
-    standard name string (file/line/function-name) that is presented in
-    each line.
+    statistics from the execution.
+
+    If no file name is given, then this function automatically prints
+    a simple profiling report, sorted by the standard name string
+    (file/line/function-name) that is present in each line.
+
+    Other sort options can be specified.  For more details, see the
+    description of the Stats.sort_stats method in the pstats module.
     """
     prof = Profile()
+    result = None
     try:
-        prof = prof.run(statement)
-    except SystemExit:
-        pass
-    if filename is not None:
-        prof.dump_stats(filename)
-    else:
-        return prof.print_stats(sort)
-
-def runctx(statement, globals, locals, filename=None):
-    """Run statement under profiler, supplying your own globals and locals,
-    optionally saving results in filename.
+        try:
+            prof = prof.run(statement)
+        except SystemExit:
+            pass
+    finally:
+        if filename is not None:
+            prof.dump_stats(filename)
+        else:
+            result = prof.print_stats(sort)
+    return result
+
+def runctx(statement, globals, locals, filename=None, sort=-1):
+    """Run statement under profiler, supplying your own globals and
+    locals, optionally saving results in filename.
 
-    statement and filename have the same semantics as profile.run
+    Arguments statement, filename and sort have the same semantics
+    as the function profile.run above.
     """
     prof = Profile()
+    result = None
     try:
-        prof = prof.runctx(statement, globals, locals)
-    except SystemExit:
-        pass
-
-    if filename is not None:
-        prof.dump_stats(filename)
-    else:
-        return prof.print_stats()
+        try:
+            prof = prof.runctx(statement, globals, locals)
+        except SystemExit:
+            pass
+    finally:
+        if filename is not None:
+            prof.dump_stats(filename)
+        else:
+            result = prof.print_stats(sort)
+    return result
 
 # Backwards compatibility.
 def help():
-    print("Documentation for the profile module can be found ")
-    print("in the Python Library Reference, section 'The Python Profiler'.")
-
-if os.name == "mac":
-    import MacOS
-    def _get_time_mac(timer=MacOS.GetTicks):
-        return timer() / 60.0
-
-if hasattr(os, "times"):
-    def _get_time_times(timer=os.times):
-        t = timer()
-        return t[0] + t[1]
-
-# Using getrusage(3) is better than clock(3) if available:
-# on some systems (e.g. FreeBSD), getrusage has a higher resolution
-# Furthermore, on a POSIX system, returns microseconds, which
-# wrap around after 36min.
-_has_res = 0
-try:
-    import resource
-    resgetrusage = lambda: resource.getrusage(resource.RUSAGE_SELF)
-    def _get_time_resource(timer=resgetrusage):
-        t = timer()
-        return t[0] + t[1]
-    _has_res = 1
-except ImportError:
-    pass
-
-class Profile:
-    """Profiler class.
-
-    self.cur is always a tuple.  Each such tuple corresponds to a stack
-    frame that is currently active (self.cur[-2]).  The following are the
-    definitions of its members.  We use this external "parallel stack" to
-    avoid contaminating the program that we are profiling. (old profiler
-    used to write into the frames local dictionary!!) Derived classes
-    can change the definition of some entries, as long as they leave
-    [-2:] intact (frame and previous tuple).  In case an internal error is
-    detected, the -3 element is used as the function name.
-
-    [ 0] = Time that needs to be charged to the parent frame's function.
-           It is used so that a function call will not have to access the
-           timing data for the parent frame.
-    [ 1] = Total time spent in this frame's function, excluding time in
-           subfunctions (this latter is tallied in cur[2]).
-    [ 2] = Total time spent in subfunctions, excluding time executing the
-           frame's function (this latter is tallied in cur[1]).
-    [-3] = Name of the function that corresponds to this frame.
-    [-2] = Actual frame that we correspond to (used to sync exception handling).
-    [-1] = Our parent 6-tuple (corresponds to frame.f_back).
-
-    Timing data for each function is stored as a 5-tuple in the dictionary
-    self.timings[].  The index is always the name stored in self.cur[-3].
-    The following are the definitions of the members:
-
-    [0] = The number of times this function was called, not counting direct
-          or indirect recursion,
-    [1] = Number of times this function appears on the stack, minus one
-    [2] = Total time spent internal to this function
-    [3] = Cumulative time that this function was present on the stack.  In
-          non-recursive functions, this is the total execution time from start
-          to finish of each invocation of a function, including time spent in
-          all subfunctions.
-    [4] = A dictionary indicating for each function name, the number of times
-          it was called by us.
-    """
-
-    bias = 0  # calibration constant
-
-    def __init__(self, timer=None, bias=None):
-        self.timings = {}
-        self.cur = None
-        self.cmd = ""
-        self.c_func_name = ""
-
-        if bias is None:
-            bias = self.bias
-        self.bias = bias     # Materialize in local dict for lookup speed.
-
-        if not timer:
-            if _has_res:
-                self.timer = resgetrusage
-                self.dispatcher = self.trace_dispatch
-                self.get_time = _get_time_resource
-            elif os.name == 'mac':
-                self.timer = MacOS.GetTicks
-                self.dispatcher = self.trace_dispatch_mac
-                self.get_time = _get_time_mac
-            elif hasattr(time, 'clock'):
-                self.timer = self.get_time = time.clock
-                self.dispatcher = self.trace_dispatch_i
-            elif hasattr(os, 'times'):
-                self.timer = os.times
-                self.dispatcher = self.trace_dispatch
-                self.get_time = _get_time_times
-            else:
-                self.timer = self.get_time = time.time
-                self.dispatcher = self.trace_dispatch_i
-        else:
-            self.timer = timer
-            t = self.timer() # test out timer function
-            try:
-                length = len(t)
-            except TypeError:
-                self.get_time = timer
-                self.dispatcher = self.trace_dispatch_i
-            else:
-                if length == 2:
-                    self.dispatcher = self.trace_dispatch
-                else:
-                    self.dispatcher = self.trace_dispatch_l
-                # This get_time() implementation needs to be defined
-                # here to capture the passed-in timer in the parameter
-                # list (for performance).  Note that we can't assume
-                # the timer() result contains two values in all
-                # cases.
-                def get_time_timer(timer=timer, sum=sum):
-                    return sum(timer())
-                self.get_time = get_time_timer
-        self.t = self.get_time()
-        self.simulate_call('profiler')
-
-    # Heavily optimized dispatch routine for os.times() timer
-
-    def trace_dispatch(self, frame, event, arg):
-        timer = self.timer
-        t = timer()
-        t = t[0] + t[1] - self.t - self.bias
-
-        if event == "c_call":
-            self.c_func_name = arg.__name__
-
-        if self.dispatch[event](self, frame,t):
-            t = timer()
-            self.t = t[0] + t[1]
-        else:
-            r = timer()
-            self.t = r[0] + r[1] - t # put back unrecorded delta
-
-    # Dispatch routine for best timer program (return = scalar, fastest if
-    # an integer but float works too -- and time.clock() relies on that).
-
-    def trace_dispatch_i(self, frame, event, arg):
-        timer = self.timer
-        t = timer() - self.t - self.bias
-
-        if event == "c_call":
-            self.c_func_name = arg.__name__
-
-        if self.dispatch[event](self, frame, t):
-            self.t = timer()
-        else:
-            self.t = timer() - t  # put back unrecorded delta
+    print("Documentation for the profile module can be found in the")
+    print("Python Library Reference, section 'The Python Profiler'.")
 
-    # Dispatch routine for macintosh (timer returns time in ticks of
-    # 1/60th second)
+# ____________________________________________________________
 
-    def trace_dispatch_mac(self, frame, event, arg):
-        timer = self.timer
-        t = timer()/60.0 - self.t - self.bias
+class Profile(_profile.Profiler):
+    """Profile(timer=None, timeunit=None, subcalls=True, builtins=True)
 
-        if event == "c_call":
-            self.c_func_name = arg.__name__
+    Builds a profiler object using the specified timer function.
+    The default timer is a fast, high resolution, built-in clock
+    based on real time.
 
-        if self.dispatch[event](self, frame, t):
-            self.t = timer()/60.0
-        else:
-            self.t = timer()/60.0 - t  # put back unrecorded delta
-
-    # SLOW generic dispatch routine for timer returning lists of numbers
-
-    def trace_dispatch_l(self, frame, event, arg):
-        get_time = self.get_time
-        t = get_time() - self.t - self.bias
-
-        if event == "c_call":
-            self.c_func_name = arg.__name__
-
-        if self.dispatch[event](self, frame, t):
-            self.t = get_time()
-        else:
-            self.t = get_time() - t # put back unrecorded delta
-
-    # In the event handlers, the first 3 elements of self.cur are unpacked
-    # into vrbls w/ 3-letter names.  The last two characters are meant to be
-    # mnemonic:
-    #     _pt  self.cur[0] "parent time"   time to be charged to parent frame
-    #     _it  self.cur[1] "internal time" time spent directly in the function
-    #     _et  self.cur[2] "external time" time spent in subfunctions
-
-    def trace_dispatch_exception(self, frame, t):
-        rpt, rit, ret, rfn, rframe, rcur = self.cur
-        if (rframe is not frame) and rcur:
-            return self.trace_dispatch_return(rframe, t)
-        self.cur = rpt, rit+t, ret, rfn, rframe, rcur
-        return 1
-
-
-    def trace_dispatch_call(self, frame, t):
-        if self.cur and frame.f_back is not self.cur[-2]:
-            rpt, rit, ret, rfn, rframe, rcur = self.cur
-            if not isinstance(rframe, Profile.fake_frame):
-                assert rframe.f_back is frame.f_back, ("Bad call", rfn,
-                                                       rframe, rframe.f_back,
-                                                       frame, frame.f_back)
-                self.trace_dispatch_return(rframe, 0)
-                assert (self.cur is None or \
-                        frame.f_back is self.cur[-2]), ("Bad call",
-                                                        self.cur[-3])
-        fcode = frame.f_code
-        fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name)
-        self.cur = (t, 0, 0, fn, frame, self.cur)
-        timings = self.timings
-        if fn in timings:
-            cc, ns, tt, ct, callers = timings[fn]
-            timings[fn] = cc, ns + 1, tt, ct, callers
-        else:
-            timings[fn] = 0, 0, 0, 0, {}
-        return 1
-
-    def trace_dispatch_c_call (self, frame, t):
-        fn = ("", 0, self.c_func_name)
-        self.cur = (t, 0, 0, fn, frame, self.cur)
-        timings = self.timings
-        if fn in timings:
-            cc, ns, tt, ct, callers = timings[fn]
-            timings[fn] = cc, ns+1, tt, ct, callers
-        else:
-            timings[fn] = 0, 0, 0, 0, {}
-        return 1
-
-    def trace_dispatch_return(self, frame, t):
-        if frame is not self.cur[-2]:
-            assert frame is self.cur[-2].f_back, ("Bad return", self.cur[-3])
-            self.trace_dispatch_return(self.cur[-2], 0)
-
-        # Prefix "r" means part of the Returning or exiting frame.
-        # Prefix "p" means part of the Previous or Parent or older frame.
-
-        rpt, rit, ret, rfn, frame, rcur = self.cur
-        rit = rit + t
-        frame_total = rit + ret
-
-        ppt, pit, pet, pfn, pframe, pcur = rcur
-        self.cur = ppt, pit + rpt, pet + frame_total, pfn, pframe, pcur
-
-        timings = self.timings
-        cc, ns, tt, ct, callers = timings[rfn]
-        if not ns:
-            # This is the only occurrence of the function on the stack.
-            # Else this is a (directly or indirectly) recursive call, and
-            # its cumulative time will get updated when the topmost call to
-            # it returns.
-            ct = ct + frame_total
-            cc = cc + 1
-
-        if pfn in callers:
-            callers[pfn] = callers[pfn] + 1  # hack: gather more
-            # stats such as the amount of time added to ct courtesy
-            # of this specific call, and the contribution to cc
-            # courtesy of this call.
-        else:
-            callers[pfn] = 1
+    For custom timer functions returning timer ticks as an integer,
+    timeunit can be a float specifying the scale (i.e. the length of
+    each timer tick in seconds).
 
-        timings[rfn] = cc, ns - 1, tt + rit, ct, callers
+    Option subcalls enables or disable statistics for the callers of
+    each function.
 
-        return 1
-
-
-    dispatch = {
-        "call": trace_dispatch_call,
-        "exception": trace_dispatch_exception,
-        "return": trace_dispatch_return,
-        "c_call": trace_dispatch_c_call,
-        "c_exception": trace_dispatch_return,  # the C function returned
-        "c_return": trace_dispatch_return,
-        }
-
-
-    # The next few functions play with self.cmd. By carefully preloading
-    # our parallel stack, we can force the profiled result to include
-    # an arbitrary string as the name of the calling function.
-    # We use self.cmd as that string, and the resulting stats look
-    # very nice :-).
-
-    def set_cmd(self, cmd):
-        if self.cur[-1]: return   # already set
-        self.cmd = cmd
-        self.simulate_call(cmd)
-
-    class fake_code:
-        def __init__(self, filename, line, name):
-            self.co_filename = filename
-            self.co_line = line
-            self.co_name = name
-            self.co_firstlineno = 0
-
-        def __repr__(self):
-            return repr((self.co_filename, self.co_line, self.co_name))
-
-    class fake_frame:
-        def __init__(self, code, prior):
-            self.f_code = code
-            self.f_back = prior
-
-    def simulate_call(self, name):
-        code = self.fake_code('profile', 0, name)
-        if self.cur:
-            pframe = self.cur[-2]
-        else:
-            pframe = None
-        frame = self.fake_frame(code, pframe)
-        self.dispatch['call'](self, frame, 0)
-
-    # collect stats from pending stack, including getting final
-    # timings for self.cmd frame.
-
-    def simulate_cmd_complete(self):
-        get_time = self.get_time
-        t = get_time() - self.t
-        while self.cur[-1]:
-            # We *can* cause assertion errors here if
-            # dispatch_trace_return checks for a frame match!
-            self.dispatch['return'](self, self.cur[-2], t)
-            t = 0
-        self.t = get_time() - t
+    Option builtin enables or disables profiling of calls to built-in
+    functions, separate from their caller.
+    """
+##    def __init__(self, timer=None, *args, **kwds):
+##        if not hasattr(timer, '__call__'):
+##            raise TypeError('timer is not callable: %s' % repr(timer))
+##        _profile.Profiler.__init__(self, timer, *args, **kwds)
 
+    # Most of the functionality is in the base class.  This subclass
+    # only adds convenient and backward-compatible methods.
 
     def print_stats(self, sort=-1):
         import pstats
-        pstats.Stats(self).strip_dirs().sort_stats(sort). \
-                  print_stats()
+        pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
 
     def dump_stats(self, file):
+        import marshal
         f = open(file, 'wb')
         self.create_stats()
         marshal.dump(self.stats, f)
         f.close()
 
     def create_stats(self):
-        self.simulate_cmd_complete()
+        self.disable()
         self.snapshot_stats()
 
     def snapshot_stats(self):
+        entries = self.getstats()
         self.stats = {}
-        for func, (cc, ns, tt, ct, callers) in self.timings.items():
-            callers = callers.copy()
-            nc = 0
-            for callcnt in callers.values():
-                nc += callcnt
+        callersdicts = {}
+        # call information
+        for entry in entries:
+            func = label(entry.code)
+            nc = entry.callcount         # ncalls column of pstats (before '/')
+            cc = nc - entry.reccallcount # ncalls column of pstats (after '/')
+            tt = entry.inlinetime        # tottime column of pstats
+            ct = entry.totaltime         # cumtime column of pstats
+            callers = {}
+            callersdicts[id(entry.code)] = callers
             self.stats[func] = cc, nc, tt, ct, callers
-
+        # subcall information
+        for entry in entries:
+            if entry.calls:
+                func = label(entry.code)
+                for subentry in entry.calls:
+                    try:
+                        callers = callersdicts[id(subentry.code)]
+                    except KeyError:
+                        continue
+                    nc = subentry.callcount
+                    cc = nc - subentry.reccallcount
+                    tt = subentry.inlinetime
+                    ct = subentry.totaltime
+                    if func in callers:
+                        prev = callers[func]
+                        nc += prev[0]
+                        cc += prev[1]
+                        tt += prev[2]
+                        ct += prev[3]
+                    callers[func] = nc, cc, tt, ct
 
     # The following two methods can be called by clients to use
     # a profiler to profile a statement, given as a string.
@@ -456,142 +151,35 @@
         return self.runctx(cmd, dict, dict)
 
     def runctx(self, cmd, globals, locals):
-        self.set_cmd(cmd)
-        sys.setprofile(self.dispatcher)
+        self.enable()
         try:
             exec(cmd, globals, locals)
         finally:
-            sys.setprofile(None)
+            self.disable()
         return self
 
     # This method is more useful to profile a single function call.
+
     def runcall(self, func, *args, **kw):
-        self.set_cmd(repr(func))
-        sys.setprofile(self.dispatcher)
+        self.enable()
         try:
             return func(*args, **kw)
         finally:
-            sys.setprofile(None)
+            self.disable()
 
+# ____________________________________________________________
 
-    #******************************************************************
-    # The following calculates the overhead for using a profiler.  The
-    # problem is that it takes a fair amount of time for the profiler
-    # to stop the stopwatch (from the time it receives an event).
-    # Similarly, there is a delay from the time that the profiler
-    # re-starts the stopwatch before the user's code really gets to
-    # continue.  The following code tries to measure the difference on
-    # a per-event basis.
-    #
-    # Note that this difference is only significant if there are a lot of
-    # events, and relatively little user code per event.  For example,
-    # code with small functions will typically benefit from having the
-    # profiler calibrated for the current platform.  This *could* be
-    # done on the fly during init() time, but it is not worth the
-    # effort.  Also note that if too large a value specified, then
-    # execution time on some functions will actually appear as a
-    # negative number.  It is *normal* for some functions (with very
-    # low call counts) to have such negative stats, even if the
-    # calibration figure is "correct."
-    #
-    # One alternative to profile-time calibration adjustments (i.e.,
-    # adding in the magic little delta during each event) is to track
-    # more carefully the number of events (and cumulatively, the number
-    # of events during sub functions) that are seen.  If this were
-    # done, then the arithmetic could be done after the fact (i.e., at
-    # display time).  Currently, we track only call/return events.
-    # These values can be deduced by examining the callees and callers
-    # vectors for each functions.  Hence we *can* almost correct the
-    # internal time figure at print time (note that we currently don't
-    # track exception event processing counts).  Unfortunately, there
-    # is currently no similar information for cumulative sub-function
-    # time.  It would not be hard to "get all this info" at profiler
-    # time.  Specifically, we would have to extend the tuples to keep
-    # counts of this in each frame, and then extend the defs of timing
-    # tuples to include the significant two figures. I'm a bit fearful
-    # that this additional feature will slow the heavily optimized
-    # event/time ratio (i.e., the profiler would run slower, fur a very
-    # low "value added" feature.)
-    #**************************************************************
-
-    def calibrate(self, m, verbose=0):
-        if self.__class__ is not Profile:
-            raise TypeError("Subclasses must override .calibrate().")
-
-        saved_bias = self.bias
-        self.bias = 0
-        try:
-            return self._calibrate_inner(m, verbose)
-        finally:
-            self.bias = saved_bias
-
-    def _calibrate_inner(self, m, verbose):
-        get_time = self.get_time
+def label(code):
+    if isinstance(code, str):
+        return ('~', 0, code)    # built-in functions ('~' sorts at the end)
+    else:
+        return (code.co_filename, code.co_firstlineno, code.co_name)
 
-        # Set up a test case to be run with and without profiling.  Include
-        # lots of calls, because we're trying to quantify stopwatch overhead.
-        # Do not raise any exceptions, though, because we want to know
-        # exactly how many profile events are generated (one call event, +
-        # one return event, per Python-level call).
-
-        def f1(n):
-            for i in range(n):
-                x = 1
-
-        def f(m, f1=f1):
-            for i in range(m):
-                f1(100)
-
-        f(m)    # warm up the cache
-
-        # elapsed_noprofile <- time f(m) takes without profiling.
-        t0 = get_time()
-        f(m)
-        t1 = get_time()
-        elapsed_noprofile = t1 - t0
-        if verbose:
-            print("elapsed time without profiling =", elapsed_noprofile)
-
-        # elapsed_profile <- time f(m) takes with profiling.  The difference
-        # is profiling overhead, only some of which the profiler subtracts
-        # out on its own.
-        p = Profile()
-        t0 = get_time()
-        p.runctx('f(m)', globals(), locals())
-        t1 = get_time()
-        elapsed_profile = t1 - t0
-        if verbose:
-            print("elapsed time with profiling =", elapsed_profile)
-
-        # reported_time <- "CPU seconds" the profiler charged to f and f1.
-        total_calls = 0.0
-        reported_time = 0.0
-        for (filename, line, funcname), (cc, ns, tt, ct, callers) in \
-                p.timings.items():
-            if funcname in ("f", "f1"):
-                total_calls += cc
-                reported_time += tt
-
-        if verbose:
-            print("'CPU seconds' profiler reported =", reported_time)
-            print("total # calls =", total_calls)
-        if total_calls != m + 1:
-            raise ValueError("internal error: total calls = %d" % total_calls)
-
-        # reported_time - elapsed_noprofile = overhead the profiler wasn't
-        # able to measure.  Divide by twice the number of calls (since there
-        # are two profiler events per call in this test) to get the hidden
-        # overhead per event.
-        mean = (reported_time - elapsed_noprofile) / 2.0 / total_calls
-        if verbose:
-            print("mean stopwatch overhead per profile event =", mean)
-        return mean
-
-#****************************************************************************
-def Stats(*args):
-    print('Report generating functions are in the "pstats" module\a')
+# ____________________________________________________________
 
 def main():
+    import os, sys
+    from optparse import OptionParser
     usage = "profile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
     parser = OptionParser(usage=usage)
     parser.allow_interspersed_args = False
diff -ur profilePy3k/Lib/test/profilee.py profileNEW/Lib/test/profilee.py
--- profilePy3k/Lib/test/profilee.py	2009-05-31 11:53:07.000000000 -0700
+++ profileNEW/Lib/test/profilee.py	2009-05-31 11:28:52.000000000 -0700
@@ -1,5 +1,5 @@
 """
-Input for test_profile.py and test_cprofile.py.
+Input for test_profile.py.
 
 IMPORTANT: This stuff is touchy. If you modify anything above the
 test class you'll have to regenerate the stats by running the two
Only in profilePy3k/Lib/test: test_cprofile.py
diff -ur profilePy3k/Lib/test/test_profile.py profileNEW/Lib/test/test_profile.py
--- profilePy3k/Lib/test/test_profile.py	2009-05-31 11:58:22.000000000 -0700
+++ profileNEW/Lib/test/test_profile.py	2009-05-31 13:34:02.000000000 -0700
@@ -1,12 +1,14 @@
 """Test suite for the profile module."""
 
+# combined test_cprofile.py and test_profile.py from py3k/Lib/test rev 73066
+
 import os
 import sys
 import pstats
 import unittest
 from difflib import unified_diff
 from io import StringIO
-from test.support import run_unittest
+from test.support import run_unittest, TESTFN, unlink
 
 import profile
 from test.profilee import testfunc, timer
@@ -16,7 +18,7 @@
 
     profilerclass = profile.Profile
     methodnames = ['print_stats', 'print_callers', 'print_callees']
-    expected_max_output = ':0(max)'
+    expected_max_output = '{built-in method max}'
 
     def get_expected_output(self):
         return _ProfileOutput
@@ -42,7 +44,7 @@
             results.append('\n'.join(output))
         return results
 
-    def test_cprofile(self):
+    def test_profile(self):
         results = self.do_profiling()
         expected = self.get_expected_output()
         self.assertEqual(results[0], 1000)
@@ -75,6 +77,20 @@
             self.assertTrue(self.expected_max_output in res,
                 "Profiling {0!r} didn't report max:\n{1}".format(stmt, res))
 
+    # Issue 3895.
+    def test_bad_counter_during_dealloc(self):
+        import _profile
+        # Must use a file as StringIO doesn't trigger the bug.
+        sys.stderr = open(TESTFN, 'w')
+        try:
+            obj = _profile.Profiler(lambda: int)
+            obj.enable()
+            obj = _profile.Profiler(1)
+            obj.disable()
+        finally:
+            sys.stderr = sys.__stderr__
+            unlink(TESTFN)
+
 
 def regenerate_expected_output(filename, cls):
     filename = filename.rstrip('co')
Only in profilePy3k/Modules: _lsprof.c
Only in profileNEW/Modules: _profile.c
diff -ur profilePy3k/setup.py profileNEW/setup.py
--- profilePy3k/setup.py	2009-05-31 13:19:42.000000000 -0700
+++ profileNEW/setup.py	2009-05-31 13:20:40.000000000 -0700
@@ -433,8 +433,8 @@
         # Python C API test module
         exts.append( Extension('_testcapi', ['_testcapimodule.c'],
                                depends=['testcapi_long.h']) )
-        # profiler (_lsprof is for cProfile.py)
-        exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) )
+        # profiler (_profile is for profile.py)
+        exts.append( Extension('_profile', ['_profile.c', 'rotatingtree.c']) )
         # static Unicode character database
         exts.append( Extension('unicodedata', ['unicodedata.c']) )
 
