@alloy-js/python 0.5.0-dev.1 → 0.5.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/CHANGELOG.md +7 -0
- package/dist/dev/src/components/CallSignature.js +2 -2
- package/dist/dev/src/components/CallSignature.js.map +1 -1
- package/dist/dev/src/components/ConstructorDeclaration.js +1 -1
- package/dist/dev/src/components/ConstructorDeclaration.js.map +1 -1
- package/dist/dev/src/components/DataclassDeclaration.js +5 -5
- package/dist/dev/src/components/DataclassDeclaration.js.map +1 -1
- package/dist/dev/src/components/FunctionBase.js +9 -9
- package/dist/dev/src/components/FunctionBase.js.map +1 -1
- package/dist/dev/src/components/PropertyDeclaration.js +8 -8
- package/dist/dev/src/components/PropertyDeclaration.js.map +1 -1
- package/dist/dev/src/components/PyDoc.js +64 -64
- package/dist/dev/src/components/PyDoc.js.map +1 -1
- package/dist/dev/src/components/PydanticClassDeclaration.js +5 -5
- package/dist/dev/src/components/PydanticClassDeclaration.js.map +1 -1
- package/dist/dev/src/components/SourceFile.js +44 -32
- package/dist/dev/src/components/SourceFile.js.map +1 -1
- package/dist/dev/src/symbols/python-output-symbol.js.map +1 -1
- package/dist/dev/test/callsignatures.test.js +471 -297
- package/dist/dev/test/callsignatures.test.js.map +1 -1
- package/dist/dev/test/class-method-declaration.test.js +21 -10
- package/dist/dev/test/class-method-declaration.test.js.map +1 -1
- package/dist/dev/test/classdeclarations.test.js +459 -393
- package/dist/dev/test/classdeclarations.test.js.map +1 -1
- package/dist/dev/test/classinstantiations.test.js +201 -168
- package/dist/dev/test/classinstantiations.test.js.map +1 -1
- package/dist/dev/test/constructordeclaration.test.js +22 -11
- package/dist/dev/test/constructordeclaration.test.js.map +1 -1
- package/dist/dev/test/dataclassdeclarations.test.js +322 -368
- package/dist/dev/test/dataclassdeclarations.test.js.map +1 -1
- package/dist/dev/test/decoratorlist.test.js +96 -49
- package/dist/dev/test/decoratorlist.test.js.map +1 -1
- package/dist/dev/test/dundermethoddeclaration.test.js +22 -11
- package/dist/dev/test/dundermethoddeclaration.test.js.map +1 -1
- package/dist/dev/test/enums.test.js +218 -184
- package/dist/dev/test/enums.test.js.map +1 -1
- package/dist/dev/test/externals.test.js +57 -45
- package/dist/dev/test/externals.test.js.map +1 -1
- package/dist/dev/test/factories.test.js +124 -50
- package/dist/dev/test/factories.test.js.map +1 -1
- package/dist/dev/test/functioncallexpressions.test.js +199 -164
- package/dist/dev/test/functioncallexpressions.test.js.map +1 -1
- package/dist/dev/test/functiondeclaration.test.js +439 -272
- package/dist/dev/test/functiondeclaration.test.js.map +1 -1
- package/dist/dev/test/imports.test.js +273 -221
- package/dist/dev/test/imports.test.js.map +1 -1
- package/dist/dev/test/memberexpressions.test.js +1237 -972
- package/dist/dev/test/memberexpressions.test.js.map +1 -1
- package/dist/dev/test/methoddeclaration.test.js +142 -78
- package/dist/dev/test/methoddeclaration.test.js.map +1 -1
- package/dist/dev/test/namepolicies.test.js +130 -94
- package/dist/dev/test/namepolicies.test.js.map +1 -1
- package/dist/dev/test/propertydeclaration.test.js +88 -59
- package/dist/dev/test/propertydeclaration.test.js.map +1 -1
- package/dist/dev/test/pydanticclassdeclarations.test.js +299 -347
- package/dist/dev/test/pydanticclassdeclarations.test.js.map +1 -1
- package/dist/dev/test/pydocs.test.js +888 -715
- package/dist/dev/test/pydocs.test.js.map +1 -1
- package/dist/dev/test/references.test.js +42 -35
- package/dist/dev/test/references.test.js.map +1 -1
- package/dist/dev/test/sourcefiles.test.js +1109 -841
- package/dist/dev/test/sourcefiles.test.js.map +1 -1
- package/dist/dev/test/staticmethoddeclaration.test.js +21 -10
- package/dist/dev/test/staticmethoddeclaration.test.js.map +1 -1
- package/dist/dev/test/type-checking-imports.test.js +408 -359
- package/dist/dev/test/type-checking-imports.test.js.map +1 -1
- package/dist/dev/test/typereference.test.js +55 -40
- package/dist/dev/test/typereference.test.js.map +1 -1
- package/dist/dev/test/uniontypeexpression.test.js +222 -146
- package/dist/dev/test/uniontypeexpression.test.js.map +1 -1
- package/dist/dev/test/utils.js +39 -77
- package/dist/dev/test/utils.js.map +1 -1
- package/dist/dev/test/values.test.js +237 -101
- package/dist/dev/test/values.test.js.map +1 -1
- package/dist/dev/test/variables.test.js +321 -203
- package/dist/dev/test/variables.test.js.map +1 -1
- package/dist/dev/test/vitest.setup.js +2 -0
- package/dist/dev/test/vitest.setup.js.map +1 -0
- package/dist/src/components/CallSignature.d.ts.map +1 -1
- package/dist/src/components/CallSignature.js.map +1 -1
- package/dist/src/components/ConstructorDeclaration.d.ts.map +1 -1
- package/dist/src/components/ConstructorDeclaration.js.map +1 -1
- package/dist/src/components/DataclassDeclaration.d.ts.map +1 -1
- package/dist/src/components/DataclassDeclaration.js.map +1 -1
- package/dist/src/components/FunctionBase.d.ts.map +1 -1
- package/dist/src/components/FunctionBase.js.map +1 -1
- package/dist/src/components/PropertyDeclaration.d.ts.map +1 -1
- package/dist/src/components/PropertyDeclaration.js.map +1 -1
- package/dist/src/components/PyDoc.d.ts.map +1 -1
- package/dist/src/components/PyDoc.js.map +1 -1
- package/dist/src/components/PydanticClassDeclaration.d.ts.map +1 -1
- package/dist/src/components/PydanticClassDeclaration.js.map +1 -1
- package/dist/src/components/SourceFile.d.ts +2 -2
- package/dist/src/components/SourceFile.d.ts.map +1 -1
- package/dist/src/components/SourceFile.js +12 -0
- package/dist/src/components/SourceFile.js.map +1 -1
- package/dist/src/symbols/python-output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/python-output-symbol.js.map +1 -1
- package/dist/test/callsignatures.test.js +346 -272
- package/dist/test/callsignatures.test.js.map +1 -1
- package/dist/test/class-method-declaration.test.js +7 -4
- package/dist/test/class-method-declaration.test.js.map +1 -1
- package/dist/test/classdeclarations.test.js +302 -288
- package/dist/test/classdeclarations.test.js.map +1 -1
- package/dist/test/classinstantiations.test.js +112 -103
- package/dist/test/classinstantiations.test.js.map +1 -1
- package/dist/test/constructordeclaration.test.js +7 -4
- package/dist/test/constructordeclaration.test.js.map +1 -1
- package/dist/test/dataclassdeclarations.test.js +134 -184
- package/dist/test/dataclassdeclarations.test.js.map +1 -1
- package/dist/test/decoratorlist.test.js +59 -36
- package/dist/test/decoratorlist.test.js.map +1 -1
- package/dist/test/dundermethoddeclaration.test.js +7 -4
- package/dist/test/dundermethoddeclaration.test.js.map +1 -1
- package/dist/test/enums.test.js +161 -159
- package/dist/test/enums.test.js.map +1 -1
- package/dist/test/externals.test.js +24 -24
- package/dist/test/externals.test.js.map +1 -1
- package/dist/test/factories.test.js +75 -33
- package/dist/test/factories.test.js.map +1 -1
- package/dist/test/functioncallexpressions.test.js +117 -106
- package/dist/test/functioncallexpressions.test.js.map +1 -1
- package/dist/test/functiondeclaration.test.js +247 -180
- package/dist/test/functiondeclaration.test.js.map +1 -1
- package/dist/test/imports.test.js +171 -143
- package/dist/test/imports.test.js.map +1 -1
- package/dist/test/memberexpressions.test.js +582 -453
- package/dist/test/memberexpressions.test.js.map +1 -1
- package/dist/test/methoddeclaration.test.js +66 -46
- package/dist/test/methoddeclaration.test.js.map +1 -1
- package/dist/test/namepolicies.test.js +90 -78
- package/dist/test/namepolicies.test.js.map +1 -1
- package/dist/test/propertydeclaration.test.js +25 -20
- package/dist/test/propertydeclaration.test.js.map +1 -1
- package/dist/test/pydanticclassdeclarations.test.js +134 -190
- package/dist/test/pydanticclassdeclarations.test.js.map +1 -1
- package/dist/test/pydocs.test.js +573 -532
- package/dist/test/pydocs.test.js.map +1 -1
- package/dist/test/references.test.js +31 -28
- package/dist/test/references.test.js.map +1 -1
- package/dist/test/sourcefiles.test.js +700 -580
- package/dist/test/sourcefiles.test.js.map +1 -1
- package/dist/test/staticmethoddeclaration.test.js +7 -4
- package/dist/test/staticmethoddeclaration.test.js.map +1 -1
- package/dist/test/type-checking-imports.test.js +297 -284
- package/dist/test/type-checking-imports.test.js.map +1 -1
- package/dist/test/typereference.test.js +29 -22
- package/dist/test/typereference.test.js.map +1 -1
- package/dist/test/uniontypeexpression.test.js +124 -88
- package/dist/test/uniontypeexpression.test.js.map +1 -1
- package/dist/test/utils.d.ts +10 -17
- package/dist/test/utils.d.ts.map +1 -1
- package/dist/test/utils.js +32 -74
- package/dist/test/utils.js.map +1 -1
- package/dist/test/values.test.js +135 -67
- package/dist/test/values.test.js.map +1 -1
- package/dist/test/variables.test.js +201 -151
- package/dist/test/variables.test.js.map +1 -1
- package/dist/test/vitest.setup.d.ts +2 -0
- package/dist/test/vitest.setup.d.ts.map +1 -0
- package/dist/test/vitest.setup.js +2 -0
- package/dist/test/vitest.setup.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/api/components/FunctionalEnumDeclaration.md +3 -6
- package/docs/api/components/MemberExpression.md +1 -5
- package/docs/api/components/SourceFile.md +20 -8
- package/docs/api/components/index.md +0 -2
- package/docs/api/functions/isTypeRefContext.md +1 -1
- package/docs/api/index.md +2 -2
- package/docs/api/types/ReferenceProps.md +7 -0
- package/docs/api/types/TypeRefContextProps.md +7 -0
- package/docs/api/types/index.md +2 -0
- package/package.json +11 -10
- package/src/components/CallSignature.tsx +4 -2
- package/src/components/ConstructorDeclaration.tsx +4 -2
- package/src/components/DataclassDeclaration.tsx +1 -2
- package/src/components/FunctionBase.tsx +1 -2
- package/src/components/PropertyDeclaration.tsx +8 -4
- package/src/components/PyDoc.tsx +12 -6
- package/src/components/PydanticClassDeclaration.tsx +1 -2
- package/src/components/SourceFile.tsx +6 -1
- package/src/symbols/python-output-symbol.ts +1 -2
- package/temp/api.json +107 -61
- package/test/callsignatures.test.tsx +309 -283
- package/test/class-method-declaration.test.tsx +3 -4
- package/test/classdeclarations.test.tsx +263 -248
- package/test/classinstantiations.test.tsx +115 -109
- package/test/constructordeclaration.test.tsx +9 -6
- package/test/dataclassdeclarations.test.tsx +243 -361
- package/test/decoratorlist.test.tsx +78 -59
- package/test/dundermethoddeclaration.test.tsx +3 -4
- package/test/enums.test.tsx +65 -81
- package/test/externals.test.tsx +25 -25
- package/test/factories.test.tsx +64 -22
- package/test/functioncallexpressions.test.tsx +123 -109
- package/test/functiondeclaration.test.tsx +209 -148
- package/test/imports.test.tsx +119 -91
- package/test/memberexpressions.test.tsx +265 -207
- package/test/methoddeclaration.test.tsx +84 -63
- package/test/namepolicies.test.tsx +69 -69
- package/test/propertydeclaration.test.tsx +7 -8
- package/test/pydanticclassdeclarations.test.tsx +355 -487
- package/test/pydocs.test.tsx +531 -579
- package/test/references.test.tsx +24 -23
- package/test/sourcefiles.test.tsx +527 -492
- package/test/staticmethoddeclaration.test.tsx +3 -4
- package/test/type-checking-imports.test.tsx +206 -218
- package/test/typereference.test.tsx +15 -12
- package/test/uniontypeexpression.test.tsx +74 -61
- package/test/utils.tsx +26 -110
- package/test/values.test.tsx +82 -32
- package/test/variables.test.tsx +162 -142
- package/test/vitest.setup.ts +1 -0
- package/tsdoc-metadata.json +1 -1
- package/vitest.config.ts +4 -0
- package/docs/api/components/Reference.md +0 -31
- package/docs/api/components/TypeRefContext.md +0 -41
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
2
|
import { Prose, code, refkey } from "@alloy-js/core";
|
|
3
|
-
import { d } from "@alloy-js/core/testing";
|
|
4
3
|
import { describe, expect, it } from "vitest";
|
|
5
4
|
import { pydanticModule, pydanticSettingsModule, typingModule } from "../src/builtins/python.js";
|
|
6
5
|
import * as py from "../src/index.js";
|
|
7
|
-
import {
|
|
6
|
+
import { TestOutput, TestOutputDirectory } from "./utils.js";
|
|
8
7
|
describe("PydanticClassDeclaration", () => {
|
|
9
8
|
it("forwards class-level decorators above `class`", () => {
|
|
10
|
-
|
|
9
|
+
expect(_$createComponent(TestOutput, {
|
|
11
10
|
path: "models.py",
|
|
11
|
+
externals: [pydanticModule, typingModule],
|
|
12
12
|
get children() {
|
|
13
13
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
14
14
|
name: "User",
|
|
@@ -25,10 +25,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
-
})
|
|
29
|
-
externals: [pydanticModule, typingModule]
|
|
30
|
-
});
|
|
31
|
-
expect(res).toRenderTo(d`
|
|
28
|
+
})).toRenderTo(`
|
|
32
29
|
from pydantic import BaseModel
|
|
33
30
|
from typing import final
|
|
34
31
|
|
|
@@ -37,12 +34,12 @@ describe("PydanticClassDeclaration", () => {
|
|
|
37
34
|
class User(BaseModel):
|
|
38
35
|
id: int
|
|
39
36
|
|
|
40
|
-
|
|
41
37
|
`);
|
|
42
38
|
});
|
|
43
39
|
it("emits a pydantic model with BaseModel, fields, and Field import", () => {
|
|
44
|
-
|
|
40
|
+
expect(_$createComponent(TestOutput, {
|
|
45
41
|
path: "models.py",
|
|
42
|
+
externals: [pydanticModule],
|
|
46
43
|
get children() {
|
|
47
44
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
48
45
|
name: "User",
|
|
@@ -63,10 +60,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
63
60
|
}
|
|
64
61
|
});
|
|
65
62
|
}
|
|
66
|
-
})
|
|
67
|
-
externals: [pydanticModule]
|
|
68
|
-
});
|
|
69
|
-
expect(res).toRenderTo(d`
|
|
63
|
+
})).toRenderTo(`
|
|
70
64
|
from pydantic import BaseModel
|
|
71
65
|
from pydantic import Field
|
|
72
66
|
|
|
@@ -75,13 +69,13 @@ describe("PydanticClassDeclaration", () => {
|
|
|
75
69
|
id: int
|
|
76
70
|
name: str = Field(default="anon")
|
|
77
71
|
|
|
78
|
-
|
|
79
72
|
`);
|
|
80
73
|
});
|
|
81
74
|
it("inherits from another pydantic model via bases", () => {
|
|
82
75
|
const baseRef = refkey();
|
|
83
|
-
|
|
76
|
+
expect(_$createComponent(TestOutput, {
|
|
84
77
|
path: "models.py",
|
|
78
|
+
externals: [pydanticModule],
|
|
85
79
|
get children() {
|
|
86
80
|
return _$createComponent(py.StatementList, {
|
|
87
81
|
get children() {
|
|
@@ -111,10 +105,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
111
105
|
}
|
|
112
106
|
});
|
|
113
107
|
}
|
|
114
|
-
})
|
|
115
|
-
externals: [pydanticModule]
|
|
116
|
-
});
|
|
117
|
-
expect(res).toRenderTo(d`
|
|
108
|
+
})).toRenderTo(`
|
|
118
109
|
from pydantic import BaseModel
|
|
119
110
|
|
|
120
111
|
|
|
@@ -124,12 +115,12 @@ describe("PydanticClassDeclaration", () => {
|
|
|
124
115
|
class Admin(User):
|
|
125
116
|
role: str
|
|
126
117
|
|
|
127
|
-
|
|
128
118
|
`);
|
|
129
119
|
});
|
|
130
120
|
it("supports required, optional, Field default, and plain default", () => {
|
|
131
|
-
|
|
121
|
+
expect(_$createComponent(TestOutput, {
|
|
132
122
|
path: "models.py",
|
|
123
|
+
externals: [pydanticModule],
|
|
133
124
|
get children() {
|
|
134
125
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
135
126
|
name: "Item",
|
|
@@ -163,10 +154,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
163
154
|
}
|
|
164
155
|
});
|
|
165
156
|
}
|
|
166
|
-
})
|
|
167
|
-
externals: [pydanticModule]
|
|
168
|
-
});
|
|
169
|
-
expect(res).toRenderTo(d`
|
|
157
|
+
})).toRenderTo(`
|
|
170
158
|
from pydantic import BaseModel
|
|
171
159
|
from pydantic import Field
|
|
172
160
|
|
|
@@ -177,7 +165,6 @@ describe("PydanticClassDeclaration", () => {
|
|
|
177
165
|
label: str = Field(default="untitled")
|
|
178
166
|
qty: int = 1
|
|
179
167
|
|
|
180
|
-
|
|
181
168
|
`);
|
|
182
169
|
});
|
|
183
170
|
it("emits class docstring", () => {
|
|
@@ -188,8 +175,9 @@ describe("PydanticClassDeclaration", () => {
|
|
|
188
175
|
})];
|
|
189
176
|
}
|
|
190
177
|
});
|
|
191
|
-
|
|
178
|
+
expect(_$createComponent(TestOutput, {
|
|
192
179
|
path: "models.py",
|
|
180
|
+
externals: [pydanticModule],
|
|
193
181
|
get children() {
|
|
194
182
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
195
183
|
name: "RequestBody",
|
|
@@ -204,10 +192,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
204
192
|
}
|
|
205
193
|
});
|
|
206
194
|
}
|
|
207
|
-
})
|
|
208
|
-
externals: [pydanticModule]
|
|
209
|
-
});
|
|
210
|
-
expect(res).toRenderTo(d`
|
|
195
|
+
})).toRenderTo(`
|
|
211
196
|
from pydantic import BaseModel
|
|
212
197
|
|
|
213
198
|
|
|
@@ -218,68 +203,70 @@ describe("PydanticClassDeclaration", () => {
|
|
|
218
203
|
|
|
219
204
|
value: str
|
|
220
205
|
|
|
221
|
-
|
|
222
206
|
`);
|
|
223
207
|
});
|
|
224
208
|
it("resolves refkey across files with pydantic imports", () => {
|
|
225
209
|
const modelRef = refkey();
|
|
226
|
-
|
|
227
|
-
|
|
210
|
+
expect(_$createComponent(TestOutputDirectory, {
|
|
211
|
+
externals: [pydanticModule],
|
|
228
212
|
get children() {
|
|
229
|
-
return _$createComponent(py.
|
|
230
|
-
|
|
231
|
-
refkey: modelRef,
|
|
213
|
+
return [_$createComponent(py.SourceFile, {
|
|
214
|
+
path: "models.py",
|
|
232
215
|
get children() {
|
|
233
|
-
return _$createComponent(py.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
216
|
+
return _$createComponent(py.PydanticClassDeclaration, {
|
|
217
|
+
name: "User",
|
|
218
|
+
refkey: modelRef,
|
|
219
|
+
get children() {
|
|
220
|
+
return _$createComponent(py.VariableDeclaration, {
|
|
221
|
+
instanceVariable: true,
|
|
222
|
+
omitNone: true,
|
|
223
|
+
name: "id",
|
|
224
|
+
type: "int"
|
|
225
|
+
});
|
|
226
|
+
}
|
|
238
227
|
});
|
|
239
228
|
}
|
|
240
|
-
})
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
});
|
|
229
|
+
}), _$createComponent(py.SourceFile, {
|
|
230
|
+
path: "service.py",
|
|
231
|
+
get children() {
|
|
232
|
+
return _$createComponent(py.FunctionDeclaration, {
|
|
233
|
+
name: "load_user",
|
|
234
|
+
returnType: modelRef,
|
|
235
|
+
parameters: [{
|
|
236
|
+
name: "user_id",
|
|
237
|
+
type: "int"
|
|
238
|
+
}],
|
|
239
|
+
children: "return User(id=user_id)"
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
})];
|
|
254
243
|
}
|
|
255
|
-
})
|
|
256
|
-
externals: [pydanticModule]
|
|
257
|
-
});
|
|
258
|
-
assertFileContents(res, {
|
|
244
|
+
})).toRenderTo({
|
|
259
245
|
"models.py": `
|
|
260
|
-
|
|
246
|
+
from pydantic import BaseModel
|
|
261
247
|
|
|
262
248
|
|
|
263
|
-
|
|
264
|
-
|
|
249
|
+
class User(BaseModel):
|
|
250
|
+
id: int
|
|
265
251
|
|
|
266
|
-
|
|
252
|
+
`,
|
|
267
253
|
"service.py": `
|
|
268
|
-
|
|
254
|
+
from typing import TYPE_CHECKING
|
|
269
255
|
|
|
270
|
-
|
|
271
|
-
|
|
256
|
+
if TYPE_CHECKING:
|
|
257
|
+
from models import User
|
|
272
258
|
|
|
273
259
|
|
|
274
|
-
|
|
275
|
-
|
|
260
|
+
def load_user(user_id: int) -> User:
|
|
261
|
+
return User(id=user_id)
|
|
276
262
|
|
|
277
|
-
|
|
263
|
+
`
|
|
278
264
|
});
|
|
279
265
|
});
|
|
280
266
|
it("emits model_config = ConfigDict(...) from top-level config props", () => {
|
|
281
|
-
|
|
267
|
+
expect(_$createComponent(TestOutput, {
|
|
282
268
|
path: "models.py",
|
|
269
|
+
externals: [pydanticModule],
|
|
283
270
|
get children() {
|
|
284
271
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
285
272
|
name: "User",
|
|
@@ -296,10 +283,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
296
283
|
}
|
|
297
284
|
});
|
|
298
285
|
}
|
|
299
|
-
})
|
|
300
|
-
externals: [pydanticModule]
|
|
301
|
-
});
|
|
302
|
-
expect(res).toRenderTo(d`
|
|
286
|
+
})).toRenderTo(`
|
|
303
287
|
from pydantic import BaseModel
|
|
304
288
|
from pydantic import ConfigDict
|
|
305
289
|
|
|
@@ -308,12 +292,12 @@ describe("PydanticClassDeclaration", () => {
|
|
|
308
292
|
model_config = ConfigDict(frozen=True, extra="forbid", validate_assignment=True)
|
|
309
293
|
id: int
|
|
310
294
|
|
|
311
|
-
|
|
312
295
|
`);
|
|
313
296
|
});
|
|
314
297
|
it("emits model_config = ConfigDict(...) from modelConfig", () => {
|
|
315
|
-
|
|
298
|
+
expect(_$createComponent(TestOutput, {
|
|
316
299
|
path: "models.py",
|
|
300
|
+
externals: [pydanticModule],
|
|
317
301
|
get children() {
|
|
318
302
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
319
303
|
name: "User",
|
|
@@ -332,10 +316,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
332
316
|
}
|
|
333
317
|
});
|
|
334
318
|
}
|
|
335
|
-
})
|
|
336
|
-
externals: [pydanticModule]
|
|
337
|
-
});
|
|
338
|
-
expect(res).toRenderTo(d`
|
|
319
|
+
})).toRenderTo(`
|
|
339
320
|
from pydantic import BaseModel
|
|
340
321
|
from pydantic import ConfigDict
|
|
341
322
|
|
|
@@ -344,12 +325,12 @@ describe("PydanticClassDeclaration", () => {
|
|
|
344
325
|
model_config = ConfigDict(frozen=True, extra="forbid", validate_assignment=True)
|
|
345
326
|
id: int
|
|
346
327
|
|
|
347
|
-
|
|
348
328
|
`);
|
|
349
329
|
});
|
|
350
330
|
it("gives precedence to top-level config props over modelConfig", () => {
|
|
351
|
-
|
|
331
|
+
expect(_$createComponent(TestOutput, {
|
|
352
332
|
path: "models.py",
|
|
333
|
+
externals: [pydanticModule],
|
|
353
334
|
get children() {
|
|
354
335
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
355
336
|
name: "User",
|
|
@@ -361,10 +342,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
361
342
|
extra: "forbid"
|
|
362
343
|
});
|
|
363
344
|
}
|
|
364
|
-
})
|
|
365
|
-
externals: [pydanticModule]
|
|
366
|
-
});
|
|
367
|
-
expect(res).toRenderTo(d`
|
|
345
|
+
})).toRenderTo(`
|
|
368
346
|
from pydantic import BaseModel
|
|
369
347
|
from pydantic import ConfigDict
|
|
370
348
|
|
|
@@ -372,12 +350,12 @@ describe("PydanticClassDeclaration", () => {
|
|
|
372
350
|
class User(BaseModel):
|
|
373
351
|
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
374
352
|
|
|
375
|
-
|
|
376
353
|
`);
|
|
377
354
|
});
|
|
378
355
|
it("supports additional typed ConfigDict props", () => {
|
|
379
|
-
|
|
356
|
+
expect(_$createComponent(TestOutput, {
|
|
380
357
|
path: "models.py",
|
|
358
|
+
externals: [pydanticModule],
|
|
381
359
|
get children() {
|
|
382
360
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
383
361
|
name: "User",
|
|
@@ -390,10 +368,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
390
368
|
valJsonBytes: "hex"
|
|
391
369
|
});
|
|
392
370
|
}
|
|
393
|
-
})
|
|
394
|
-
externals: [pydanticModule]
|
|
395
|
-
});
|
|
396
|
-
expect(res).toRenderTo(d`
|
|
371
|
+
})).toRenderTo(`
|
|
397
372
|
from pydantic import BaseModel
|
|
398
373
|
from pydantic import ConfigDict
|
|
399
374
|
|
|
@@ -401,12 +376,12 @@ describe("PydanticClassDeclaration", () => {
|
|
|
401
376
|
class User(BaseModel):
|
|
402
377
|
model_config = ConfigDict(coerce_numbers_to_str=True, ser_json_bytes="base64", str_min_length=1, str_max_length=128, use_enum_values=True, val_json_bytes="hex", validate_return=True)
|
|
403
378
|
|
|
404
|
-
|
|
405
379
|
`);
|
|
406
380
|
});
|
|
407
381
|
it("imports SecretStr when used as a field type", () => {
|
|
408
|
-
|
|
382
|
+
expect(_$createComponent(TestOutput, {
|
|
409
383
|
path: "models.py",
|
|
384
|
+
externals: [pydanticModule],
|
|
410
385
|
get children() {
|
|
411
386
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
412
387
|
name: "Credentials",
|
|
@@ -422,10 +397,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
422
397
|
}
|
|
423
398
|
});
|
|
424
399
|
}
|
|
425
|
-
})
|
|
426
|
-
externals: [pydanticModule]
|
|
427
|
-
});
|
|
428
|
-
expect(res).toRenderTo(d`
|
|
400
|
+
})).toRenderTo(`
|
|
429
401
|
from pydantic import BaseModel
|
|
430
402
|
from typing import TYPE_CHECKING
|
|
431
403
|
|
|
@@ -436,12 +408,12 @@ describe("PydanticClassDeclaration", () => {
|
|
|
436
408
|
class Credentials(BaseModel):
|
|
437
409
|
token: SecretStr
|
|
438
410
|
|
|
439
|
-
|
|
440
411
|
`);
|
|
441
412
|
});
|
|
442
413
|
it("emits arbitrary model_config via modelConfigExpression", () => {
|
|
443
|
-
|
|
414
|
+
expect(_$createComponent(TestOutput, {
|
|
444
415
|
path: "models.py",
|
|
416
|
+
externals: [pydanticModule],
|
|
445
417
|
get children() {
|
|
446
418
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
447
419
|
name: "M",
|
|
@@ -450,10 +422,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
450
422
|
}
|
|
451
423
|
});
|
|
452
424
|
}
|
|
453
|
-
})
|
|
454
|
-
externals: [pydanticModule]
|
|
455
|
-
});
|
|
456
|
-
expect(res).toRenderTo(d`
|
|
425
|
+
})).toRenderTo(`
|
|
457
426
|
from pydantic import BaseModel
|
|
458
427
|
from pydantic import ConfigDict
|
|
459
428
|
|
|
@@ -461,12 +430,12 @@ describe("PydanticClassDeclaration", () => {
|
|
|
461
430
|
class M(BaseModel):
|
|
462
431
|
model_config = ConfigDict(frozen=True, extra="allow")
|
|
463
432
|
|
|
464
|
-
|
|
465
433
|
`);
|
|
466
434
|
});
|
|
467
435
|
it("supports RootModel as explicit bases entry", () => {
|
|
468
|
-
|
|
436
|
+
expect(_$createComponent(TestOutput, {
|
|
469
437
|
path: "models.py",
|
|
438
|
+
externals: [pydanticModule],
|
|
470
439
|
get children() {
|
|
471
440
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
472
441
|
name: "Tags",
|
|
@@ -475,22 +444,19 @@ describe("PydanticClassDeclaration", () => {
|
|
|
475
444
|
}
|
|
476
445
|
});
|
|
477
446
|
}
|
|
478
|
-
})
|
|
479
|
-
externals: [pydanticModule]
|
|
480
|
-
});
|
|
481
|
-
expect(res).toRenderTo(d`
|
|
447
|
+
})).toRenderTo(`
|
|
482
448
|
from pydantic import RootModel
|
|
483
449
|
|
|
484
450
|
|
|
485
451
|
class Tags(RootModel[list[str]]):
|
|
486
452
|
pass
|
|
487
453
|
|
|
488
|
-
|
|
489
454
|
`);
|
|
490
455
|
});
|
|
491
456
|
it("places Pydantic validators above classmethod", () => {
|
|
492
|
-
|
|
457
|
+
expect(_$createComponent(TestOutput, {
|
|
493
458
|
path: "models.py",
|
|
459
|
+
externals: [pydanticModule],
|
|
494
460
|
get children() {
|
|
495
461
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
496
462
|
name: "User",
|
|
@@ -515,10 +481,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
515
481
|
}
|
|
516
482
|
});
|
|
517
483
|
}
|
|
518
|
-
})
|
|
519
|
-
externals: [pydanticModule]
|
|
520
|
-
});
|
|
521
|
-
expect(res).toRenderTo(d`
|
|
484
|
+
})).toRenderTo(`
|
|
522
485
|
from pydantic import BaseModel
|
|
523
486
|
from pydantic import field_validator
|
|
524
487
|
|
|
@@ -531,14 +494,14 @@ describe("PydanticClassDeclaration", () => {
|
|
|
531
494
|
return value.strip()
|
|
532
495
|
|
|
533
496
|
|
|
534
|
-
|
|
535
497
|
`);
|
|
536
498
|
});
|
|
537
499
|
});
|
|
538
500
|
describe("Pydantic ecosystem emitters", () => {
|
|
539
501
|
it("typing module resolves Any and similar annotations", () => {
|
|
540
|
-
|
|
502
|
+
expect(_$createComponent(TestOutput, {
|
|
541
503
|
path: "models.py",
|
|
504
|
+
externals: [typingModule],
|
|
542
505
|
get children() {
|
|
543
506
|
return _$createComponent(py.FunctionDeclaration, {
|
|
544
507
|
name: "identity",
|
|
@@ -554,10 +517,7 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
554
517
|
children: "return x"
|
|
555
518
|
});
|
|
556
519
|
}
|
|
557
|
-
})
|
|
558
|
-
externals: [typingModule]
|
|
559
|
-
});
|
|
560
|
-
expect(res).toRenderTo(d`
|
|
520
|
+
})).toRenderTo(`
|
|
561
521
|
from typing import TYPE_CHECKING
|
|
562
522
|
|
|
563
523
|
if TYPE_CHECKING:
|
|
@@ -567,12 +527,12 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
567
527
|
def identity(x: Any) -> Any:
|
|
568
528
|
return x
|
|
569
529
|
|
|
570
|
-
|
|
571
530
|
`);
|
|
572
531
|
});
|
|
573
532
|
it("pydantic.types constrains field annotations", () => {
|
|
574
|
-
|
|
533
|
+
expect(_$createComponent(TestOutput, {
|
|
575
534
|
path: "models.py",
|
|
535
|
+
externals: [pydanticModule],
|
|
576
536
|
get children() {
|
|
577
537
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
578
538
|
name: "Score",
|
|
@@ -588,10 +548,7 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
588
548
|
}
|
|
589
549
|
});
|
|
590
550
|
}
|
|
591
|
-
})
|
|
592
|
-
externals: [pydanticModule]
|
|
593
|
-
});
|
|
594
|
-
expect(res).toRenderTo(d`
|
|
551
|
+
})).toRenderTo(`
|
|
595
552
|
from pydantic import BaseModel
|
|
596
553
|
from typing import TYPE_CHECKING
|
|
597
554
|
|
|
@@ -602,53 +559,56 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
602
559
|
class Score(BaseModel):
|
|
603
560
|
points: PositiveInt
|
|
604
561
|
|
|
605
|
-
|
|
606
562
|
`);
|
|
607
563
|
});
|
|
608
564
|
it("postponed annotations support forward references in fields", () => {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
get futureImports() {
|
|
612
|
-
return [_$createComponent(py.FutureStatement, {
|
|
613
|
-
feature: "annotations"
|
|
614
|
-
})];
|
|
615
|
-
},
|
|
565
|
+
expect(_$createComponent(TestOutputDirectory, {
|
|
566
|
+
externals: [pydanticModule],
|
|
616
567
|
get children() {
|
|
617
|
-
return _$createComponent(py.
|
|
618
|
-
|
|
619
|
-
get
|
|
620
|
-
return [_$createComponent(py.
|
|
621
|
-
|
|
622
|
-
omitNone: true,
|
|
623
|
-
name: "label",
|
|
624
|
-
type: "str"
|
|
625
|
-
}), _$createComponent(py.VariableDeclaration, {
|
|
626
|
-
instanceVariable: true,
|
|
627
|
-
name: "child",
|
|
628
|
-
type: code`"Node" | None`
|
|
568
|
+
return _$createComponent(py.SourceFile, {
|
|
569
|
+
path: "models.py",
|
|
570
|
+
get futureImports() {
|
|
571
|
+
return [_$createComponent(py.FutureStatement, {
|
|
572
|
+
feature: "annotations"
|
|
629
573
|
})];
|
|
574
|
+
},
|
|
575
|
+
get children() {
|
|
576
|
+
return _$createComponent(py.PydanticClassDeclaration, {
|
|
577
|
+
name: "Node",
|
|
578
|
+
get children() {
|
|
579
|
+
return [_$createComponent(py.VariableDeclaration, {
|
|
580
|
+
instanceVariable: true,
|
|
581
|
+
omitNone: true,
|
|
582
|
+
name: "label",
|
|
583
|
+
type: "str"
|
|
584
|
+
}), _$createComponent(py.VariableDeclaration, {
|
|
585
|
+
instanceVariable: true,
|
|
586
|
+
name: "child",
|
|
587
|
+
type: code`"Node" | None`
|
|
588
|
+
})];
|
|
589
|
+
}
|
|
590
|
+
});
|
|
630
591
|
}
|
|
631
592
|
});
|
|
632
593
|
}
|
|
633
|
-
})
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
expect(res).toRenderTo(d`
|
|
637
|
-
from __future__ import annotations
|
|
638
|
-
|
|
639
|
-
from pydantic import BaseModel
|
|
594
|
+
})).toRenderTo({
|
|
595
|
+
"models.py": `
|
|
596
|
+
from __future__ import annotations
|
|
640
597
|
|
|
598
|
+
from pydantic import BaseModel
|
|
641
599
|
|
|
642
|
-
class Node(BaseModel):
|
|
643
|
-
label: str
|
|
644
|
-
child: "Node" | None = None
|
|
645
600
|
|
|
601
|
+
class Node(BaseModel):
|
|
602
|
+
label: str
|
|
603
|
+
child: "Node" | None = None
|
|
646
604
|
|
|
647
|
-
|
|
605
|
+
`
|
|
606
|
+
});
|
|
648
607
|
});
|
|
649
608
|
it("model_config can use pydantic.alias_generators", () => {
|
|
650
|
-
|
|
609
|
+
expect(_$createComponent(TestOutput, {
|
|
651
610
|
path: "models.py",
|
|
611
|
+
externals: [pydanticModule],
|
|
652
612
|
get children() {
|
|
653
613
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
654
614
|
name: "M",
|
|
@@ -657,10 +617,7 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
657
617
|
}
|
|
658
618
|
});
|
|
659
619
|
}
|
|
660
|
-
})
|
|
661
|
-
externals: [pydanticModule]
|
|
662
|
-
});
|
|
663
|
-
expect(res).toRenderTo(d`
|
|
620
|
+
})).toRenderTo(`
|
|
664
621
|
from pydantic import BaseModel
|
|
665
622
|
from pydantic import ConfigDict
|
|
666
623
|
from pydantic.alias_generators import to_camel
|
|
@@ -669,12 +626,12 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
669
626
|
class M(BaseModel):
|
|
670
627
|
model_config = ConfigDict(alias_generator=to_camel)
|
|
671
628
|
|
|
672
|
-
|
|
673
629
|
`);
|
|
674
630
|
});
|
|
675
631
|
it("pydantic_settings exposes BaseSettings", () => {
|
|
676
|
-
|
|
632
|
+
expect(_$createComponent(TestOutput, {
|
|
677
633
|
path: "config.py",
|
|
634
|
+
externals: [pydanticSettingsModule],
|
|
678
635
|
get children() {
|
|
679
636
|
return _$createComponent(py.ClassDeclaration, {
|
|
680
637
|
name: "AppSettings",
|
|
@@ -683,22 +640,19 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
683
640
|
}
|
|
684
641
|
});
|
|
685
642
|
}
|
|
686
|
-
})
|
|
687
|
-
externals: [pydanticSettingsModule]
|
|
688
|
-
});
|
|
689
|
-
expect(res).toRenderTo(d`
|
|
643
|
+
})).toRenderTo(`
|
|
690
644
|
from pydantic_settings import BaseSettings
|
|
691
645
|
|
|
692
646
|
|
|
693
647
|
class AppSettings(BaseSettings):
|
|
694
648
|
pass
|
|
695
649
|
|
|
696
|
-
|
|
697
650
|
`);
|
|
698
651
|
});
|
|
699
652
|
it("emits @computed_field above @property via PropertyDeclaration", () => {
|
|
700
|
-
|
|
653
|
+
expect(_$createComponent(TestOutput, {
|
|
701
654
|
path: "models.py",
|
|
655
|
+
externals: [pydanticModule],
|
|
702
656
|
get children() {
|
|
703
657
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
704
658
|
name: "Square",
|
|
@@ -719,10 +673,7 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
719
673
|
}
|
|
720
674
|
});
|
|
721
675
|
}
|
|
722
|
-
})
|
|
723
|
-
externals: [pydanticModule]
|
|
724
|
-
});
|
|
725
|
-
expect(res).toRenderTo(d`
|
|
676
|
+
})).toRenderTo(`
|
|
726
677
|
from pydantic import BaseModel
|
|
727
678
|
from pydantic import computed_field
|
|
728
679
|
|
|
@@ -735,12 +686,12 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
735
686
|
return self.width ** 2
|
|
736
687
|
|
|
737
688
|
|
|
738
|
-
|
|
739
689
|
`);
|
|
740
690
|
});
|
|
741
691
|
it("emits computed_field on an instance method", () => {
|
|
742
|
-
|
|
692
|
+
expect(_$createComponent(TestOutput, {
|
|
743
693
|
path: "models.py",
|
|
694
|
+
externals: [pydanticModule],
|
|
744
695
|
get children() {
|
|
745
696
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
746
697
|
name: "Square",
|
|
@@ -761,10 +712,7 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
761
712
|
}
|
|
762
713
|
});
|
|
763
714
|
}
|
|
764
|
-
})
|
|
765
|
-
externals: [pydanticModule]
|
|
766
|
-
});
|
|
767
|
-
expect(res).toRenderTo(d`
|
|
715
|
+
})).toRenderTo(`
|
|
768
716
|
from pydantic import BaseModel
|
|
769
717
|
from pydantic import computed_field
|
|
770
718
|
|
|
@@ -776,12 +724,12 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
776
724
|
return self.width ** 2
|
|
777
725
|
|
|
778
726
|
|
|
779
|
-
|
|
780
727
|
`);
|
|
781
728
|
});
|
|
782
729
|
it("emits model_validator above classmethod", () => {
|
|
783
|
-
|
|
730
|
+
expect(_$createComponent(TestOutput, {
|
|
784
731
|
path: "models.py",
|
|
732
|
+
externals: [pydanticModule],
|
|
785
733
|
get children() {
|
|
786
734
|
return _$createComponent(py.PydanticClassDeclaration, {
|
|
787
735
|
name: "Bag",
|
|
@@ -806,10 +754,7 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
806
754
|
}
|
|
807
755
|
});
|
|
808
756
|
}
|
|
809
|
-
})
|
|
810
|
-
externals: [pydanticModule]
|
|
811
|
-
});
|
|
812
|
-
expect(res).toRenderTo(d`
|
|
757
|
+
})).toRenderTo(`
|
|
813
758
|
from pydantic import BaseModel
|
|
814
759
|
from pydantic import model_validator
|
|
815
760
|
|
|
@@ -822,7 +767,6 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
822
767
|
return data
|
|
823
768
|
|
|
824
769
|
|
|
825
|
-
|
|
826
770
|
`);
|
|
827
771
|
});
|
|
828
772
|
});
|