Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b4d4aa7

Browse files
committed
Added option (-c) to display cycles including uncollectable garbage.
Displays the total number of Python objects in existence at each iteration. svn path=/trunk/matplotlib/; revision=3452
1 parent 79d2892 commit b4d4aa7

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

lib/matplotlib/cbook.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,68 @@ def plot(self, i0=0, isub=1):
844844
show()
845845

846846

847+
def print_cycles(objects, outstream=sys.stdout, show_progress=False):
848+
"""
849+
objects: A list of objects to find cycles in. It is often useful
850+
to pass in gc.garbage to find the cycles that are
851+
preventing some objects from being garbage collected.
852+
outstream: The stream for output.
853+
show_progress: If True, print the number of objects reached as they are
854+
found.
855+
"""
856+
import gc
857+
from types import FrameType
858+
859+
def print_path(path):
860+
for i, step in enumerate(path):
861+
# next "wraps around"
862+
next = path[(i + 1) % len(path)]
863+
864+
outstream.write(" %s -- " % str(type(step)))
865+
if isinstance(step, dict):
866+
for key, val in step.items():
867+
if val is next:
868+
outstream.write("[%s]" % repr(key))
869+
break
870+
if key is next:
871+
outstream.write("[key] = %s" % repr(val))
872+
break
873+
elif isinstance(step, list):
874+
outstream.write("[%d]" % step.index(next))
875+
elif isinstance(step, tuple):
876+
outstream.write("( tuple )")
877+
else:
878+
outstream.write(repr(step))
879+
outstream.write(" ->\n")
880+
outstream.write("\n")
881+
882+
def recurse(obj, start, all, current_path):
883+
if show_progress:
884+
outstream.write("%d\r" % len(all))
885+
886+
all[id(obj)] = None
887+
888+
referents = gc.get_referents(obj)
889+
for referent in referents:
890+
# If we've found our way back to the start, this is
891+
# a cycle, so print it out
892+
if referent is start:
893+
print_path(current_path)
894+
895+
# Don't go back through the original list of objects, or
896+
# through temporary references to the object, since those
897+
# are just an artifact of the cycle detector itself.
898+
elif referent is objects or isinstance(referent, FrameType):
899+
continue
900+
901+
# We haven't seen this object before, so recurse
902+
elif id(referent) not in all:
903+
recurse(referent, start, all, current_path + [obj])
904+
905+
for obj in objects:
906+
outstream.write("Examining: %r\n" % obj)
907+
recurse(obj, obj, { }, [])
908+
847909
if __name__=='__main__':
848910
assert( allequal([1,1,1]) )
849911
assert(not allequal([1,1,0]) )

0 commit comments

Comments
 (0)