Esempio n. 1
0
 def test_no_new_reference_cycles(self):
     # Similar to https://github.com/mgedmin/objgraph/pull/22 but for
     # typestats()
     gc.disable()
     x = type('MyClass', (), {})()
     self.assertEqual(len(gc.get_referrers(x)), 1)
     objgraph.typestats()
     self.assertEqual(len(gc.get_referrers(x)), 1)
Esempio n. 2
0
 def test_no_new_reference_cycles(self):
     # Similar to https://github.com/mgedmin/objgraph/pull/22 but for
     # typestats()
     gc.disable()
     x = type('MyClass', (), {})()
     self.assertEqual(len(gc.get_referrers(x)), 1)
     objgraph.typestats()
     self.assertEqual(len(gc.get_referrers(x)), 1)
Esempio n. 3
0
def get_memory_leak_report(options):
    import objgraph
    import pympler.asizeof
    original_path = options.module_name
    if os.path.sep in original_path:
        module_name = original_path.replace(".py", "").replace(".pyc", "")
        module_name = module_name.replace(os.path.sep, ".")
    else:
        module_name = original_path

    args = [original_path] + options.args.split()
    sys.argv = args
    module = importlib.import_module(module_name)

    current_stats = objgraph.typestats(shortnames=True)
    for _ in range(options.init_step_count):
        module.main()
        # Get the baseline
        current_stats = objgraph.typestats(shortnames=True)

    total = 0
    growths = []
    for i in range(options.leak_step_count):
        logger.debug("Step %s", i)
        # Call the API again, and check the growth.
        # Ideally there is no growth after each call
        module.main()
        growth = get_growth_from_stats(current_stats)

        adj_growth = []
        for type_, new_count, inc in growth:
            fn = "%s-leak-step-%s-%s.png" % (options.short_name, i, type_)
            fn = os.path.join(options.destination, fn)
            leaked_objects = objgraph.by_type(type_)[-inc:]

            # Generate a graph for the leaked objects
            # up to a maximum of 100
            objgraph.show_backrefs(leaked_objects[:50], filename=fn)
            # Also get the size of the objects leaked
            size = pympler.asizeof.asized(leaked_objects).size / 2 ** 10
            total += size
            logger.debug("+%s: %r grew to %s (+%s KB)",
                         inc, type_, new_count, size)
            adj_growth.append((type_, new_count, inc, size))
        adj_growth.sort(key=lambda x: x[3], reverse=True)
        growths.append(adj_growth)
        # Update the current stats
        current_stats = objgraph.typestats(shortnames=True)
    return growths, total
Esempio n. 4
0
 def test_without_filter(self):
     MyClass = type('MyClass', (), {'__module__': 'mymodule'})  # noqa
     x, y = MyClass(), MyClass()
     x.magic_attr = True
     y.magic_attr = False
     stats = objgraph.typestats(shortnames=False)
     self.assertEqual(2, stats['mymodule.MyClass'])
def report_growth(label='', limit=20, peak_stats={}):
    """Using the objgraph module, report the growth of objects since the last call."""
    # pylint:disable=dangerous-default-value
    # pylint 'Dangerous default value {} as argument'
    if LOG.isEnabledFor(logging.DEBUG3) and _ObjGraph:
        # Tried and failed to redirect stdout to get this output in the
        # log, so copying the entire show_growth() function here just to
        # write to the log.
        LOG.debug3("object growth {}".format(label))
        gc.collect()
        # Have to get the objects ourselves and free them, otherwise typestats() leaks.
        all_objects = gc.get_objects()
        try:
            stats = objgraph.typestats(all_objects)
            deltas = {}
            for name, count in stats.items():
                old_count = peak_stats.get(name, 0)
                if count > old_count:
                    deltas[name] = count - old_count
                    peak_stats[name] = count
            deltas = sorted(deltas.items(),
                            key=operator.itemgetter(1),
                            reverse=True)
            if limit:
                deltas = deltas[:limit]
            if deltas:
                width = max(len(name) for name, count in deltas)
                for name, delta in deltas:
                    LOG.debug3('%-*s%9d %+9d' %
                               (width, name, stats[name], delta))
        finally:
            del all_objects
