(self)
| 897 | return rep, False |
| 898 | |
| 899 | def collect(self) -> Iterator[nodes.Item | nodes.Collector]: |
| 900 | class="cm"># This is a cache for the root directories of the initial paths. |
| 901 | class="cm"># We can't use collection_cache for Session because of its special |
| 902 | class="cm"># role as the bootstrapping collector. |
| 903 | path_cache: dict[Path, Sequence[nodes.Collector]] = {} |
| 904 | |
| 905 | pm = self.config.pluginmanager |
| 906 | |
| 907 | for collection_argument in self._initial_parts: |
| 908 | self.trace(class="st">"processing argument", collection_argument) |
| 909 | self.trace.root.indent += 1 |
| 910 | |
| 911 | argpath = collection_argument.path |
| 912 | names = collection_argument.parts |
| 913 | parametrization = collection_argument.parametrization |
| 914 | module_name = collection_argument.module_name |
| 915 | |
| 916 | class="cm"># resolve_collection_argument() ensures this. |
| 917 | if argpath.is_dir(): |
| 918 | assert not names, fclass="st">"invalid arg {(argpath, names)!r}" |
| 919 | |
| 920 | paths = [argpath] |
| 921 | class="cm"># Add relevant parents of the path, from the root, e.g. |
| 922 | class="cm"># /a/b/c.py -> [/, /a, /a/b, /a/b/c.py] |
| 923 | if module_name is None: |
| 924 | class="cm"># Paths outside of the confcutdir should not be considered. |
| 925 | for path in argpath.parents: |
| 926 | if not pm._is_in_confcutdir(path): |
| 927 | break |
| 928 | paths.insert(0, path) |
| 929 | else: |
| 930 | class="cm"># For --pyargs arguments, only consider paths matching the module |
| 931 | class="cm"># name. Paths beyond the package hierarchy are not included. |
| 932 | module_name_parts = module_name.split(class="st">".") |
| 933 | for i, path in enumerate(argpath.parents, 2): |
| 934 | if i > len(module_name_parts) or path.stem != module_name_parts[-i]: |
| 935 | break |
| 936 | paths.insert(0, path) |
| 937 | |
| 938 | class="cm"># Start going over the parts from the root, collecting each level |
| 939 | class="cm"># and discarding all nodes which donclass="st">'t match the level's part. |
| 940 | any_matched_in_initial_part = False |
| 941 | notfound_collectors = [] |
| 942 | work: list[tuple[nodes.Collector | nodes.Item, list[Path | str]]] = [ |
| 943 | (self, [*paths, *names]) |
| 944 | ] |
| 945 | while work: |
| 946 | matchnode, matchparts = work.pop() |
| 947 | |
| 948 | class="cm"># Pop'd all of the parts, this is a match. |
| 949 | if not matchparts: |
| 950 | yield matchnode |
| 951 | any_matched_in_initial_part = True |
| 952 | continue |
| 953 | |
| 954 | class="cm"># Should have been matched by now, discard. |
| 955 | if not isinstance(matchnode, nodes.Collector): |
| 956 | continue |
nothing calls this directly
no test coverage detected