Look for submodules that are now suppressed in target package. If a submodule a.b gets added, we need to mark it as suppressed in modules that contain "from a import b". Previously we assumed that 'a.b' is not a module but a regular name. This is only relevant when following import
(
module: str,
path: str | None,
deps: dict[str, set[str]],
graph: Graph,
fscache: FileSystemCache,
refresh_file: Callable[[str, str], list[str]],
)
| 1230 | |
| 1231 | |
| 1232 | def refresh_suppressed_submodules( |
| 1233 | module: str, |
| 1234 | path: str | None, |
| 1235 | deps: dict[str, set[str]], |
| 1236 | graph: Graph, |
| 1237 | fscache: FileSystemCache, |
| 1238 | refresh_file: Callable[[str, str], list[str]], |
| 1239 | ) -> list[str] | None: |
| 1240 | """Look for submodules that are now suppressed in target package. |
| 1241 | |
| 1242 | If a submodule a.b gets added, we need to mark it as suppressed |
| 1243 | in modules that contain "from a import b". Previously we assumed |
| 1244 | that 'a.b' is not a module but a regular name. |
| 1245 | |
| 1246 | This is only relevant when following imports normally. |
| 1247 | |
| 1248 | Args: |
| 1249 | module: target package in which to look for submodules |
| 1250 | path: path of the module |
| 1251 | refresh_file: function that reads the AST of a module (returns error messages) |
| 1252 | |
| 1253 | Return a list of errors from refresh_file() if it was called. If the |
| 1254 | return value is None, we didn't call refresh_file(). |
| 1255 | """ |
| 1256 | messages = None |
| 1257 | if path is None or not path.endswith(INIT_SUFFIXES): |
| 1258 | # Only packages have submodules. |
| 1259 | return None |
| 1260 | # Find any submodules present in the directory. |
| 1261 | pkgdir = os.path.dirname(path) |
| 1262 | try: |
| 1263 | entries = fscache.listdir(pkgdir) |
| 1264 | except FileNotFoundError: |
| 1265 | entries = [] |
| 1266 | for fnam in entries: |
| 1267 | if ( |
| 1268 | not fnam.endswith((".py", ".pyi")) |
| 1269 | or fnam.startswith("__init__.") |
| 1270 | or fnam.count(".") != 1 |
| 1271 | ): |
| 1272 | continue |
| 1273 | shortname = fnam.split(".")[0] |
| 1274 | submodule = module + "." + shortname |
| 1275 | trigger = make_trigger(submodule) |
| 1276 | |
| 1277 | # We may be missing the required fine-grained deps. |
| 1278 | ensure_deps_loaded(module, deps, graph) |
| 1279 | |
| 1280 | if trigger in deps: |
| 1281 | for dep in deps[trigger]: |
| 1282 | # We can ignore <...> deps since a submodule can't trigger any. |
| 1283 | state = graph.get(dep) |
| 1284 | if not state: |
| 1285 | # Maybe it's a non-top-level target. We only care about the module. |
| 1286 | dep_module = module_prefix(graph, dep) |
| 1287 | if dep_module is not None: |
| 1288 | state = graph.get(dep_module) |
| 1289 | if state: |
no test coverage detected
searching dependent graphs…