| 377 | |
| 378 | |
| 379 | def _assert_no_instances(cls, when=""): |
| 380 | __tracebackhide__ = True |
| 381 | n = 0 |
| 382 | ref = list() |
| 383 | gc.collect() |
| 384 | objs = gc.get_objects() |
| 385 | for obj in objs: # e.g., vtkPolyData, Brain, Plotter, etc. |
| 386 | try: |
| 387 | check = isinstance(obj, cls) |
| 388 | except Exception: # such as a weakref |
| 389 | check = False |
| 390 | if check: |
| 391 | if cls.__name__ == "Brain": |
| 392 | ref.append(f"Brain._cleaned = {getattr(obj, '_cleaned', None)}") |
| 393 | rr = gc.get_referrers(obj) |
| 394 | count = 0 |
| 395 | for r in rr: # e.g., list, dict, etc. that holds the reference to obj |
| 396 | if ( |
| 397 | r is not objs |
| 398 | and r is not globals() |
| 399 | and r is not locals() |
| 400 | and not inspect.isframe(r) |
| 401 | ): |
| 402 | name = _fullname(r, referent=obj) |
| 403 | if isinstance(r, list | dict | tuple): |
| 404 | rep = f"len={len(r)}" |
| 405 | r_ = gc.get_referrers(r) |
| 406 | types = list() |
| 407 | for x in r_: |
| 408 | types.append(_fullname(x, referent=r)) |
| 409 | types = " / ".join(sorted(types)) |
| 410 | rep += f" | {len(r_)} referrers: {types}" |
| 411 | del r_ |
| 412 | else: |
| 413 | rep = "repr=" |
| 414 | rep += repr(r)[:100].replace("\n", " ") |
| 415 | # If it's a __closure__, get more information |
| 416 | if rep.startswith("<cell at "): |
| 417 | try: |
| 418 | rep += f" ({repr(r.cell_contents)[:100]})" |
| 419 | except Exception: |
| 420 | pass |
| 421 | ref.append(f"{name} with {rep}") |
| 422 | count += 1 |
| 423 | del r |
| 424 | del rr |
| 425 | n += count > 0 |
| 426 | del obj |
| 427 | del objs |
| 428 | gc.collect() |
| 429 | assert n == 0, f"\n{n} {cls.__name__} @ {when}:\n" + "\n".join(ref) |
| 430 | |
| 431 | |
| 432 | def _resource_path(submodule, filename): |