Esempio n. 6
0
    def get_new_objects(lst, fn, *args, **kwargs):
        """
        Collect types and numbers of new objects left over after the given function is called.

        If lst is not empty after the call, this MAY indicate a memory leak, but not necessarily,
        since some functions are intended to create new objects for later use.

        Parameters
        ----------
        lst : list
            List used to collect objects and deltas.
        fn : function
            The function being checked for possible memory leaks.
        *args : tuple
            Positional args passed to fn.
        **kwargs : dict
            Named args to be passed to fn.

        Returns
        -------
        object
            The object returned by the call to fn.
        """
        gc.collect()
        start_objs = objgraph.typestats()
        start_objs['frame'] += 1
        start_objs['function'] += 1
        start_objs['builtin_function_or_method'] += 1
        start_objs['cell'] += 1
        ret = fn(*args, **kwargs)
        lst.extend([(str(o), delta) for o, _, delta in objgraph.growth(peak_stats=start_objs)])
        return ret
Esempio n. 7
0
 def test_without_filter(self):
     MyClass = type('MyClass', (), {'__module__': 'mymodule'})  # noqa
     x, y = MyClass(), MyClass()
     x.magic_attr = True
     y.magic_attr = False
     stats = objgraph.typestats(shortnames=False)
     self.assertEqual(2, stats['mymodule.MyClass'])
Esempio n. 8
0
def main():
    a1 = dict()
    a2 = dict()
    a3 = dict()
    a1['a2'] = a2
    a2['a3'] = a3
    a3['a1'] = a1
    b = dict()
    b['b'] = b
    c = dict()
    c['c'] = 'c'

    import gc
    import types
    print(len(_bfs([b], gc.get_referrers)))

    sccs = tarjan([a1, b, c], gc.get_referrers)

    show_cycles(sccs, joined=True)
    print(sccs)
    del sccs
    gc.collect()

    sccs = tarjan([d, e, f])

    show_cycles(sccs, joined=True)

    return

    sccs = tarjan(gc.get_objects(), gc.get_referrers)
    print([len(i) for i in sccs])
    import objgraph
    objs = objgraph.at_addrs(sccs[0])
    print(objgraph.typestats(objs))
Esempio n. 9
0
def OBJGRAPH_DELTAS():
    from collections import OrderedDict
    try:
        import objgraph
        import gc
        import operator
        peak_stats = cache.ram('peak_stats', lambda: {}, time_expire=None)
        last_checked = cache.ram('last_checked',
                                 lambda: request.now,
                                 time_expire=None)
        gc.collect()
        #cobbled together from https://github.com/mgedmin/objgraph/blob/master/objgraph.py (show_growth())
        stats = objgraph.typestats(shortnames=False)
        deltas = {}
        for name, count in stats.items():
            old_count = peak_stats.get(name, 0)
            if count > old_count:
                deltas[name] = count - old_count
                peak_stats[name] = count
        peak_stats = cache.ram('peak_stats', lambda: peak_stats, time_expire=0)
        cache.ram('last_checked', lambda: request.now, time_expire=0)
        deltas = sorted(deltas.items(),
                        key=operator.itemgetter(1),
                        reverse=True)
        return ({
            'growth': deltas,
            'last_checked': last_checked,
            'time_period': "{}".format(request.now - last_checked)
        })
    except Exception as e:
        return ({'error': e})
Esempio n. 10
0
 def wrapper(*args, **kwargs):
     start_objs = objgraph.typestats()
     start_objs['frame'] += 1
     start_objs['cell'] += 1
     ret = fn(*args, **kwargs)
     for obj, _, delta_objs in objgraph.growth(peak_stats=start_objs):
         print(str(fn), "added %s %+d" % (obj, delta_objs))
     return ret
Esempio n. 11
0
def set_type_count_checkpoint():
    import objgraph
    global checkpoint_type_stats
    checkpoint_type_stats = objgraph.typestats()
    print '====>\t', 'checkpoint', datetime.strftime(datetime.now(), '%X')
    print '\n'.join(('\t%s: %d' % item) for item in
                     reversed(sorted(checkpoint_type_stats.iteritems(), key=itemgetter(1)))), \
           '\n', '-'*40
Esempio n. 12
0
 def test_with_filter(self):
     MyClass = type('MyClass', (), {'__module__': 'mymodule'})  # noqa
     x, y = MyClass(), MyClass()
     x.magic_attr = True
     y.magic_attr = False
     stats = objgraph.typestats(
         shortnames=False,
         filter=lambda e: isinstance(e, MyClass) and e.magic_attr)
     self.assertEqual(1, stats['mymodule.MyClass'])
