@alloy-js/python 0.1.0-dev.4 → 0.1.0-dev.6

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.
Files changed (181) hide show
  1. package/dist/src/builtins/python.js +2 -1
  2. package/dist/src/builtins/python.js.map +1 -0
  3. package/dist/src/components/Atom.js +2 -1
  4. package/dist/src/components/Atom.js.map +1 -0
  5. package/dist/src/components/CallSignature.d.ts.map +1 -1
  6. package/dist/src/components/CallSignature.js +10 -12
  7. package/dist/src/components/CallSignature.js.map +1 -0
  8. package/dist/src/components/ClassDeclaration.d.ts.map +1 -1
  9. package/dist/src/components/ClassDeclaration.js +8 -21
  10. package/dist/src/components/ClassDeclaration.js.map +1 -0
  11. package/dist/src/components/ClassInstantiation.d.ts.map +1 -1
  12. package/dist/src/components/ClassInstantiation.js +6 -5
  13. package/dist/src/components/ClassInstantiation.js.map +1 -0
  14. package/dist/src/components/Declaration.d.ts +1 -5
  15. package/dist/src/components/Declaration.d.ts.map +1 -1
  16. package/dist/src/components/Declaration.js +8 -16
  17. package/dist/src/components/Declaration.js.map +1 -0
  18. package/dist/src/components/EnumDeclaration.d.ts.map +1 -1
  19. package/dist/src/components/EnumDeclaration.js +35 -60
  20. package/dist/src/components/EnumDeclaration.js.map +1 -0
  21. package/dist/src/components/EnumMember.d.ts.map +1 -1
  22. package/dist/src/components/EnumMember.js +5 -5
  23. package/dist/src/components/EnumMember.js.map +1 -0
  24. package/dist/src/components/FunctionCallExpression.js +2 -1
  25. package/dist/src/components/FunctionCallExpression.js.map +1 -0
  26. package/dist/src/components/FunctionDeclaration.d.ts.map +1 -1
  27. package/dist/src/components/FunctionDeclaration.js +8 -16
  28. package/dist/src/components/FunctionDeclaration.js.map +1 -0
  29. package/dist/src/components/ImportStatement.js +2 -1
  30. package/dist/src/components/ImportStatement.js.map +1 -0
  31. package/dist/src/components/LexicalScope.d.ts +8 -0
  32. package/dist/src/components/LexicalScope.d.ts.map +1 -0
  33. package/dist/src/components/LexicalScope.js +22 -0
  34. package/dist/src/components/LexicalScope.js.map +1 -0
  35. package/dist/src/components/MemberExpression.js +2 -1
  36. package/dist/src/components/MemberExpression.js.map +1 -0
  37. package/dist/src/components/MemberScope.d.ts +8 -0
  38. package/dist/src/components/MemberScope.d.ts.map +1 -0
  39. package/dist/src/components/MemberScope.js +16 -0
  40. package/dist/src/components/MemberScope.js.map +1 -0
  41. package/dist/src/components/NoNamePolicy.js +2 -1
  42. package/dist/src/components/NoNamePolicy.js.map +1 -0
  43. package/dist/src/components/PyDoc.js +2 -1
  44. package/dist/src/components/PyDoc.js.map +1 -0
  45. package/dist/src/components/PythonBlock.js +2 -1
  46. package/dist/src/components/PythonBlock.js.map +1 -0
  47. package/dist/src/components/Reference.js +2 -1
  48. package/dist/src/components/Reference.js.map +1 -0
  49. package/dist/src/components/SourceFile.js +3 -3
  50. package/dist/src/components/SourceFile.js.map +1 -0
  51. package/dist/src/components/StatementList.js +2 -1
  52. package/dist/src/components/StatementList.js.map +1 -0
  53. package/dist/src/components/UnionTypeExpression.js +2 -1
  54. package/dist/src/components/UnionTypeExpression.js.map +1 -0
  55. package/dist/src/components/VariableDeclaration.d.ts.map +1 -1
  56. package/dist/src/components/VariableDeclaration.js +10 -32
  57. package/dist/src/components/VariableDeclaration.js.map +1 -0
  58. package/dist/src/components/index.d.ts +2 -0
  59. package/dist/src/components/index.d.ts.map +1 -1
  60. package/dist/src/components/index.js +4 -1
  61. package/dist/src/components/index.js.map +1 -0
  62. package/dist/src/create-module.d.ts.map +1 -1
  63. package/dist/src/create-module.js +5 -5
  64. package/dist/src/create-module.js.map +1 -0
  65. package/dist/src/index.js +2 -1
  66. package/dist/src/index.js.map +1 -0
  67. package/dist/src/name-conflict-resolver.d.ts +3 -0
  68. package/dist/src/name-conflict-resolver.d.ts.map +1 -0
  69. package/dist/src/name-conflict-resolver.js +8 -0
  70. package/dist/src/name-conflict-resolver.js.map +1 -0
  71. package/dist/src/name-policy.js +2 -1
  72. package/dist/src/name-policy.js.map +1 -0
  73. package/dist/src/parameter-descriptor.js +2 -1
  74. package/dist/src/parameter-descriptor.js.map +1 -0
  75. package/dist/src/symbol-creation.d.ts +13 -2
  76. package/dist/src/symbol-creation.d.ts.map +1 -1
  77. package/dist/src/symbol-creation.js +35 -10
  78. package/dist/src/symbol-creation.js.map +1 -0
  79. package/dist/src/symbols/index.d.ts +1 -1
  80. package/dist/src/symbols/index.d.ts.map +1 -1
  81. package/dist/src/symbols/index.js +3 -2
  82. package/dist/src/symbols/index.js.map +1 -0
  83. package/dist/src/symbols/python-lexical-scope.d.ts +7 -0
  84. package/dist/src/symbols/python-lexical-scope.d.ts.map +1 -0
  85. package/dist/src/symbols/python-lexical-scope.js +15 -0
  86. package/dist/src/symbols/python-lexical-scope.js.map +1 -0
  87. package/dist/src/symbols/python-member-scope.d.ts +3 -4
  88. package/dist/src/symbols/python-member-scope.d.ts.map +1 -1
  89. package/dist/src/symbols/python-member-scope.js +6 -8
  90. package/dist/src/symbols/python-member-scope.js.map +1 -0
  91. package/dist/src/symbols/python-module-scope.d.ts +4 -9
  92. package/dist/src/symbols/python-module-scope.d.ts.map +1 -1
  93. package/dist/src/symbols/python-module-scope.js +8 -15
  94. package/dist/src/symbols/python-module-scope.js.map +1 -0
  95. package/dist/src/symbols/python-output-symbol.d.ts +10 -7
  96. package/dist/src/symbols/python-output-symbol.d.ts.map +1 -1
  97. package/dist/src/symbols/python-output-symbol.js +25 -7
  98. package/dist/src/symbols/python-output-symbol.js.map +1 -0
  99. package/dist/src/symbols/reference.d.ts +2 -2
  100. package/dist/src/symbols/reference.d.ts.map +1 -1
  101. package/dist/src/symbols/reference.js +37 -36
  102. package/dist/src/symbols/reference.js.map +1 -0
  103. package/dist/src/symbols/scopes.d.ts +3 -1
  104. package/dist/src/symbols/scopes.d.ts.map +1 -1
  105. package/dist/src/symbols/scopes.js +10 -1
  106. package/dist/src/symbols/scopes.js.map +1 -0
  107. package/dist/src/utils.js +2 -1
  108. package/dist/src/utils.js.map +1 -0
  109. package/dist/test/callsignatures.test.js +2 -1
  110. package/dist/test/callsignatures.test.js.map +1 -0
  111. package/dist/test/classdeclarations.test.js +89 -53
  112. package/dist/test/classdeclarations.test.js.map +1 -0
  113. package/dist/test/classinstantiations.test.js +2 -1
  114. package/dist/test/classinstantiations.test.js.map +1 -0
  115. package/dist/test/enums.test.js +10 -3
  116. package/dist/test/enums.test.js.map +1 -0
  117. package/dist/test/externals.test.js +8 -6
  118. package/dist/test/externals.test.js.map +1 -0
  119. package/dist/test/functioncallexpressions.test.js +2 -1
  120. package/dist/test/functioncallexpressions.test.js.map +1 -0
  121. package/dist/test/functiondeclaration.test.js +75 -37
  122. package/dist/test/functiondeclaration.test.js.map +1 -0
  123. package/dist/test/imports.test.js +11 -37
  124. package/dist/test/imports.test.js.map +1 -0
  125. package/dist/test/memberexpressions.test.js +2 -1
  126. package/dist/test/memberexpressions.test.js.map +1 -0
  127. package/dist/test/namepolicies.test.js +2 -1
  128. package/dist/test/namepolicies.test.js.map +1 -0
  129. package/dist/test/pydocs.test.js +2 -1
  130. package/dist/test/pydocs.test.js.map +1 -0
  131. package/dist/test/references.test.js +2 -1
  132. package/dist/test/references.test.js.map +1 -0
  133. package/dist/test/sourcefiles.test.js +2 -1
  134. package/dist/test/sourcefiles.test.js.map +1 -0
  135. package/dist/test/uniontypeexpression.test.js +2 -1
  136. package/dist/test/uniontypeexpression.test.js.map +1 -0
  137. package/dist/test/utils.d.ts +2 -3
  138. package/dist/test/utils.d.ts.map +1 -1
  139. package/dist/test/utils.js +8 -4
  140. package/dist/test/utils.js.map +1 -0
  141. package/dist/test/values.test.js +2 -1
  142. package/dist/test/values.test.js.map +1 -0
  143. package/dist/test/variables.test.js +13 -12
  144. package/dist/test/variables.test.js.map +1 -0
  145. package/dist/tsconfig.tsbuildinfo +1 -1
  146. package/package.json +3 -3
  147. package/src/components/CallSignature.tsx +9 -17
  148. package/src/components/ClassDeclaration.tsx +5 -32
  149. package/src/components/ClassInstantiation.tsx +6 -12
  150. package/src/components/Declaration.tsx +1 -20
  151. package/src/components/EnumDeclaration.tsx +18 -41
  152. package/src/components/EnumMember.tsx +1 -3
  153. package/src/components/FunctionDeclaration.tsx +5 -24
  154. package/src/components/LexicalScope.tsx +24 -0
  155. package/src/components/MemberScope.tsx +18 -0
  156. package/src/components/SourceFile.tsx +2 -2
  157. package/src/components/VariableDeclaration.tsx +7 -35
  158. package/src/components/index.ts +2 -0
  159. package/src/create-module.ts +7 -13
  160. package/src/name-conflict-resolver.ts +21 -0
  161. package/src/symbol-creation.ts +50 -11
  162. package/src/symbols/index.ts +1 -1
  163. package/src/symbols/python-lexical-scope.ts +16 -0
  164. package/src/symbols/python-member-scope.ts +4 -8
  165. package/src/symbols/python-module-scope.ts +6 -32
  166. package/src/symbols/python-output-symbol.ts +36 -10
  167. package/src/symbols/reference.tsx +70 -0
  168. package/src/symbols/scopes.ts +15 -1
  169. package/temp/api.json +897 -539
  170. package/test/classdeclarations.test.tsx +66 -31
  171. package/test/enums.test.tsx +2 -2
  172. package/test/externals.test.tsx +6 -7
  173. package/test/functiondeclaration.test.tsx +48 -39
  174. package/test/imports.test.tsx +11 -36
  175. package/test/utils.tsx +11 -5
  176. package/test/variables.test.tsx +11 -7
  177. package/dist/src/symbols/custom-output-scope.d.ts +0 -10
  178. package/dist/src/symbols/custom-output-scope.d.ts.map +0 -1
  179. package/dist/src/symbols/custom-output-scope.js +0 -25
  180. package/src/symbols/custom-output-scope.ts +0 -35
  181. package/src/symbols/reference.ts +0 -99
