Find files that import from or depend on the given file. Performs up to *max_hops* iterations of expansion (default 2). Stops early if the total exceeds 500 files. Returns a :class:`DependentList` — a regular ``list[str]`` that also carries a ``.truncated`` flag. When ``truncated
(
store: GraphStore,
file_path: str,
max_hops: int = _MAX_DEPENDENT_HOPS,
)
| 755 | |
| 756 | |
| 757 | def find_dependents( |
| 758 | store: GraphStore, |
| 759 | file_path: str, |
| 760 | max_hops: int = _MAX_DEPENDENT_HOPS, |
| 761 | ) -> DependentList: |
| 762 | """Find files that import from or depend on the given file. |
| 763 | |
| 764 | Performs up to *max_hops* iterations of expansion (default 2). |
| 765 | Stops early if the total exceeds 500 files. |
| 766 | |
| 767 | Returns a :class:`DependentList` — a regular ``list[str]`` that also |
| 768 | carries a ``.truncated`` flag. When ``truncated is True`` the |
| 769 | returned list is capped at ``_MAX_DEPENDENT_FILES`` and the full |
| 770 | set of dependents was not explored. See issue #261. |
| 771 | """ |
| 772 | all_dependents: set[str] = set() |
| 773 | visited: set[str] = {file_path} |
| 774 | frontier: set[str] = {file_path} |
| 775 | for _hop in range(max_hops): |
| 776 | next_frontier: set[str] = set() |
| 777 | for fp in frontier: |
| 778 | deps = _single_hop_dependents(store, fp) |
| 779 | new_deps = deps - visited |
| 780 | all_dependents.update(new_deps) |
| 781 | next_frontier.update(new_deps) |
| 782 | visited.update(next_frontier) |
| 783 | frontier = next_frontier |
| 784 | if not frontier: |
| 785 | break |
| 786 | if len(all_dependents) > _MAX_DEPENDENT_FILES: |
| 787 | logger.warning( |
| 788 | "Dependent expansion capped at %d files for %s", |
| 789 | len(all_dependents), |
| 790 | file_path, |
| 791 | ) |
| 792 | return DependentList( |
| 793 | list(all_dependents)[:_MAX_DEPENDENT_FILES], |
| 794 | truncated=True, |
| 795 | ) |
| 796 | return DependentList(list(all_dependents)) |
| 797 | |
| 798 | |
| 799 | def _parse_single_file( |