Esempio n. 13
0
 def test_with_filter(self):
     MyClass = type('MyClass', (), {'__module__': 'mymodule'})  # noqa
     x, y = MyClass(), MyClass()
     x.magic_attr = True
     y.magic_attr = False
     stats = objgraph.typestats(
         shortnames=False,
         filter=lambda e: isinstance(e, MyClass) and e.magic_attr)
     self.assertEqual(1, stats['mymodule.MyClass'])
Esempio n. 14
0
def sample_objects(timestamp, stream):
    # instead of keeping the count_per_type in memory, stream the data to a file
    # to save memory
    count_per_type = objgraph.typestats()

    # add the timestamp for plotting
    data = [timestamp, count_per_type]

    data_pickled = pickle.dumps(data)
    stream.write(data_pickled)
Esempio n. 15
0
def sample_objects(timestamp, stream):
    # instead of keeping the count_per_type in memory, stream the data to a file
    # to save memory
    count_per_type = objgraph.typestats()

    # add the timestamp for plotting
    data = [timestamp, count_per_type]

    data_pickled = pickle.dumps(data)
    stream.write(data_pickled)
Esempio n. 16
0
    def _tick(self):
        print("TICK")
        if self.request is not None:
            return
        print(objgraph.typestats())

        self.request = QtNetwork.QNetworkRequest()
        self.request.setUrl(QtCore.QUrl(self.url))
        self.request.setRawHeader(b"User-Agent", b"Test")
        self.reply = self.manager.get(self.request)
        self.reply.finished.connect(self._finished)
Esempio n. 17
0
def _trace_call(frame, arg, stack, context):
    """
    This is called after we have matched based on glob pattern and isinstance check.
    """
    global time0
    if time0 is None:
        time0 = time.time()

    (qual_cache, method_counts, class_counts, id2count, verbose, memory, leaks,
     stream, show_ptrs) = context

    funcname = find_qualified_name(frame.f_code.co_filename,
                                   frame.f_code.co_firstlineno, qual_cache)

    self = frame.f_locals['self']
    try:
        pname = "(%s)" % self.pathname
    except AttributeError:
        pname = ""

    cname = self.__class__.__name__
    my_id = id(self)
    if my_id in id2count:
        id_count = id2count[my_id]
    else:
        class_counts[cname] += 1
        id2count[my_id] = id_count = class_counts[cname]

    sname = "%s#%d%s" % (self.__class__.__name__, id_count, pname)

    fullname = '.'.join((sname, funcname))
    method_counts[fullname] += 1

    indent = tab * (len(stack) - 1)
    if verbose:
        _printer("%s--> %s (%d)" % (indent, fullname, method_counts[fullname]))
        _indented_print(frame.f_locals,
                        frame.f_locals,
                        len(stack) - 1,
                        show_ptrs=show_ptrs)
    else:
        _printer("%s-->%s" % (indent, fullname))

    if memory is not None:
        memory.append(mem_usage())

    if leaks is not None:
        stats = objgraph.typestats()
        stats['frame'] += 1
        stats['cell'] += 1
        stats['list'] += 1
        leaks.append(stats)

    stream.flush()
Esempio n. 18
0
    def __call__(self, request, *args, **kwargs):
        Metrics.RequestCounter.labels(method=request.method).inc()
        response = self.get_response(request, *args, **kwargs)
        Metrics.ResponseCounter.labels(response.status_code).inc()

        gc.collect()
        stats = objgraph.typestats()
        for obj, cnt in stats.items():
            Metrics.ObjectsInMemory.labels(obj).set(cnt)

        return response
