Find additional objects referenced by objs and append them to objs. We use this since gc.get_objects() does not return objects without pointers in them such as strings.
(objs: list[object])
| 92 | |
| 93 | |
| 94 | def find_recursive_objects(objs: list[object]) -> None: |
| 95 | """Find additional objects referenced by objs and append them to objs. |
| 96 | |
| 97 | We use this since gc.get_objects() does not return objects without pointers |
| 98 | in them such as strings. |
| 99 | """ |
| 100 | seen = {id(o) for o in objs} |
| 101 | |
| 102 | def visit(o: object) -> None: |
| 103 | if id(o) not in seen: |
| 104 | objs.append(o) |
| 105 | seen.add(id(o)) |
| 106 | |
| 107 | for obj in objs.copy(): |
| 108 | if type(obj) is FakeInfo: |
| 109 | # Processing these would cause a crash. |
| 110 | continue |
| 111 | if type(obj) in (dict, defaultdict): |
| 112 | for key, val in cast(dict[object, object], obj).items(): |
| 113 | visit(key) |
| 114 | visit(val) |
| 115 | if type(obj) in (list, tuple, set): |
| 116 | for x in cast(Iterable[object], obj): |
| 117 | visit(x) |
| 118 | if hasattr(obj, "__slots__"): |
| 119 | for base in type.mro(type(obj)): |
| 120 | for slot in getattr(base, "__slots__", ()): |
| 121 | if hasattr(obj, slot): |
| 122 | visit(getattr(obj, slot)) |
no test coverage detected
searching dependent graphs…