@suss/adapter-python 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -0
- package/dist/index.cjs +2287 -733
- package/dist/index.d.cts +148 -3
- package/dist/index.d.ts +148 -3
- package/dist/index.js +1938 -356
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -2,7 +2,8 @@ import { TypeShape, BehavioralSummary } from '@suss/behavioral-ir';
|
|
|
2
2
|
import { Tree, Node } from 'web-tree-sitter';
|
|
3
3
|
export { Node as PyNode, Tree as PyTree } from 'web-tree-sitter';
|
|
4
4
|
import { Database } from '@suss/datalog';
|
|
5
|
-
import { ExtractorOptions, RawCodeStructure } from '@suss/extractor';
|
|
5
|
+
import { ExtractorOptions, RawCodeStructure, TimingReport, ExtractionReport, CacheDiagnostic } from '@suss/extractor';
|
|
6
|
+
import { WhyExplained } from '@suss/resolution';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* A new `Parser` for every call, so that parses running at the same time do
|
|
@@ -10,6 +11,18 @@ import { ExtractorOptions, RawCodeStructure } from '@suss/extractor';
|
|
|
10
11
|
* is loaded once per process and shared.
|
|
11
12
|
*/
|
|
12
13
|
declare function parsePython(source: string): Promise<Tree>;
|
|
14
|
+
/**
|
|
15
|
+
* Load the grammar ahead of time, for a caller whose own entry point is
|
|
16
|
+
* async but whose parsing happens later through `parsePythonSync`. Loading
|
|
17
|
+
* the WASM grammar is the only async part; parsing a tree from it is not.
|
|
18
|
+
*/
|
|
19
|
+
declare function preloadPythonGrammar(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* `parsePython` without the await, for a caller that cannot itself be
|
|
22
|
+
* async. Throws if `preloadPythonGrammar` (or `parsePython`) has not
|
|
23
|
+
* already loaded the grammar in this process.
|
|
24
|
+
*/
|
|
25
|
+
declare function parsePythonSync(source: string): Tree;
|
|
13
26
|
|
|
14
27
|
/**
|
|
15
28
|
* The lexical binder. It builds module, class, and function scopes over one
|
|
@@ -184,6 +197,22 @@ declare function classifyDecorator(decoratorNode: Node, scope: Scope): Decorator
|
|
|
184
197
|
*/
|
|
185
198
|
interface PythonPack {
|
|
186
199
|
name: string;
|
|
200
|
+
/**
|
|
201
|
+
* Pack version stamp, which feeds the cache invalidation key. Bump on
|
|
202
|
+
* any change that affects discovered units or extracted summaries.
|
|
203
|
+
* The CLI folds a hash of the loaded pack file and its config into
|
|
204
|
+
* this stamp on top, so a pack run through the CLI invalidates on an
|
|
205
|
+
* edit whether or not it declares a version of its own.
|
|
206
|
+
*/
|
|
207
|
+
version?: string;
|
|
208
|
+
/**
|
|
209
|
+
* Files under the project this pack reads that are not among the
|
|
210
|
+
* `.py` files a run walks, given the files the run is about to walk.
|
|
211
|
+
* Their content feeds the same cache key the pack's own config does,
|
|
212
|
+
* so an edit to one of them re-extracts instead of handing back the
|
|
213
|
+
* previous answer.
|
|
214
|
+
*/
|
|
215
|
+
discoveryInputs?: (files: readonly string[]) => string[];
|
|
187
216
|
/** Wire protocol for the produced boundary bindings, e.g. "http". */
|
|
188
217
|
protocol: string;
|
|
189
218
|
discovery: PythonDiscoveryPattern[];
|
|
@@ -394,13 +423,16 @@ type NoValuePrefix = "unstated" | "unreadable";
|
|
|
394
423
|
*/
|
|
395
424
|
type PathRepeatedSlashes = "kept" | "merged";
|
|
396
425
|
|
|
426
|
+
/**
|
|
427
|
+
* What discovery uses for one file. `factsPath` is the path the facts were
|
|
428
|
+
* keyed under, which is the absolute one, while a summary shows the short one.
|
|
429
|
+
*/
|
|
397
430
|
interface StorageLookup {
|
|
398
431
|
readonly facts: Database;
|
|
399
432
|
readonly factsPath: string;
|
|
400
433
|
readonly patterns: readonly StoragePattern[];
|
|
401
434
|
readonly definitionAt: (key: string) => Node | undefined;
|
|
402
435
|
readonly couldMatch: ReadonlySet<string>;
|
|
403
|
-
readonly leadsToStorage: ReadonlySet<string>;
|
|
404
436
|
/** What a pack says about statements a project writes as SQL itself. */
|
|
405
437
|
readonly rawSql?: readonly RawSqlPattern[];
|
|
406
438
|
}
|
|
@@ -554,6 +586,12 @@ declare function objectReturnedBy(db: Database, callKey: string): string | null;
|
|
|
554
586
|
* call and its callee start at the same offset.
|
|
555
587
|
*/
|
|
556
588
|
declare function nodeId(filePath: string, node: Node): string;
|
|
589
|
+
/**
|
|
590
|
+
* The key a read of this expression joins on, for a caller that has an
|
|
591
|
+
* expression in hand and wants to ask the rules about it. `enclosing` is
|
|
592
|
+
* the function the expression is written in, or null at module level.
|
|
593
|
+
*/
|
|
594
|
+
declare function readKey(filePath: string, node: Node, enclosing: Node | null): string;
|
|
557
595
|
/**
|
|
558
596
|
* Walk a module and emit the value facts. A nested function is walked in its
|
|
559
597
|
* own right, so a body's returns and calls belong to the function that wrote
|
|
@@ -561,6 +599,59 @@ declare function nodeId(filePath: string, node: Node): string;
|
|
|
561
599
|
*/
|
|
562
600
|
declare function emitValueFacts(db: Database, filePath: string, root: Node): void;
|
|
563
601
|
|
|
602
|
+
/**
|
|
603
|
+
* The session behind `suss ask why` on a Python project: a tree-sitter
|
|
604
|
+
* parse of the asked-about source, a way to point at the expression
|
|
605
|
+
* somebody spelled, and the witness proof of what it resolved to,
|
|
606
|
+
* rendered through `@suss/resolution`'s phrases.
|
|
607
|
+
*
|
|
608
|
+
* It parses every file under the root and emits the same value facts
|
|
609
|
+
* `extractPythonProject` does, keeping a location for every fact key so
|
|
610
|
+
* a proof's atoms can point back at source. A handle this session hands
|
|
611
|
+
* back pairs a tree-sitter node with the file it came from, since a
|
|
612
|
+
* node alone does not say which file parsed it.
|
|
613
|
+
*/
|
|
614
|
+
|
|
615
|
+
interface PythonWhySessionOptions {
|
|
616
|
+
/** The project root, which paths in every answer come out relative to. */
|
|
617
|
+
dir: string;
|
|
618
|
+
}
|
|
619
|
+
/** A found node, paired with the file it was parsed from. */
|
|
620
|
+
interface PythonValueHandle {
|
|
621
|
+
file: string;
|
|
622
|
+
node: Node;
|
|
623
|
+
}
|
|
624
|
+
declare class PythonWhySession {
|
|
625
|
+
private readonly root;
|
|
626
|
+
private readonly db;
|
|
627
|
+
private readonly locations;
|
|
628
|
+
private readonly trees;
|
|
629
|
+
constructor(options: PythonWhySessionOptions);
|
|
630
|
+
/**
|
|
631
|
+
* The smallest expression on `line` of `file` whose text is exactly
|
|
632
|
+
* `text`, or null.
|
|
633
|
+
*/
|
|
634
|
+
findExpression(file: string, line: number, text: string): PythonValueHandle | null;
|
|
635
|
+
/**
|
|
636
|
+
* The callee of the call written as `calleeText` between `startLine`
|
|
637
|
+
* and `endLine` of `file`, or null.
|
|
638
|
+
*/
|
|
639
|
+
findCallee(file: string, startLine: number, endLine: number, calleeText: string): PythonValueHandle | null;
|
|
640
|
+
/**
|
|
641
|
+
* Why `value` resolves to what it does: the witness proof, flattened
|
|
642
|
+
* to the chain and rendered. Null when the value does not resolve,
|
|
643
|
+
* which the caller says in its own words.
|
|
644
|
+
*/
|
|
645
|
+
explain(value: PythonValueHandle, options?: {
|
|
646
|
+
maxDepth?: number;
|
|
647
|
+
}): WhyExplained | null;
|
|
648
|
+
private locate;
|
|
649
|
+
private rootOf;
|
|
650
|
+
private pathOf;
|
|
651
|
+
/** A file path said relative to the root, or as given when it is outside the root. */
|
|
652
|
+
private displayPath;
|
|
653
|
+
}
|
|
654
|
+
|
|
564
655
|
/**
|
|
565
656
|
* The name is part of the key because the range is measured in lines, two
|
|
566
657
|
* units can start on the same line, and `entry` is a set, so keying on the range
|
|
@@ -589,8 +680,18 @@ interface ExtractPythonOptions {
|
|
|
589
680
|
roots: string[];
|
|
590
681
|
/** When set, `location.file` on each summary is relativized against this. */
|
|
591
682
|
workspaceRoot?: string;
|
|
683
|
+
/** The directory a summary's id measures its file from, when that differs from `workspaceRoot`. */
|
|
684
|
+
projectRoot?: string;
|
|
592
685
|
/** As well as deciding how much of what nobody could read reaches a summary, "strict" lets a route that cannot be built stop the run. */
|
|
593
686
|
gapHandling?: ExtractorOptions["gapHandling"];
|
|
687
|
+
/** Called once with the run's per-phase wall time, for `suss extract --timing`. */
|
|
688
|
+
onTiming?: (report: TimingReport) => void;
|
|
689
|
+
/** Called once with the file-by-file funnel, for `suss extract --explain`. */
|
|
690
|
+
onExtractionReport?: (report: ExtractionReport) => void;
|
|
691
|
+
/** Called once with what the cache decided, for `suss extract --timing`. */
|
|
692
|
+
onCacheDiagnostic?: (diagnostic: CacheDiagnostic) => void;
|
|
693
|
+
/** Absolute. `<projectRoot>/.suss/cache` by default; `null` turns it off. */
|
|
694
|
+
cacheDir?: string | null;
|
|
594
695
|
}
|
|
595
696
|
interface ExtractPythonResult {
|
|
596
697
|
summaries: BehavioralSummary[];
|
|
@@ -600,4 +701,48 @@ declare function extractPythonProject(options: ExtractPythonOptions): Promise<Ex
|
|
|
600
701
|
/** Every `.py` file under `root`, depth-first, skipping the usual non-source directories. */
|
|
601
702
|
declare function findPythonFiles(root: string): string[];
|
|
602
703
|
|
|
603
|
-
|
|
704
|
+
/**
|
|
705
|
+
* Evidence for drafting a project-wrapper dependency stub: every
|
|
706
|
+
* import, anywhere in the project, of the asked module or one of its
|
|
707
|
+
* submodules. A Python decorator pattern matches a wrapper's import
|
|
708
|
+
* module exactly (see discovery.ts's `importModule.includes`), so a
|
|
709
|
+
* stub covers one imported module at a time rather than one package,
|
|
710
|
+
* and this groups by the exact module text a project writes.
|
|
711
|
+
*
|
|
712
|
+
* This walks every node rather than going through the binder in
|
|
713
|
+
* scope.ts, so an import inside an `if` or `try` still counts as
|
|
714
|
+
* evidence even though the binder would not resolve a name through it.
|
|
715
|
+
*/
|
|
716
|
+
interface PythonImportSite {
|
|
717
|
+
/** The name imported at this site, null for a bare `import module`, which binds the whole module rather than one name from it. */
|
|
718
|
+
name: string | null;
|
|
719
|
+
file: string;
|
|
720
|
+
line: number;
|
|
721
|
+
}
|
|
722
|
+
interface PythonImportEvidence {
|
|
723
|
+
/** The full dotted module text, exactly as a stub's `package` would spell it. */
|
|
724
|
+
module: string;
|
|
725
|
+
sites: PythonImportSite[];
|
|
726
|
+
}
|
|
727
|
+
interface PythonImportEvidenceOptions {
|
|
728
|
+
packageName: string;
|
|
729
|
+
directory: string;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Every import of `packageName`, or a submodule of it, across the
|
|
733
|
+
* project's own files, grouped by the exact module each was imported
|
|
734
|
+
* from.
|
|
735
|
+
*/
|
|
736
|
+
declare function pythonImportEvidence(options: PythonImportEvidenceOptions): Promise<PythonImportEvidence[]>;
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* version.ts: this adapter's own half of the cache key.
|
|
740
|
+
*
|
|
741
|
+
* `ADAPTER_VERSION` is the hand-bumped semver. Bump it on any change
|
|
742
|
+
* that affects extraction output: IR shape, discovery semantics,
|
|
743
|
+
* terminal classification, anything that would invalidate previously
|
|
744
|
+
* cached summaries.
|
|
745
|
+
*/
|
|
746
|
+
declare const ADAPTER_VERSION = "0.1.0";
|
|
747
|
+
|
|
748
|
+
export { ADAPTER_VERSION, type AnnotationContext, type Binding, type BoundPythonFile, type DecoratedClassRoute, type DecoratedFunctionRoute, type DecoratorArg, type DecoratorClassification, type DiscoveryOptions, type ExtractPythonOptions, type ExtractPythonResult, type ModuleBinding, type ModuleResolution, type ModuleResolverOptions, type MountObjectCarrier, type MountObjectPrefix, type MountPrefixEffect, type NoValuePrefix, type PathRepeatedSlashes, type PrefixTrailingSlash, type PythonDiscoveryPattern, type PythonImportEvidence, type PythonImportEvidenceOptions, type PythonImportSite, type PythonPack, type PythonValueHandle, PythonWhySession, type PythonWhySessionOptions, type RawSqlPattern, type RelativeModuleSpec, type RouteConventions, type RoutePrefixResolution, type RouterComposition, type RouterIndex, type Scope, type ScopeKind, type StoragePattern, annotationToShape, bindModule, buildRouterIndex, classifyDecorator, containedValues, discoverUnits, emitEntryFact, emitModuleImportFacts, emitValueFacts, extractPythonProject, findPythonFiles, nodeId, objectReturnedBy, parsePython, parsePythonSync, preloadPythonGrammar, pythonImportEvidence, readKey, resolveAbsoluteModule, resolveCalls, resolveModule, resolveName, resolveRelativeModule, shapeFromName, unitKey };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { TypeShape, BehavioralSummary } from '@suss/behavioral-ir';
|
|
|
2
2
|
import { Tree, Node } from 'web-tree-sitter';
|
|
3
3
|
export { Node as PyNode, Tree as PyTree } from 'web-tree-sitter';
|
|
4
4
|
import { Database } from '@suss/datalog';
|
|
5
|
-
import { ExtractorOptions, RawCodeStructure } from '@suss/extractor';
|
|
5
|
+
import { ExtractorOptions, RawCodeStructure, TimingReport, ExtractionReport, CacheDiagnostic } from '@suss/extractor';
|
|
6
|
+
import { WhyExplained } from '@suss/resolution';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* A new `Parser` for every call, so that parses running at the same time do
|
|
@@ -10,6 +11,18 @@ import { ExtractorOptions, RawCodeStructure } from '@suss/extractor';
|
|
|
10
11
|
* is loaded once per process and shared.
|
|
11
12
|
*/
|
|
12
13
|
declare function parsePython(source: string): Promise<Tree>;
|
|
14
|
+
/**
|
|
15
|
+
* Load the grammar ahead of time, for a caller whose own entry point is
|
|
16
|
+
* async but whose parsing happens later through `parsePythonSync`. Loading
|
|
17
|
+
* the WASM grammar is the only async part; parsing a tree from it is not.
|
|
18
|
+
*/
|
|
19
|
+
declare function preloadPythonGrammar(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* `parsePython` without the await, for a caller that cannot itself be
|
|
22
|
+
* async. Throws if `preloadPythonGrammar` (or `parsePython`) has not
|
|
23
|
+
* already loaded the grammar in this process.
|
|
24
|
+
*/
|
|
25
|
+
declare function parsePythonSync(source: string): Tree;
|
|
13
26
|
|
|
14
27
|
/**
|
|
15
28
|
* The lexical binder. It builds module, class, and function scopes over one
|
|
@@ -184,6 +197,22 @@ declare function classifyDecorator(decoratorNode: Node, scope: Scope): Decorator
|
|
|
184
197
|
*/
|
|
185
198
|
interface PythonPack {
|
|
186
199
|
name: string;
|
|
200
|
+
/**
|
|
201
|
+
* Pack version stamp, which feeds the cache invalidation key. Bump on
|
|
202
|
+
* any change that affects discovered units or extracted summaries.
|
|
203
|
+
* The CLI folds a hash of the loaded pack file and its config into
|
|
204
|
+
* this stamp on top, so a pack run through the CLI invalidates on an
|
|
205
|
+
* edit whether or not it declares a version of its own.
|
|
206
|
+
*/
|
|
207
|
+
version?: string;
|
|
208
|
+
/**
|
|
209
|
+
* Files under the project this pack reads that are not among the
|
|
210
|
+
* `.py` files a run walks, given the files the run is about to walk.
|
|
211
|
+
* Their content feeds the same cache key the pack's own config does,
|
|
212
|
+
* so an edit to one of them re-extracts instead of handing back the
|
|
213
|
+
* previous answer.
|
|
214
|
+
*/
|
|
215
|
+
discoveryInputs?: (files: readonly string[]) => string[];
|
|
187
216
|
/** Wire protocol for the produced boundary bindings, e.g. "http". */
|
|
188
217
|
protocol: string;
|
|
189
218
|
discovery: PythonDiscoveryPattern[];
|
|
@@ -394,13 +423,16 @@ type NoValuePrefix = "unstated" | "unreadable";
|
|
|
394
423
|
*/
|
|
395
424
|
type PathRepeatedSlashes = "kept" | "merged";
|
|
396
425
|
|
|
426
|
+
/**
|
|
427
|
+
* What discovery uses for one file. `factsPath` is the path the facts were
|
|
428
|
+
* keyed under, which is the absolute one, while a summary shows the short one.
|
|
429
|
+
*/
|
|
397
430
|
interface StorageLookup {
|
|
398
431
|
readonly facts: Database;
|
|
399
432
|
readonly factsPath: string;
|
|
400
433
|
readonly patterns: readonly StoragePattern[];
|
|
401
434
|
readonly definitionAt: (key: string) => Node | undefined;
|
|
402
435
|
readonly couldMatch: ReadonlySet<string>;
|
|
403
|
-
readonly leadsToStorage: ReadonlySet<string>;
|
|
404
436
|
/** What a pack says about statements a project writes as SQL itself. */
|
|
405
437
|
readonly rawSql?: readonly RawSqlPattern[];
|
|
406
438
|
}
|
|
@@ -554,6 +586,12 @@ declare function objectReturnedBy(db: Database, callKey: string): string | null;
|
|
|
554
586
|
* call and its callee start at the same offset.
|
|
555
587
|
*/
|
|
556
588
|
declare function nodeId(filePath: string, node: Node): string;
|
|
589
|
+
/**
|
|
590
|
+
* The key a read of this expression joins on, for a caller that has an
|
|
591
|
+
* expression in hand and wants to ask the rules about it. `enclosing` is
|
|
592
|
+
* the function the expression is written in, or null at module level.
|
|
593
|
+
*/
|
|
594
|
+
declare function readKey(filePath: string, node: Node, enclosing: Node | null): string;
|
|
557
595
|
/**
|
|
558
596
|
* Walk a module and emit the value facts. A nested function is walked in its
|
|
559
597
|
* own right, so a body's returns and calls belong to the function that wrote
|
|
@@ -561,6 +599,59 @@ declare function nodeId(filePath: string, node: Node): string;
|
|
|
561
599
|
*/
|
|
562
600
|
declare function emitValueFacts(db: Database, filePath: string, root: Node): void;
|
|
563
601
|
|
|
602
|
+
/**
|
|
603
|
+
* The session behind `suss ask why` on a Python project: a tree-sitter
|
|
604
|
+
* parse of the asked-about source, a way to point at the expression
|
|
605
|
+
* somebody spelled, and the witness proof of what it resolved to,
|
|
606
|
+
* rendered through `@suss/resolution`'s phrases.
|
|
607
|
+
*
|
|
608
|
+
* It parses every file under the root and emits the same value facts
|
|
609
|
+
* `extractPythonProject` does, keeping a location for every fact key so
|
|
610
|
+
* a proof's atoms can point back at source. A handle this session hands
|
|
611
|
+
* back pairs a tree-sitter node with the file it came from, since a
|
|
612
|
+
* node alone does not say which file parsed it.
|
|
613
|
+
*/
|
|
614
|
+
|
|
615
|
+
interface PythonWhySessionOptions {
|
|
616
|
+
/** The project root, which paths in every answer come out relative to. */
|
|
617
|
+
dir: string;
|
|
618
|
+
}
|
|
619
|
+
/** A found node, paired with the file it was parsed from. */
|
|
620
|
+
interface PythonValueHandle {
|
|
621
|
+
file: string;
|
|
622
|
+
node: Node;
|
|
623
|
+
}
|
|
624
|
+
declare class PythonWhySession {
|
|
625
|
+
private readonly root;
|
|
626
|
+
private readonly db;
|
|
627
|
+
private readonly locations;
|
|
628
|
+
private readonly trees;
|
|
629
|
+
constructor(options: PythonWhySessionOptions);
|
|
630
|
+
/**
|
|
631
|
+
* The smallest expression on `line` of `file` whose text is exactly
|
|
632
|
+
* `text`, or null.
|
|
633
|
+
*/
|
|
634
|
+
findExpression(file: string, line: number, text: string): PythonValueHandle | null;
|
|
635
|
+
/**
|
|
636
|
+
* The callee of the call written as `calleeText` between `startLine`
|
|
637
|
+
* and `endLine` of `file`, or null.
|
|
638
|
+
*/
|
|
639
|
+
findCallee(file: string, startLine: number, endLine: number, calleeText: string): PythonValueHandle | null;
|
|
640
|
+
/**
|
|
641
|
+
* Why `value` resolves to what it does: the witness proof, flattened
|
|
642
|
+
* to the chain and rendered. Null when the value does not resolve,
|
|
643
|
+
* which the caller says in its own words.
|
|
644
|
+
*/
|
|
645
|
+
explain(value: PythonValueHandle, options?: {
|
|
646
|
+
maxDepth?: number;
|
|
647
|
+
}): WhyExplained | null;
|
|
648
|
+
private locate;
|
|
649
|
+
private rootOf;
|
|
650
|
+
private pathOf;
|
|
651
|
+
/** A file path said relative to the root, or as given when it is outside the root. */
|
|
652
|
+
private displayPath;
|
|
653
|
+
}
|
|
654
|
+
|
|
564
655
|
/**
|
|
565
656
|
* The name is part of the key because the range is measured in lines, two
|
|
566
657
|
* units can start on the same line, and `entry` is a set, so keying on the range
|
|
@@ -589,8 +680,18 @@ interface ExtractPythonOptions {
|
|
|
589
680
|
roots: string[];
|
|
590
681
|
/** When set, `location.file` on each summary is relativized against this. */
|
|
591
682
|
workspaceRoot?: string;
|
|
683
|
+
/** The directory a summary's id measures its file from, when that differs from `workspaceRoot`. */
|
|
684
|
+
projectRoot?: string;
|
|
592
685
|
/** As well as deciding how much of what nobody could read reaches a summary, "strict" lets a route that cannot be built stop the run. */
|
|
593
686
|
gapHandling?: ExtractorOptions["gapHandling"];
|
|
687
|
+
/** Called once with the run's per-phase wall time, for `suss extract --timing`. */
|
|
688
|
+
onTiming?: (report: TimingReport) => void;
|
|
689
|
+
/** Called once with the file-by-file funnel, for `suss extract --explain`. */
|
|
690
|
+
onExtractionReport?: (report: ExtractionReport) => void;
|
|
691
|
+
/** Called once with what the cache decided, for `suss extract --timing`. */
|
|
692
|
+
onCacheDiagnostic?: (diagnostic: CacheDiagnostic) => void;
|
|
693
|
+
/** Absolute. `<projectRoot>/.suss/cache` by default; `null` turns it off. */
|
|
694
|
+
cacheDir?: string | null;
|
|
594
695
|
}
|
|
595
696
|
interface ExtractPythonResult {
|
|
596
697
|
summaries: BehavioralSummary[];
|
|
@@ -600,4 +701,48 @@ declare function extractPythonProject(options: ExtractPythonOptions): Promise<Ex
|
|
|
600
701
|
/** Every `.py` file under `root`, depth-first, skipping the usual non-source directories. */
|
|
601
702
|
declare function findPythonFiles(root: string): string[];
|
|
602
703
|
|
|
603
|
-
|
|
704
|
+
/**
|
|
705
|
+
* Evidence for drafting a project-wrapper dependency stub: every
|
|
706
|
+
* import, anywhere in the project, of the asked module or one of its
|
|
707
|
+
* submodules. A Python decorator pattern matches a wrapper's import
|
|
708
|
+
* module exactly (see discovery.ts's `importModule.includes`), so a
|
|
709
|
+
* stub covers one imported module at a time rather than one package,
|
|
710
|
+
* and this groups by the exact module text a project writes.
|
|
711
|
+
*
|
|
712
|
+
* This walks every node rather than going through the binder in
|
|
713
|
+
* scope.ts, so an import inside an `if` or `try` still counts as
|
|
714
|
+
* evidence even though the binder would not resolve a name through it.
|
|
715
|
+
*/
|
|
716
|
+
interface PythonImportSite {
|
|
717
|
+
/** The name imported at this site, null for a bare `import module`, which binds the whole module rather than one name from it. */
|
|
718
|
+
name: string | null;
|
|
719
|
+
file: string;
|
|
720
|
+
line: number;
|
|
721
|
+
}
|
|
722
|
+
interface PythonImportEvidence {
|
|
723
|
+
/** The full dotted module text, exactly as a stub's `package` would spell it. */
|
|
724
|
+
module: string;
|
|
725
|
+
sites: PythonImportSite[];
|
|
726
|
+
}
|
|
727
|
+
interface PythonImportEvidenceOptions {
|
|
728
|
+
packageName: string;
|
|
729
|
+
directory: string;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Every import of `packageName`, or a submodule of it, across the
|
|
733
|
+
* project's own files, grouped by the exact module each was imported
|
|
734
|
+
* from.
|
|
735
|
+
*/
|
|
736
|
+
declare function pythonImportEvidence(options: PythonImportEvidenceOptions): Promise<PythonImportEvidence[]>;
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* version.ts: this adapter's own half of the cache key.
|
|
740
|
+
*
|
|
741
|
+
* `ADAPTER_VERSION` is the hand-bumped semver. Bump it on any change
|
|
742
|
+
* that affects extraction output: IR shape, discovery semantics,
|
|
743
|
+
* terminal classification, anything that would invalidate previously
|
|
744
|
+
* cached summaries.
|
|
745
|
+
*/
|
|
746
|
+
declare const ADAPTER_VERSION = "0.1.0";
|
|
747
|
+
|
|
748
|
+
export { ADAPTER_VERSION, type AnnotationContext, type Binding, type BoundPythonFile, type DecoratedClassRoute, type DecoratedFunctionRoute, type DecoratorArg, type DecoratorClassification, type DiscoveryOptions, type ExtractPythonOptions, type ExtractPythonResult, type ModuleBinding, type ModuleResolution, type ModuleResolverOptions, type MountObjectCarrier, type MountObjectPrefix, type MountPrefixEffect, type NoValuePrefix, type PathRepeatedSlashes, type PrefixTrailingSlash, type PythonDiscoveryPattern, type PythonImportEvidence, type PythonImportEvidenceOptions, type PythonImportSite, type PythonPack, type PythonValueHandle, PythonWhySession, type PythonWhySessionOptions, type RawSqlPattern, type RelativeModuleSpec, type RouteConventions, type RoutePrefixResolution, type RouterComposition, type RouterIndex, type Scope, type ScopeKind, type StoragePattern, annotationToShape, bindModule, buildRouterIndex, classifyDecorator, containedValues, discoverUnits, emitEntryFact, emitModuleImportFacts, emitValueFacts, extractPythonProject, findPythonFiles, nodeId, objectReturnedBy, parsePython, parsePythonSync, preloadPythonGrammar, pythonImportEvidence, readKey, resolveAbsoluteModule, resolveCalls, resolveModule, resolveName, resolveRelativeModule, shapeFromName, unitKey };
|