import type { SymbolInfo, SyntaxNode } from '../types.js'; import type { LanguageDefinition } from './types.js'; import type { LanguageTraverser, DeclarationFunctionInfo } from '../traversers/types.js'; import type { LanguageExportExtractor, LanguageImportExtractor, LanguageSymbolExtractor } from '../extractors/types.js'; /** * Python AST traverser * * Handles Python AST node types and traversal patterns. * Python has a simpler structure than TypeScript/JavaScript: * - Functions are defined with 'def' or 'async def' * - No variable declarations with functions (unlike JS const x = () => {}) * - Classes contain methods (which are just functions) */ export declare class PythonTraverser implements LanguageTraverser { targetNodeTypes: string[]; containerTypes: string[]; declarationTypes: string[]; functionTypes: string[]; shouldExtractChildren(node: SyntaxNode): boolean; isDeclarationWithFunction(_node: SyntaxNode): boolean; getContainerBody(node: SyntaxNode): SyntaxNode | null; shouldTraverseChildren(node: SyntaxNode): boolean; findParentContainerName(node: SyntaxNode): string | undefined; findFunctionInDeclaration(_node: SyntaxNode): DeclarationFunctionInfo; } /** * Python export extractor * * Python doesn't have explicit export syntax. All module-level (top-level) * declarations are considered exported (importable by other modules): * - Classes: class User: ... * - Functions: def helper(): ... * - Async functions: async def fetch_data(): ... */ export declare class PythonExportExtractor implements LanguageExportExtractor { private readonly exportableTypes; private extractExportName; extractExports(rootNode: SyntaxNode): string[]; private extractReExportNames; } /** * Python import extractor * * Handles: * - import os * - import os as system * - from utils.validate import validateEmail, validatePhone * - from typing import Optional as Opt */ export declare class PythonImportExtractor implements LanguageImportExtractor { readonly importNodeTypes: string[]; /** * Extract the clean dotted module path for the `imports` list (used by * test-association discovery and dependency analysis) — never the raw * statement text. Delegates to `processImportSymbols()` so the `imports` * list and the `importedSymbols` map are always derived from the same * computation and can never disagree. * * Shapes: * - `import os` -> "os"; `import os as system` -> "os" (module, not alias) * - `import x.y` / `import x.y as z` -> "x.y" * - `from utils.validate import X` -> "utils.validate" * - Relative (#904): `from . import X` -> "./"; `from .foo import X` -> * "./foo"; `from ..pkg import Y` -> "../pkg" — `convertPythonRelativeImport` * (below) converts the grammar's leading-dot form to a `./`/`../`-prefixed * specifier, mirroring `RustImportExtractor`'s `super::` -> `../` * conversion, so `resolveRelativeImport()` in * `../../utils/path-matching.js` can resolve it against the importer's * own directory the same way it already resolves a JS `./foo` specifier * (see `chunker.ts`'s `RESOLVE_RELATIVE_IMPORTS`, which threads `filepath` * through for Python too). * * A statement with multiple comma-separated modules (`import a, b.c`) * yields only the first (`"a"`) — a pre-existing limitation of * `processPythonImport()`, not a new one introduced here. * * Wildcard from-imports (`from x.y import *`) still yield the module path * (`"x.y"`) — `collectImportedSymbols()` records a `'*'` placeholder symbol * (mirroring `RustImportExtractor.processUseWildcard()`) so the statement * isn't dropped entirely just because it names no specific symbols. */ extractImportPath(node: SyntaxNode): string | null; extractImportPaths(node: SyntaxNode): string[]; processImportSymbols(node: SyntaxNode): { importPath: string; symbols: string[]; } | null; processImportSymbolsList(node: SyntaxNode): Array<{ importPath: string; symbols: string[]; }>; private processSimpleImport; private processAliasedImport; /** * Process Python regular import statement. * e.g., "import os", "import os as system" */ private processPythonImport; private findModulePath; private collectImportedSymbols; /** * Process Python from...import statement. * e.g., "from utils.validate import validateEmail, validatePhone" */ private processPythonFromImport; } /** * Python symbol extractor * * Handles: * - function_definition (def foo():) * - async_function_definition (async def foo():) * - class_definition (class Foo:) * * `parentClass` is threaded into `extractClassInfo` (not just function * extraction) so a nested class (`class Outer:\n class Inner: ...`) * reports its enclosing class — `PythonTraverser.findParentContainerName` * already resolves this for every top-level node, not just methods (#949). * * Call sites: call (foo(), obj.method()) */ export declare class PythonSymbolExtractor implements LanguageSymbolExtractor { readonly symbolNodeTypes: string[]; extractSymbol(node: SyntaxNode, content: string, parentClass?: string): SymbolInfo | null; /** * Unwrap `decorated_definition` (decorator(s) + a function/class field) to the * inner definition's symbol info, so decorated functions/methods/classes carry * the same name/type/complexity/callSites as their undecorated counterparts. * The decorator source is folded into `signature` so it isn't silently dropped - * mirrors how e.g. Java's `@Override` naturally stays part of the signature text * (there it's a sibling child of the same node, not a separate wrapper node). */ private extractDecoratedInfo; extractCallSite(node: SyntaxNode): { symbol: string; line: number; key: string; } | null; private extractFunctionInfo; private extractClassInfo; } export declare const pythonDefinition: LanguageDefinition; //# sourceMappingURL=python.d.ts.map