@@ -1,16 +1,29 @@
1
- import { refkey, useContext } from "@alloy-js/core";
1
+ import {
2
+ OutputScopeOptions,
3
+ OutputSpace,
4
+ useBinder,
5
+ useContext,
6
+ } from "@alloy-js/core";
2
7
  import { PythonSourceFileContext } from "./components/SourceFile.js";
3
8
  import { PythonElements, usePythonNamePolicy } from "./name-policy.js";
4
9
  import {
5
- CreatePythonSymbolOptions,
6
10
  PythonOutputSymbol,
11
+ PythonOutputSymbolOptions,
12
+ usePythonScope,
7
13
  } from "./symbols/index.js";
14
+ import { PythonLexicalScope } from "./symbols/python-lexical-scope.js";
8
15
 
16
+ interface CreatePythonSymbolOptions extends PythonOutputSymbolOptions {
17
+ space?: OutputSpace;
18
+ instance?: boolean;
19
+ }
20
+ /**
21
+ * Creates a symbol for a python declaration in the current scope.
22
+ */
9
23
  export function createPythonSymbol(
10
24
  name: string,
11
- options: CreatePythonSymbolOptions,
25
+ options: CreatePythonSymbolOptions = {},
12
26
  kind?: PythonElements,
13
- createRefkeyIfNeeded = false,
14
27
  ): PythonOutputSymbol {
15
28
  let processedName = name;
16
29
  const sfContext = useContext(PythonSourceFileContext);
@@ -21,16 +34,42 @@ export function createPythonSymbol(
21
34
  processedName = namePolicy.getName(name, kind);
22
35
  }
23
36
  }
