@alloy-js/python 0.3.0-dev.1 → 0.3.0-dev.2

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 (34) hide show
  1. package/dist/src/builtins/python.d.ts +3 -0
  2. package/dist/src/builtins/python.d.ts.map +1 -1
  3. package/dist/src/builtins/python.js +6 -0
  4. package/dist/src/builtins/python.js.map +1 -1
  5. package/dist/src/components/DataclassDeclaration.d.ts +41 -0
  6. package/dist/src/components/DataclassDeclaration.d.ts.map +1 -0
  7. package/dist/src/components/DataclassDeclaration.js +150 -0
  8. package/dist/src/components/DataclassDeclaration.js.map +1 -0
  9. package/dist/src/components/PyDoc.d.ts.map +1 -1
  10. package/dist/src/components/PyDoc.js +59 -15
  11. package/dist/src/components/PyDoc.js.map +1 -1
  12. package/dist/src/components/UnionTypeExpression.d.ts.map +1 -1
  13. package/dist/src/components/UnionTypeExpression.js +6 -6
  14. package/dist/src/components/UnionTypeExpression.js.map +1 -1
  15. package/dist/src/components/index.d.ts +1 -0
  16. package/dist/src/components/index.d.ts.map +1 -1
  17. package/dist/src/components/index.js +1 -0
  18. package/dist/src/components/index.js.map +1 -1
  19. package/dist/test/dataclassdeclarations.test.d.ts +2 -0
  20. package/dist/test/dataclassdeclarations.test.d.ts.map +1 -0
  21. package/dist/test/dataclassdeclarations.test.js +630 -0
  22. package/dist/test/dataclassdeclarations.test.js.map +1 -0
  23. package/dist/test/pydocs.test.js +11 -19
  24. package/dist/test/pydocs.test.js.map +1 -1
  25. package/dist/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +1 -1
  27. package/src/builtins/python.ts +7 -0
  28. package/src/components/DataclassDeclaration.tsx +185 -0
  29. package/src/components/PyDoc.tsx +66 -20
  30. package/src/components/UnionTypeExpression.tsx +4 -7
  31. package/src/components/index.ts +1 -0
  32. package/temp/api.json +267 -0
  33. package/test/dataclassdeclarations.test.tsx +585 -0
  34. package/test/pydocs.test.tsx +11 -24