Esempio n. 19
0
def memory_content(interactive=False):
    typestats = dict(objgraph.typestats())

    while True:
        types = []
        for itype, type_name in enumerate(sorted(typestats.keys())):
            print '%d %s: %d' % (itype, type_name, typestats[type_name])
            types.append(type_name)
            cls = eval(type_name)
            if hasattr(cls, '__len__'):
                for obj in objgraph.by_type(type_name):
                    if len(obj) > 1000:
                        print '   Large object (n=%d) [%s ...]' % (len(obj),
                                                                   str(obj[0]))

        if not interactive:
            break

        print 'Inspect? (0-%d or q):' % itype
        response = sys.stdin.readline().strip()
        if response == 'q':
            break

        try:
            itype = int(response)
            objs = objgraph.by_type(types[itype])
        except:
            print 'Unrecognized input %s' % response
            continue

        while True:
            print 'Item #? (0-%d or q):' % len(objs)
            response = sys.stdin.readline()
            if response == 'q':
                break

            try:
                iobj = int(response)
                obj = objs[iobj]
            except:
                print 'Unrecognized input %s' % response
                continue

            while True:
                print 'Expression? (use "obj", e.g., len(obj), or q):'
                response = sys.stdin.readline()
                if response == 'q':
                    break

                try:
                    print eval(response)
                except:
                    print 'Unrecognized input %s' % response
                    continue
Esempio n. 20
0
def memory_content(interactive = False):
    typestats = dict(objgraph.typestats())

    while True:
        types = []
        for itype, type_name in enumerate(sorted(typestats.keys())):
            print '%d %s: %d' % (itype, type_name, typestats[type_name])
            types.append(type_name)
            cls = eval(type_name)
            if hasattr(cls, '__len__'):
                for obj in objgraph.by_type(type_name):
                    if len(obj) > 1000:
                        print '   Large object (n=%d) [%s ...]' % (len(obj), str(obj[0]))

        if not interactive:
            break

        print 'Inspect? (0-%d or q):' % itype
        response = sys.stdin.readline().strip()
        if response == 'q':
            break

        try:
            itype = int(response)
            objs = objgraph.by_type(types[itype])
        except:
            print 'Unrecognized input %s' % response
            continue

        while True:
            print 'Item #? (0-%d or q):' % len(objs)
            response = sys.stdin.readline()
            if response == 'q':
                break
    
            try:
                iobj = int(response)
                obj = objs[iobj]
            except:
                print 'Unrecognized input %s' % response
                continue

            while True:
                print 'Expression? (use "obj", e.g., len(obj), or q):'
                response = sys.stdin.readline()
                if response == 'q':
                    break
        
                try:
                    print eval(response)
                except:
                    print 'Unrecognized input %s' % response
                    continue
Esempio n. 21
0
def dump_type_count_checkpoint_diff():
    import objgraph
    type_stats = objgraph.typestats()
    diff = {}
    for key, val in type_stats.iteritems():
        countdiff = val - checkpoint_type_stats.get(key, 0)
        if countdiff:
            diff[key] = countdiff

    print '====>\t', 'checkpoint diff', datetime.strftime(datetime.now(), '%X')
    print '\n'.join(('\t%s: %d' % item) for item in
                     reversed(sorted(diff.iteritems(), key=itemgetter(1)))), \
           '\n', '-'*40
Esempio n. 22
0
def show_cycles(sccs, joined=False):
    import objgraph
    a = sccs
    if joined:
        a = []
        for scc in sccs:
            a.extend(scc)
        a = [a]

    for scc in a:
        objs = objgraph.at_addrs(scc)
        print(objgraph.typestats(objs))
        objgraph.show_backrefs(objs, max_depth=len(scc) + 5,
            filter=lambda x: id(x) in scc)
Esempio n. 23
0
def get_growth_from_stats(current_stats):
    import objgraph
    new_stats = objgraph.typestats(shortnames=True)
    growth = []
    for type_, new_count in new_stats.items():
        if type_ == "frame":
            # This is an object that objgraph adds.
            # Skip it.
            continue
        old_count = current_stats.get(type_, 0)
        increment = new_count - old_count
        if increment > 0:
            growth.append((type_, new_count, increment))
    growth.sort(key=lambda x: x[2], reverse=True)
    return growth
Esempio n. 24
0
def show_cycles(sccs, joined=False):
    import objgraph
    a = sccs
    if joined:
        a = []
        for scc in sccs:
            a.extend(scc)
        a = [a]

    for scc in a:
        objs = objgraph.at_addrs(scc)
        print(objgraph.typestats(objs))
        objgraph.show_backrefs(objs,
                               max_depth=len(scc) + 5,
                               filter=lambda x: id(x) in scc)