37
+ const currentScope = usePythonScope();
38
+ let targetSpace = options.space ?? undefined;
39
+ if (!options.space && currentScope) {
40
+ if (currentScope.isMemberScope) {
41
+ if (options.instance) {
42
+ targetSpace = currentScope.ownerSymbol!.instanceMembers;
43
+ } else {
44
+ targetSpace = currentScope.ownerSymbol!.staticMembers;
45
+ }
46
+ } else {
47
+ if (options.instance) {
48
+ throw new Error(
49
+ `Cannot declare instance variable ${name} outside of a member scope`,
50
+ );
51
+ }
52
+ targetSpace = (currentScope as PythonLexicalScope).symbols;
53
+ }
54
+ }
55
+
56
+ const binder = options.binder ?? currentScope?.binder ?? useBinder();
24
57
 
25
- return new PythonOutputSymbol(processedName, {
26
- binder: options.binder,
58
+ return new PythonOutputSymbol(processedName, targetSpace, {
59
+ binder: binder,
27
60
  aliasTarget: options.aliasTarget,
28
- scope: options.scope,
29
- refkeys:
30
- options.refkeys ??
31
- (createRefkeyIfNeeded ? refkey(processedName) : undefined),
32
- flags: options.flags,
61
+ refkeys: options.refkeys,
33
62
  metadata: options.metadata,
34
63
  module: sfContext?.module,
64
+ type: options.type,
35
65
  });
36
66
  }
67
+
68
+ export function createLexicalScope(
69
+ name: string,
70
+ options: OutputScopeOptions = {},
71
+ ) {
72
+ const parent = usePythonScope();
73
+
74
+ return new PythonLexicalScope(name, parent, options);
75
+ }
@@ -1,4 +1,4 @@
1
- export * from "./custom-output-scope.js";
1
+ export * from "./python-lexical-scope.js";
2
2
  export * from "./python-member-scope.js";
3
3
  export * from "./python-module-scope.js";
4
4
  export * from "./python-output-symbol.js";
@@ -0,0 +1,16 @@
1
+ import { OutputScope } from "@alloy-js/core";
2
+
3
+ export class PythonLexicalScope extends OutputScope {
4
+ public static readonly declarationSpaces: readonly string[] = ["symbols"];
5
+
6
+ get symbols() {
7
+ return this.spaceFor("symbols")!;
8
+ }
9
+
10
+ // Lexical scopes do not have an owner symbol. This ensures that we get the
11
+ // correct type when using `usePythonScope` (i.e. we don't get the
12
+ // OutputScope's `OutputSymbol | undefined` type).
13
+ get ownerSymbol(): undefined {
14
+ return undefined;
15
+ }
16
+ }
@@ -1,12 +1,8 @@
1
- import { CustomOutputScope } from "./custom-output-scope.js";
1
+ import { OutputScope } from "@alloy-js/core";
2
2
  import { PythonOutputSymbol } from "./python-output-symbol.js";
3
3
 
4
- export class PythonMemberScope extends CustomOutputScope {
5
- get kind() {
6
- return "member" as const;
7
- }
8
-
9
- get owner() {
10
- return super.owner as PythonOutputSymbol;
4
+ export class PythonMemberScope extends OutputScope {
5
+ get ownerSymbol() {
6
+ return super.ownerSymbol as PythonOutputSymbol;
11
7
  }
12
8
  }
@@ -1,6 +1,5 @@
1
1
  import { reactive, shallowReactive } from "@alloy-js/core";
2
- import { createPythonSymbol } from "../symbol-creation.js";
3
- import { CustomOutputScope } from "./custom-output-scope.js";
2
+ import { PythonLexicalScope } from "./python-lexical-scope.js";
4
3
  import { PythonOutputSymbol } from "./python-output-symbol.js";
5
4
 
6
5
  export class ImportedSymbol {
@@ -21,23 +20,9 @@ export interface ImportRecordProps {
21
20
  symbols: Set<ImportedSymbol>;
22
21
  }
23
22
 
24
- export type ImportRecords = Map<PythonModuleScope, ImportRecordProps>;
25
-
26
- export const ImportRecords = Map as {
27
- new (): ImportRecords;
28
- new (
29
- entries?:
30
- | readonly (readonly [PythonModuleScope, ImportRecordProps])[]
31
- | null,
32
- ): ImportRecords;
33
- prototype: Map<PythonModuleScope, ImportRecordProps>;
34
- };
35
-
36
- export class PythonModuleScope extends CustomOutputScope {
37
- get kind() {
38
- return "module" as const;
39
- }
23
+ export class ImportRecords extends Map<PythonModuleScope, ImportRecordProps> {}
40
24
 
25
+ export class PythonModuleScope extends PythonLexicalScope {
41
26
  #importedSymbols: Map<PythonOutputSymbol, PythonOutputSymbol> =
42
27
  shallowReactive(new Map());
43
28
  get importedSymbols() {
@@ -55,29 +40,18 @@ export class PythonModuleScope extends CustomOutputScope {
55
40
  return existing;
56
41
  }
57
42
 
58
- if (targetModule.kind !== "module") {
59
- throw new Error("Cannot import symbol that isn't in module scope");
60
- }
61
-
62
43
  if (!this.importedModules.has(targetModule)) {
63
44
  this.importedModules.set(targetModule, {
64
45
  symbols: new Set<ImportedSymbol>(),
65
46
  });
66
47
  }
67
48
 
68
- const localSymbol = createPythonSymbol(
49
+ const localSymbol = new PythonOutputSymbol(
69
50
  targetSymbol.name,
70
- {
71
- binder: this.binder,
72
- scope: this,
73
- aliasTarget: targetSymbol,
74
- },
75
- undefined,
76
- false,
51
+ this.symbols,
52
+ { binder: this.binder, aliasTarget: targetSymbol },
77
53
  );
78
54
 
79
- targetSymbol.copyTo(localSymbol);
80
-
81
55
  this.importedSymbols.set(targetSymbol, localSymbol);
82
56
  this.importedModules.get(targetModule)!.symbols?.add({
83
57
  local: localSymbol,
@@ -1,12 +1,11 @@
1
- import { OutputSymbol, OutputSymbolOptions } from "@alloy-js/core";
2
- import { PythonMemberScope } from "./python-member-scope.js";
1
+ import { OutputSpace, OutputSymbol, OutputSymbolOptions } from "@alloy-js/core";
3
2
 
4
- export interface CreatePythonSymbolOptions extends OutputSymbolOptions {
3
+ export interface PythonOutputSymbolOptions extends OutputSymbolOptions {
5
4
  module?: string;
6
5
  }
7
6
 
8
7
  export interface CreatePythonSymbolFunctionOptions
9
- extends CreatePythonSymbolOptions {
8
+ extends PythonOutputSymbolOptions {
10
9
  name: string;
11
10
  }
12
11
 
@@ -14,8 +13,14 @@ export interface CreatePythonSymbolFunctionOptions
14
13
  * Represents an 'exported' symbol from a .py file. Class, enum, interface etc.
15
14
  */
16
15
  export class PythonOutputSymbol extends OutputSymbol {
17
- constructor(name: string, options: CreatePythonSymbolOptions) {
18
- super(name, options);
16
+ static readonly memberSpaces = ["static", "instance"] as const;
17
+
18
+ constructor(
19
+ name: string,
20
+ spaces: OutputSpace[] | OutputSpace | undefined,
21
+ options: PythonOutputSymbolOptions,
22
+ ) {
23
+ super(name, spaces, options);
19
24
  this.#module = options.module ?? undefined;
20
25
  }
21
26
 
@@ -26,11 +31,32 @@ export class PythonOutputSymbol extends OutputSymbol {
26
31
  return this.#module;
27
32
  }
28
33
 
29
- set module(value: string | undefined) {
30
- this.#module = value;
34
+ get staticMembers() {
35
+ return this.memberSpaceFor("static")!;
36
+ }
37
+
38
+ get instanceMembers() {
39
+ return this.memberSpaceFor("instance")!;
40
+ }
41
+
42
+ get isStaticMemberSymbol() {
43
+ return !this.isInstanceMemberSymbol;
31
44
  }
32
45
 
33
- get instanceMemberScope() {
34
- return super.instanceMemberScope as PythonMemberScope | undefined;
46
+ get isInstanceMemberSymbol() {
47
+ return this.spaces.some((s) => s.key === "instance");
48
+ }
49
+
50
+ copy() {
51
+ const copy = new PythonOutputSymbol(this.name, undefined, {
52
+ binder: this.binder,
53
+ aliasTarget: this.aliasTarget,
54
+ module: this.module,
55
+ metadata: this.metadata,
56
+ });
57
+
58
+ this.initializeCopy(copy);
59
+
60
+ return copy;
35
61
  }
36
62
  }
@@ -0,0 +1,70 @@
1
+ import {
2
+ Children,
3
+ memo,
4
+ Refkey,
5
+ resolve,
6
+ untrack,
7
+ useContext,
8
+ } from "@alloy-js/core";
9
+ import { MemberExpression } from "../components/MemberExpression.jsx";
10
+ import { PythonSourceFileContext } from "../components/SourceFile.jsx";
11
+ import {
12
+ PythonModuleScope,
13
+ PythonOutputScope,
14
+ PythonOutputSymbol,
15
+ } from "./index.js";
16
+
17
+ export function ref(
18
+ refkey: Refkey,
19
+ ): () => [Children, PythonOutputSymbol | undefined] {
20
+ const sourceFile = useContext(PythonSourceFileContext);
21
+ const resolveResult = resolve<PythonOutputScope, PythonOutputSymbol>(
22
+ refkey as Refkey,
23
+ );
24
+
25
+ return memo(() => {
26
+ if (resolveResult.value === undefined) {
27
+ return ["<Unresolved Symbol>", undefined];
28
+ }
29
+
30
+ const { commonScope, lexicalDeclaration, symbol, pathDown, memberPath } =
31
+ resolveResult.value;
32
+
33
+ // Where the target declaration is relative to the referencing scope.
34
+ // * module: target symbol is in a different module
35
+ // * local: target symbol is within the current module
36
+ const targetLocation =
37
+ pathDown[0] instanceof PythonModuleScope ? "module" : "local";
38
+ let localSymbol: PythonOutputSymbol | undefined;
39
+
40
+ if (targetLocation === "module") {
41
+ localSymbol = untrack(() =>
42
+ sourceFile!.scope.addImport(
43
+ lexicalDeclaration,
44
+ pathDown[0] as PythonModuleScope,
45
+ ),
46
+ );
47
+ }
48
+
49
+ const parts = [];
50
+
51
+ if (commonScope && commonScope.isMemberScope) {
52
+ // we are referencing a member of a type we are inside
53
+ if (lexicalDeclaration.isInstanceMemberSymbol) {
54
+ parts.push(<MemberExpression.Part id="self" />);
55
+ } else {
56
+ parts.push(<MemberExpression.Part symbol={commonScope.ownerSymbol} />);
57
+ }
58
+ parts.push(<MemberExpression.Part symbol={lexicalDeclaration} />);
59
+ } else {
60
+ parts.push(
61
+ <MemberExpression.Part symbol={localSymbol ?? lexicalDeclaration} />,
62
+ );
63
+ }
64
+ for (const part of memberPath) {
65
+ parts.push(<MemberExpression.Part symbol={part} />);
66
+ }
67
+
68
+ return [<MemberExpression children={parts} />, localSymbol ?? symbol];
69
+ });
70
+ }
@@ -1,9 +1,23 @@
1
1
  import { useScope } from "@alloy-js/core";
2
+ import { PythonLexicalScope } from "./python-lexical-scope.js";
2
3
  import { PythonMemberScope } from "./python-member-scope.js";
3
4
  import { PythonModuleScope } from "./python-module-scope.js";
4
5
 
5
- export type PythonOutputScope = PythonModuleScope | PythonMemberScope;
6
+ export type PythonOutputScope =
7
+ | PythonLexicalScope
8
+ | PythonModuleScope
9
+ | PythonMemberScope;
6
10
 
7
11
  export function usePythonScope() {
8
12
  return useScope() as PythonOutputScope;
9
13
  }
14
+
15
+ export function usePythonLexicalScope() {
16
+ const scope = usePythonScope();
17
+ if (!(scope instanceof PythonLexicalScope)) {
18
+ throw new Error(
19
+ "Expected a PythonLexicalScope, but got " + scope.constructor.name,
20
+ );
21
+ }
22
+ return scope;
23
+ }