@@ -0,0 +1,185 @@
1
+ import { For, Show } from "@alloy-js/core";
2
+ import { snakeCase } from "change-case";
3
+ import { dataclassesModule } from "../builtins/python.js";
4
+ import { usePythonScope } from "../symbols/scopes.js";
5
+ import { Atom } from "./Atom.jsx";
6
+ import type { ClassDeclarationProps } from "./ClassDeclaration.js";
7
+ import { ClassDeclaration } from "./ClassDeclaration.js";
8
+ import { StatementList } from "./StatementList.js";
9
+
10
+ /**
11
+ * Validate decorator-only rules that do not depend on class members.
12
+ */
13
+ function validateDataclassDecoratorArgs(kwargs: DataclassDecoratorKwargs) {
14
+ if (kwargs.weakrefSlot === true && kwargs.slots !== true) {
15
+ throw new Error(
16
+ "weakref_slot=True requires slots=True in @dataclass decorator",
17
+ );
18
+ }
19
+ if (kwargs.order === true && kwargs.eq === false) {
20
+ throw new Error("order=True requires eq=True in @dataclass decorator");
21
+ }
22
+ }
23
+
24
+ /**
25
+ * Validate symbol-level conflicts. Must be called from within a member scope
26
+ * (inside the class body) so member symbols are available.
27
+ */
28
+ function validateDataclassMemberConflicts(kwargs: DataclassDecoratorKwargs) {
29
+ const scope = usePythonScope();
30
+ const owner: any = (scope as any).ownerSymbol;
31
+ if (!owner) return;
32
+
33
+ const hasMemberNamed = (name: string): boolean => {
34
+ const instanceNames: Set<string> | undefined = (
35
+ owner.instanceMembers as any
36
+ )?.symbolNames;
37
+ const staticNames: Set<string> | undefined = (owner.staticMembers as any)
38
+ ?.symbolNames;
39
+ return Boolean(instanceNames?.has(name) || staticNames?.has(name));
40
+ };
41
+
42
+ if (kwargs.order === true) {
43
+ for (const m of ["__lt__", "__le__", "__gt__", "__ge__"]) {
44
+ if (hasMemberNamed(m)) {
45
+ throw new TypeError(
46
+ `Cannot specify order=True when the class already defines ${m}()`,
47
+ );
48
+ }
49
+ }
50
+ }
51
+
52
+ if (kwargs.unsafeHash === true && hasMemberNamed("__hash__")) {
53
+ throw new TypeError(
54
+ "Cannot specify unsafe_hash=True when the class already defines __hash__()",
55
+ );
56
+ }
57
+
58
+ if (kwargs.frozen === true) {
59
+ if (hasMemberNamed("__setattr__")) {
60
+ throw new TypeError(
61
+ "Cannot specify frozen=True when the class already defines __setattr__()",
62
+ );
63
+ }
64
+ if (hasMemberNamed("__delattr__")) {
65
+ throw new TypeError(
66
+ "Cannot specify frozen=True when the class already defines __delattr__()",
67
+ );
68
+ }
69
+ }
70
+
71
+ if (kwargs.slots === true && hasMemberNamed("__slots__")) {
72
+ throw new TypeError(
73
+ "Cannot specify slots=True when the class already defines __slots__()",
74
+ );
75
+ }
76
+
77
+ // Enforce at most one KW_ONLY sentinel as a symbol
78
+ let kwOnlyCount = 0;
79
+ for (const sym of owner.instanceMembers as Iterable<any>) {
80
+ if (sym.originalName === "_") kwOnlyCount++;
81
+ }
82
+ if (kwOnlyCount > 1) {
83
+ throw new Error("Only one KW_ONLY sentinel is allowed per dataclass body");
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Allowed keyword arguments for the Python `@dataclass(...)` decorator.
89
+ * Single source of truth: runtime keys and compile-time type are derived here.
90
+ */
91
+ export const dataclassDecoratorKeys = [
92
+ "init",
93
+ "repr",
94
+ "eq",
95
+ "order",
96
+ "unsafeHash",
97
+ "frozen",
98
+ "matchArgs",
99
+ "kwOnly",
100
+ "slots",
101
+ "weakrefSlot",
102
+ ] as const;
103
+ export const dataclassDecoratorKeySet = new Set<string>(
104
+ dataclassDecoratorKeys as unknown as string[],
105
+ );
106
+ export type DataclassDecoratorKey = (typeof dataclassDecoratorKeys)[number];
107
+ export type DataclassDecoratorKwargs = Partial<
108
+ Record<DataclassDecoratorKey, boolean>
109
+ >;
110
+
111
+ export interface DataclassDeclarationProps
112
+ extends ClassDeclarationProps,
113
+ DataclassDecoratorKwargs {}
114
+
115
+ /**
116
+ * Renders a Python dataclass.
117
+ *
118
+ * Example:
119
+ * ```tsx
120
+ * <py.DataclassDeclaration name="User" kwOnly>
121
+ * <py.VariableDeclaration instanceVariable omitNone name="id" type="int" />
122
+ * <py.VariableDeclaration instanceVariable name={namekey("_", { ignoreNamePolicy: true })} type={dataclassesModule["."].KW_ONLY} omitNone />
123
+ * <py.VariableDeclaration
124
+ * instanceVariable
125
+ * name="name"
126
+ * type="str"
127
+ * initializer={"Anonymous"}
128
+ * />
129
+ * </py.DataclassDeclaration>
130
+ * ```
131
+ * Will render as:
132
+ * ```py
133
+ * from dataclasses import dataclass
134
+ * from dataclasses import KW_ONLY
135
+ *
136
+ * @dataclass(kw_only=True)
137
+ * class User:
138
+ * id: int
139
+ * _: KW_ONLY
140
+ * name: str = "Anonymous"
141
+ * ```
142
+ */
143
+ export function DataclassDeclaration(props: DataclassDeclarationProps) {
144
+ // Collect flags from props in the order they appear (preserves emission order)
145
+ const decoratorEntries: Array<[string, any]> = [];
146
+ const kwargs = {} as DataclassDecoratorKwargs;
147
+ for (const key of Object.keys(props)) {
148
+ // Only include known flags; skip undefined values
149
+ if (dataclassDecoratorKeySet.has(key)) {
150
+ const value = (props as any)[key];
151
+ if (value !== undefined) {
152
+ (kwargs as any)[key] = value;
153
+ decoratorEntries.push([snakeCase(key), value]);
154
+ }
155
+ }
156
+ }
157
+ const hasDecoratorArgs = decoratorEntries.length > 0;
158
+
159
+ if (hasDecoratorArgs) {
160
+ validateDataclassDecoratorArgs(kwargs);
161
+ }
162
+
163
+ return (
164
+ <>
165
+ {"@"}
166
+ {dataclassesModule["."].dataclass}
167
+ <Show when={hasDecoratorArgs}>
168
+ (
169
+ <For each={decoratorEntries} comma space>
170
+ {([k, v]) => (
171
+ <>
172
+ {k}=<Atom jsValue={v} />
173
+ </>
174
+ )}
175
+ </For>
176
+ )
177
+ </Show>
178
+ <hbr />
179
+ <ClassDeclaration name={props.name} bases={props.bases} doc={props.doc}>
180
+ <StatementList>{props.children}</StatementList>
181
+ {validateDataclassMemberConflicts(kwargs as DataclassDecoratorKwargs)}
182
+ </ClassDeclaration>
183
+ </>
184
+ );
185
+ }
@@ -6,6 +6,8 @@ import {
6
6
  Prose,
7
7
  Show,
8
8
  childrenArray,
9
+ computed,
10
+ isKeyedChild,
9
11
  } from "@alloy-js/core";
10
12
  import { ParameterDescriptor } from "../parameter-descriptor.js";
11
13
  import { Atom } from "./Atom.jsx";
@@ -265,26 +267,50 @@ export interface PyDocExampleProps {
265
267
  * Create a PyDoc example, which is prepended by \>\>.
266
268
  */
267
269
  export function PyDocExample(props: PyDocExampleProps) {
268
- const children = childrenArray(() => props.children);
269
- let lines: string[] = [];
270
+ const lines = computed(() => {
271
+ const kids = childrenArray(() => props.children, {
272
+ preserveFragments: true,
273
+ });
274
+ const out: Children[] = [];
275
+
276
+ const isBr = (node: any): boolean => {
277
+ if (node == null) return false;
278
+ const keyed = isKeyedChild(node as any);
279
+ const tag = keyed ? (node as any).tag : (node as any)?.tag;
280
+ const kind = (node as any)?.kind;
281
+ // Consider only <br /> as a line splitter (not rendered as content).
282
+ return tag === "br" || kind === "br";
283
+ };
284
+
285
+ // Handles a single string child: split on newlines to produce lines.
286
+ const splitAndTrim = (s: string): string[] =>
287
+ s
288
+ .split(/\r?\n/)
289
+ .map((x) => x.trim())
290
+ .filter((x) => x.length > 0);
291
+
292
+ if (kids.length === 1 && typeof kids[0] === "string") {
293
+ return splitAndTrim(kids[0] as string);
294
+ }
270
295
 
271
- if (children.length === 1 && typeof children[0] === "string") {
272
- // Split, trim each line, and filter out empty lines
273
- lines = children[0]
274
- .split(/\r?\n/)
275
- .map((line) => line.trim())
276
- .filter((line) => line.length > 0);
277
- } else {
278
- // For non-string children, filter out empty/whitespace-only strings
279
- lines = children
280
- .map((child) => (typeof child === "string" ? child : ""))
281
- .map((line) => line.trim())
282
- .filter((line) => line.length > 0);
283
- }
296
+ // Handles mixed children: each child becomes a line, string children
297
+ // may include embedded newlines, and <br /> acts as a line split.
298
+ for (const child of kids) {
299
+ if (child == null || isBr(child)) continue;
300
+ if (typeof child === "string") {
301
+ // String children: split on newlines to produce lines.
302
+ for (const seg of splitAndTrim(child)) out.push(seg);
303
+ } else {
304
+ // Non-string child (component/fragment) are preserved as their own doctest line.
305
+ out.push(child);
306
+ }
307
+ }
308
+ return out;
309
+ });
284
310
 
285
311
  return (
286
312
  <>
287
- <For each={lines}>
313
+ <For each={lines.value}>
288
314
  {(line) => (
289
315
  <>
290
316
  {">> "}
@@ -301,12 +327,32 @@ export interface SimpleCommentBlockProps {
301
327
  }
302
328
 
303
329
  export function SimpleCommentBlock(props: SimpleCommentBlockProps) {
330
+ const children = childrenArray(() => props.children);
331
+ let content: Children;
332
+ if (children.length === 1 && typeof children[0] === "string") {
333
+ const raw = children[0] as string;
334
+ if (raw.includes("\n") || raw.includes("\\n")) {
335
+ const parts = raw.split(/\r?\n|\\n/);
336
+ content = (
337
+ <>
338
+ {parts.map((p, i) => (
339
+ <>
340
+ <Prose>{p}</Prose>
341
+ {i < parts.length - 1 && <hbr />}
342
+ </>
343
+ ))}
344
+ </>
345
+ );
346
+ } else {
347
+ content = <Prose>{props.children}</Prose>;
348
+ }
349
+ } else {
350
+ content = <Prose>{props.children}</Prose>;
351
+ }
352
+
304
353
  return (
305
354
  <>
306
- #{" "}
307
- <align string="# ">
308
- <Prose>{props.children}</Prose>
309
- </align>
355
+ # <align string="# ">{content}</align>
310
356
  </>
311
357
  );
312
358
  }
@@ -1,26 +1,23 @@
1
- import { Children, For, childrenArray } from "@alloy-js/core";
1
+ import { Children, List } from "@alloy-js/core";
2
2
 
3
3
  export interface UnionTypeExpressionProps {
4
4
  children: Children;
5
5
  }
6
6
 
7
7
  export function UnionTypeExpression(props: UnionTypeExpressionProps) {
8
- const items = childrenArray(() => props.children);
9
8
  return (
10
9
  <group>
11
10
  <ifBreak>(</ifBreak>
12
11
  <indent>
13
12
  <sbr />
14
- <For
15
- each={items}
13
+ <List
14
+ children={props.children}
16
15
  joiner={
17
16
  <>
18
17
  <br />|{" "}
19
18
  </>
20
19
  }
21
- >
22
- {(child) => child}
23
- </For>
20
+ />
24
21
  </indent>
25
22
  <sbr />
26
23
  <ifBreak>)</ifBreak>
@@ -4,6 +4,7 @@ export * from "./ClassDeclaration.js";
4
4
  export * from "./ClassInstantiation.js";
5
5
  export * from "./ClassMethodDeclaration.js";
6
6
  export * from "./ConstructorDeclaration.js";
7
+ export * from "./DataclassDeclaration.js";
7
8
  export * from "./Declaration.js";
8
9
  export * from "./DunderMethodDeclaration.js";
9
10
  export * from "./EnumDeclaration.js";
package/temp/api.json CHANGED
@@ -2358,6 +2358,273 @@
2358
2358
  }
2359
2359
  ]
2360
2360
  },
2361
+ {
2362
+ "kind": "Function",
2363
+ "canonicalReference": "@alloy-js/python!DataclassDeclaration:function(1)",
2364
+ "docComment": "/**\n * Renders a Python dataclass.\n *\n * Example:\n * ```tsx\n * <py.DataclassDeclaration name=\"User\" kwOnly>\n * <py.VariableDeclaration instanceVariable omitNone name=\"id\" type=\"int\" />\n * <py.VariableDeclaration instanceVariable name={namekey(\"_\", { ignoreNamePolicy: true })} type={dataclassesModule[\".\"].KW_ONLY} omitNone />\n * <py.VariableDeclaration\n * instanceVariable\n * name=\"name\"\n * type=\"str\"\n * initializer={\"Anonymous\"}\n * />\n * </py.DataclassDeclaration>\n * ```\n *\n * Will render as:\n * ```py\n * from dataclasses import dataclass\n * from dataclasses import KW_ONLY\n *\n * @dataclass(kw_only=True)\n * class User:\n * id: int\n * _: KW_ONLY\n * name: str = \"Anonymous\"\n * ```\n *\n */\n",
2365
+ "excerptTokens": [
2366
+ {
2367
+ "kind": "Content",
2368
+ "text": "export declare function DataclassDeclaration(props: "
2369
+ },
2370
+ {
2371
+ "kind": "Reference",
2372
+ "text": "DataclassDeclarationProps",
2373
+ "canonicalReference": "@alloy-js/python!DataclassDeclarationProps:interface"
2374
+ },
2375
+ {
2376
+ "kind": "Content",
2377
+ "text": "): "
2378
+ },
2379
+ {
2380
+ "kind": "Content",
2381
+ "text": "import(\"@alloy-js/core\")."
2382
+ },
2383
+ {
2384
+ "kind": "Reference",
2385
+ "text": "Children",
2386
+ "canonicalReference": "@alloy-js/core!Children:type"
2387
+ },
2388
+ {
2389
+ "kind": "Content",
2390
+ "text": ";"
2391
+ }
2392
+ ],
2393
+ "fileUrlPath": "src/components/DataclassDeclaration.tsx",
2394
+ "returnTypeTokenRange": {
2395
+ "startIndex": 3,
2396
+ "endIndex": 5
2397
+ },
2398
+ "releaseTag": "Public",
2399
+ "overloadIndex": 1,
2400
+ "parameters": [
2401
+ {
2402
+ "parameterName": "props",
2403
+ "parameterTypeTokenRange": {
2404
+ "startIndex": 1,
2405
+ "endIndex": 2
2406
+ },
2407
+ "isOptional": false
2408
+ }
2409
+ ],
2410
+ "name": "DataclassDeclaration"
2411
+ },
2412
+ {
2413
+ "kind": "Interface",
2414
+ "canonicalReference": "@alloy-js/python!DataclassDeclarationProps:interface",
2415
+ "docComment": "",
2416
+ "excerptTokens": [
2417
+ {
2418
+ "kind": "Content",
2419
+ "text": "export interface DataclassDeclarationProps extends "
2420
+ },
2421
+ {
2422
+ "kind": "Reference",
2423
+ "text": "ClassDeclarationProps",
2424
+ "canonicalReference": "@alloy-js/python!ClassDeclarationProps:interface"
2425
+ },
2426
+ {
2427
+ "kind": "Content",
2428
+ "text": ", "
2429
+ },
2430
+ {
2431
+ "kind": "Reference",
2432
+ "text": "DataclassDecoratorKwargs",
2433
+ "canonicalReference": "@alloy-js/python!DataclassDecoratorKwargs:type"
2434
+ },
2435
+ {
2436
+ "kind": "Content",
2437
+ "text": " "
2438
+ }
2439
+ ],
2440
+ "fileUrlPath": "src/components/DataclassDeclaration.tsx",
2441
+ "releaseTag": "Public",
2442
+ "name": "DataclassDeclarationProps",
2443
+ "preserveMemberOrder": false,
2444
+ "members": [],
2445
+ "extendsTokenRanges": [
2446
+ {
2447
+ "startIndex": 1,
2448
+ "endIndex": 2
2449
+ },
2450
+ {
2451
+ "startIndex": 3,
2452
+ "endIndex": 4
2453
+ }
2454
+ ]
2455
+ },
2456
+ {
2457
+ "kind": "TypeAlias",
2458
+ "canonicalReference": "@alloy-js/python!DataclassDecoratorKey:type",
2459
+ "docComment": "",
2460
+ "excerptTokens": [
2461
+ {
2462
+ "kind": "Content",
2463
+ "text": "export type DataclassDecoratorKey = "
2464
+ },
2465
+ {
2466
+ "kind": "Content",
2467
+ "text": "(typeof "
2468
+ },
2469
+ {
2470
+ "kind": "Reference",
2471
+ "text": "dataclassDecoratorKeys",
2472
+ "canonicalReference": "@alloy-js/python!dataclassDecoratorKeys:var"
2473
+ },
2474
+ {
2475
+ "kind": "Content",
2476
+ "text": ")[number]"
2477
+ },
2478
+ {
2479
+ "kind": "Content",
2480
+ "text": ";"
2481
+ }
2482
+ ],
2483
+ "fileUrlPath": "src/components/DataclassDeclaration.tsx",
2484
+ "releaseTag": "Public",
2485
+ "name": "DataclassDecoratorKey",
2486
+ "typeTokenRange": {
2487
+ "startIndex": 1,
2488
+ "endIndex": 4
2489
+ }
2490
+ },
2491
+ {
2492
+ "kind": "Variable",
2493
+ "canonicalReference": "@alloy-js/python!dataclassDecoratorKeys:var",
2494
+ "docComment": "/**\n * Allowed keyword arguments for the Python `@dataclass(...)` decorator.\n * Single source of truth: runtime keys and compile-time type are derived here.\n */\n",
2495
+ "excerptTokens": [
2496
+ {
2497
+ "kind": "Content",
2498
+ "text": "dataclassDecoratorKeys: "
2499
+ },
2500
+ {
2501
+ "kind": "Content",
2502
+ "text": "readonly [\"init\", \"repr\", \"eq\", \"order\", \"unsafeHash\", \"frozen\", \"matchArgs\", \"kwOnly\", \"slots\", \"weakrefSlot\"]"
2503
+ }
2504
+ ],
2505
+ "fileUrlPath": "src/components/DataclassDeclaration.tsx",
2506
+ "isReadonly": true,
2507
+ "releaseTag": "Public",
2508
+ "name": "dataclassDecoratorKeys",
2509
+ "variableTypeTokenRange": {
2510
+ "startIndex": 1,
2511
+ "endIndex": 2
2512
+ }
2513
+ },
2514
+ {
2515
+ "kind": "Variable",
2516
+ "canonicalReference": "@alloy-js/python!dataclassDecoratorKeySet:var",
2517
+ "docComment": "",
2518
+ "excerptTokens": [
2519
+ {
2520
+ "kind": "Content",
2521
+ "text": "dataclassDecoratorKeySet: "
2522
+ },
2523
+ {
2524
+ "kind": "Reference",
2525
+ "text": "Set",
2526
+ "canonicalReference": "!Set:interface"
2527
+ },
2528
+ {
2529
+ "kind": "Content",
2530
+ "text": "<string>"
2531
+ }
2532
+ ],
2533
+ "fileUrlPath": "src/components/DataclassDeclaration.tsx",
2534
+ "isReadonly": true,
2535
+ "releaseTag": "Public",
2536
+ "name": "dataclassDecoratorKeySet",
2537
+ "variableTypeTokenRange": {
2538
+ "startIndex": 1,
2539
+ "endIndex": 3
2540
+ }
2541
+ },
2542
+ {
2543
+ "kind": "TypeAlias",
2544
+ "canonicalReference": "@alloy-js/python!DataclassDecoratorKwargs:type",
2545
+ "docComment": "",
2546
+ "excerptTokens": [
2547
+ {
2548
+ "kind": "Content",
2549
+ "text": "export type DataclassDecoratorKwargs = "
2550
+ },
2551
+ {
2552
+ "kind": "Reference",
2553
+ "text": "Partial",
2554
+ "canonicalReference": "!Partial:type"
2555
+ },
2556
+ {
2557
+ "kind": "Content",
2558
+ "text": "<"
2559
+ },
2560
+ {
2561
+ "kind": "Reference",
2562
+ "text": "Record",
2563
+ "canonicalReference": "!Record:type"
2564
+ },
2565
+ {
2566
+ "kind": "Content",
2567
+ "text": "<"
2568
+ },
2569
+ {
2570
+ "kind": "Reference",
2571
+ "text": "DataclassDecoratorKey",
2572
+ "canonicalReference": "@alloy-js/python!DataclassDecoratorKey:type"
2573
+ },
2574
+ {
2575
+ "kind": "Content",
2576
+ "text": ", boolean>>"
2577
+ },
2578
+ {
2579
+ "kind": "Content",
2580
+ "text": ";"
2581
+ }
2582
+ ],
2583
+ "fileUrlPath": "src/components/DataclassDeclaration.tsx",
2584
+ "releaseTag": "Public",
2585
+ "name": "DataclassDecoratorKwargs",
2586
+ "typeTokenRange": {
2587
+ "startIndex": 1,
2588
+ "endIndex": 7
2589
+ }
2590
+ },
2591
+ {
2592
+ "kind": "Variable",
2593
+ "canonicalReference": "@alloy-js/python!dataclassesModule:var",
2594
+ "docComment": "",
2595
+ "excerptTokens": [
2596
+ {
2597
+ "kind": "Content",
2598
+ "text": "dataclassesModule: "
2599
+ },
2600
+ {
2601
+ "kind": "Content",
2602
+ "text": "import(\"../create-module.js\")."
2603
+ },
2604
+ {
2605
+ "kind": "Reference",
2606
+ "text": "ModuleRefkeys",
2607
+ "canonicalReference": "@alloy-js/python!ModuleRefkeys:type"
2608
+ },
2609
+ {
2610
+ "kind": "Content",
2611
+ "text": "<{\n readonly \".\": [\"dataclass\", \"KW_ONLY\"];\n}> & "
2612
+ },
2613
+ {
2614
+ "kind": "Reference",
2615
+ "text": "SymbolCreator",
2616
+ "canonicalReference": "@alloy-js/core!SymbolCreator:interface"
2617
+ }
2618
+ ],
2619
+ "fileUrlPath": "src/builtins/python.ts",
2620
+ "isReadonly": true,
2621
+ "releaseTag": "Public",
2622
+ "name": "dataclassesModule",
2623
+ "variableTypeTokenRange": {
2624
+ "startIndex": 1,
2625
+ "endIndex": 5
2626
+ }
2627
+ },
2361
2628
  {
2362
2629
  "kind": "Function",
2363
2630
  "canonicalReference": "@alloy-js/python!Declaration:function(1)",