Esempio n. 25
0
def object_growth():
    """
    Shows changes in allocations, like objgraph.show_growth(), except:

    - show_growth() prints to stdout, this is flask view.

    - this saves the peaks in the session, so that each user sees the changes
      between their last page load, not some global.

    - this function is commented :)

    """
    # We don't want our numbers crudded up by a GC cycle that hasn't run yet,
    # so force GC before we gather stats.
    gc.collect()

    # `typestats() `returns a dict of {type-name: count-of-allocations}. We'll
    # compare the current count for each type to the previous count, stored
    # in the session as `peak_stats`, and save the changes into `deltas`.
    peak_stats = flask.session.get('peak_stats', {})
    stats = objgraph.typestats()
    deltas = {}

    # For each type, look it the old count in `peak_stats`, defaulting to 0.
    # We're really only interested in *growth* -- remember, we're looking for
    # memory leaks -- so if the current count is greater than the peak count,
    # we want to return that change in `deltas` and also note the new peak
    # for later.
    for name, count in stats.iteritems():
        old_count = peak_stats.get(name, 0)
        if count > old_count:
            deltas[name] = count - old_count
            peak_stats[name] = count

    # We have to remember to store `peak_stats` back in the session, otherwise
    # Flask won't notice that it's changed.
    flask.session['peak_stats'] = peak_stats

    # Create (type-name, delta) tuples, sorted by objects with the biggest growth.
    deltas = sorted(deltas.items(), key=operator.itemgetter(1), reverse=True)

    return flask.render_template(
        'growth.html',
        growth=deltas,
    )
Esempio n. 26
0
def memory_delta():
    typestats = dict(objgraph.typestats())

    names = set(snapshot.keys()) | set(typestats.keys())
    for name in names:
        try:
            now = typestats[name]
        except:
            now = 0

        try:
            before = snapshot[name]
        except:
            before = 0

        print ' %s: %+d' % (name, (now - before))

    snapshot = typestats
Esempio n. 27
0
def memory_delta():
    typestats = dict(objgraph.typestats())

    names = set(snapshot.keys()) | set(typestats.keys())
    for name in names:
        try:
            now = typestats[name]
        except:
            now = 0

        try:
            before = snapshot[name]
        except:
            before = 0

        print ' %s: %+d' % (name, (now - before))

    snapshot = typestats
Esempio n. 28
0
    def check_leaks(self, suppress=False, limit=20):
        stats = objgraph.typestats(shortnames=False)
        deltas = {}
        for name, count in stats.items():
            old_count = self.peak.get(name, 0)
            if count > old_count:
                deltas[name] = count - old_count
                self.peak[name] = count

        deltas = sorted(deltas.items(), key=operator.itemgetter(1), reverse=True)
        deltas = deltas[:limit]

        if not suppress:
            if deltas:
                self.logger.info("Peak memory usage change:")
                width = max(len(name) for name, count in deltas)
                for name, delta in deltas:
                    self.logger.info('  %-*s%9d %+9d' % (width, name, stats[name], delta))
Esempio n. 29
0
def object_growth():
    """
    Shows changes in allocations, like objgraph.show_growth(), except:

    - show_growth() prints to stdout, this is flask view.

    - this saves the peaks in the session, so that each user sees the changes
      between their last page load, not some global.

    - this function is commented :)

    """
    # We don't want our numbers crudded up by a GC cycle that hasn't run yet,
    # so force GC before we gather stats.
    gc.collect()

    # `typestats() `returns a dict of {type-name: count-of-allocations}. We'll
    # compare the current count for each type to the previous count, stored
    # in the session as `peak_stats`, and save the changes into `deltas`.
    peak_stats = flask.session.get('peak_stats', {})
    stats = objgraph.typestats()
    deltas = {}

    # For each type, look it the old count in `peak_stats`, defaulting to 0.
    # We're really only interested in *growth* -- remember, we're looking for
    # memory leaks -- so if the current count is greater than the peak count,
    # we want to return that change in `deltas` and also note the new peak
    # for later.
    for name, count in stats.iteritems():
        old_count = peak_stats.get(name, 0)
        if count > old_count:
            deltas[name] = count - old_count
            peak_stats[name] = count

    # We have to remember to store `peak_stats` back in the session, otherwise
    # Flask won't notice that it's changed.
    flask.session['peak_stats'] = peak_stats

    # Create (type-name, delta) tuples, sorted by objects with the biggest growth.
    deltas = sorted(deltas.items(), key=operator.itemgetter(1), reverse=True)

    return flask.render_template('growth.html',
        growth = deltas,
    )
