Given a .py[i] filename, return module and base directory. For example, given "xxx/yyy/foo/bar.py", we might return something like: ("foo.bar", "xxx/yyy") If namespace packages is off, we crawl upwards until we find a directory without an __init__.py If nam
(self, path: str)
| 140 | return sources |
| 141 | |
| 142 | def crawl_up(self, path: str) -> tuple[str, str]: |
| 143 | """Given a .py[i] filename, return module and base directory. |
| 144 | |
| 145 | For example, given "xxx/yyy/foo/bar.py", we might return something like: |
| 146 | ("foo.bar", "xxx/yyy") |
| 147 | |
| 148 | If namespace packages is off, we crawl upwards until we find a directory without |
| 149 | an __init__.py |
| 150 | |
| 151 | If namespace packages is on, we crawl upwards until the nearest explicit base directory. |
| 152 | Failing that, we return one past the highest directory containing an __init__.py |
| 153 | |
| 154 | We won't crawl past directories with invalid package names. |
| 155 | The base directory returned is an absolute path. |
| 156 | """ |
| 157 | path = os.path.abspath(path) |
| 158 | parent, filename = os.path.split(path) |
| 159 | |
| 160 | module_name = strip_py(filename) or filename |
| 161 | |
| 162 | parent_module, base_dir = self.crawl_up_dir(parent) |
| 163 | if module_name == "__init__": |
| 164 | return parent_module, base_dir |
| 165 | |
| 166 | # Note that module_name might not actually be a valid identifier, but that's okay |
| 167 | # Ignoring this possibility sidesteps some search path confusion |
| 168 | module = module_join(parent_module, module_name) |
| 169 | return module, base_dir |
| 170 | |
| 171 | def crawl_up_dir(self, dir: str) -> tuple[str, str]: |
| 172 | return self._crawl_up_helper(dir) or ("", dir) |