(file: string, name: string, context: ResolutionContext, depth: number)
| 2192 | } |
| 2193 | |
| 2194 | function pythonModuleSymbolUncached(file: string, name: string, context: ResolutionContext, depth: number): Node | undefined { |
| 2195 | const own = context.getNodesInFile(file).find((n) => |
| 2196 | n.name === name && !n.qualifiedName.includes('::') && |
| 2197 | (n.kind === 'class' || n.kind === 'function' || n.kind === 'variable' || n.kind === 'constant')); |
| 2198 | if (own || depth >= 3) return own; |
| 2199 | // Re-exported by name (`from .users import User`), else through a star import |
| 2200 | // (`from .users import *` — not among the import mappings, so read here). |
| 2201 | const sources: Array<{ source: string; exported: string }> = context.getImportMappings(file, 'python') |
| 2202 | .filter((imp) => !imp.isNamespace && imp.localName === name) |
| 2203 | .map((imp) => ({ source: imp.source, exported: imp.exportedName })); |
| 2204 | for (const m of (context.readFile(file) ?? '').matchAll(/^\s*from\s+([\w.]+)\s+import\s+\*/gm)) { |
| 2205 | sources.push({ source: m[1]!, exported: name }); |
| 2206 | } |
| 2207 | for (const { source, exported } of sources) { |
| 2208 | const target = resolveImportPath(source, file, 'python', context) ?? findPythonModuleFile(source, context, file)?.filePath ?? null; |
| 2209 | if (!target || target === file) continue; |
| 2210 | const found = pythonModuleSymbol(target, exported, context, depth + 1); |
| 2211 | if (found) return found; |
| 2212 | } |
| 2213 | return undefined; |
| 2214 | } |
| 2215 | |
| 2216 | function findPythonModuleFile( |
| 2217 | mod: string, |
no test coverage detected