Esempio n. 30
0
    def check_iter_leaks(niter, func, *args, **kwargs):
        """
        Run func niter times and collect info on new objects left over after each iteration.

        Parameters
        ----------
        niter : int
            Number of times to run func.
        func : function
            A function that takes no arguments.
        *args : tuple
            Positional args passed to func.
        **kwargs : dict
            Named args to be passed to func.

        Returns
        -------
        set
            set of tuples of the form (typename, count)
        """
        if niter < 2:
            raise RuntimeError(
                "Must run the function at least twice, but niter={}".format(
                    niter))
        iters = []
        gc.collect()
        start_objs = objgraph.typestats()
        if 'frame' in start_objs:
            start_objs['frame'] += 1
        start_objs['function'] += 1
        start_objs['builtin_function_or_method'] += 1
        start_objs['cell'] += 1
        for i in range(niter):
            func(*args, **kwargs)
            gc.collect()
            lst = [(str(o), delta)
                   for o, _, delta in objgraph.growth(peak_stats=start_objs)]
            iters.append(lst)

        set1 = set(iters[-2])
        set2 = set(iters[-1])

        return set2 - set1
Esempio n. 31
0
def main():
    a1 = dict()
    a2 = dict()
    a3 = dict()
    a1['a2'] = a2
    a2['a3'] = a3
    a3['a1'] = a1
    b = dict()
    b['b'] = b
    c = dict()
    c['c'] = 'c'

    import gc
    import types
    print(len(
        _bfs([b],
            gc.get_referrers
            )
     ))

    sccs = tarjan([a1, b, c], gc.get_referrers)

    show_cycles(sccs, joined=True)
    print(sccs)
    del sccs
    gc.collect()


    sccs = tarjan([d, e, f])

    show_cycles(sccs, joined=True)

    return

    sccs = tarjan(gc.get_objects(), gc.get_referrers)
    print([len(i) for i in sccs])
    import objgraph
    objs = objgraph.at_addrs(sccs[0])
    print(objgraph.typestats(objs))
Esempio n. 32
0
def OBJGRAPH_DELTAS():
    from collections import OrderedDict
    try:
        import objgraph
        import gc
        import operator
        peak_stats = cache.ram('peak_stats', lambda: {}, time_expire=None)
        last_checked = cache.ram('last_checked', lambda: request.now, time_expire=None)
        gc.collect()
        #cobbled together from https://github.com/mgedmin/objgraph/blob/master/objgraph.py (show_growth())
        stats = objgraph.typestats(shortnames=False)
        deltas = {}
        for name, count in stats.items():
            old_count = peak_stats.get(name, 0)
            if count > old_count:
                deltas[name] = count - old_count
                peak_stats[name] = count
        peak_stats = cache.ram('peak_stats', lambda: peak_stats, time_expire=0)
        cache.ram('last_checked', lambda:  request.now, time_expire=0)
        deltas = sorted(deltas.items(), key=operator.itemgetter(1), reverse=True)
        return({'growth':deltas, 'last_checked': last_checked, 'time_period': "{}".format(request.now -last_checked)})
    except Exception as e:
        return({'error':e})
Esempio n. 33
0
 def test_long_type_names(self):
     x = type('MyClass', (), {'__module__': 'mymodule'})()  # noqa
     stats = objgraph.typestats(shortnames=False)
     self.assertEqual(1, stats['mymodule.MyClass'])
Esempio n. 34
0
 def test_long_type_names(self):
     x = type('MyClass', (), {'__module__': 'mymodule'})()  # noqa
     stats = objgraph.typestats(shortnames=False)
     self.assertEqual(1, stats['mymodule.MyClass'])
Esempio n. 35
0
 def obj_log(self):
     self.obj_file.write('%s %s\n' % (
         datetime.utcnow().isoformat(),
         json.dumps(objgraph.typestats())
     ))
     self.obj_file.flush()
Esempio n. 36
0
 def obj_log(self):
     self.obj_file.write(
         '%s %s\n' %
         (datetime.utcnow().isoformat(), json.dumps(objgraph.typestats())))
     self.obj_file.flush()
Esempio n. 37
0
 def do_update(self):
     leaked = objgraph.get_leaking_objects()
     self.g.update()
     leaked = objgraph.get_leaking_objects()
     ts = objgraph.typestats(leaked)
     self.assertFalse(ts)