@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,5 +1,4 @@
|
|
|
1
1
|
import { Prose, code, refkey } from "@alloy-js/core";
|
|
2
|
-
import { d } from "@alloy-js/core/testing";
|
|
3
2
|
import { describe, expect, it } from "vitest";
|
|
4
3
|
import {
|
|
5
4
|
pydanticModule,
|
|
@@ -7,35 +6,26 @@ import {
|
|
|
7
6
|
typingModule,
|
|
8
7
|
} from "../src/builtins/python.js";
|
|
9
8
|
import * as py from "../src/index.js";
|
|
10
|
-
import {
|
|
11
|
-
assertFileContents,
|
|
12
|
-
toSourceText,
|
|
13
|
-
toSourceTextMultiple,
|
|
14
|
-
} from "./utils.jsx";
|
|
9
|
+
import { TestOutput, TestOutputDirectory } from "./utils.js";
|
|
15
10
|
|
|
16
11
|
describe("PydanticClassDeclaration", () => {
|
|
17
12
|
it("forwards class-level decorators above `class`", () => {
|
|
18
|
-
|
|
19
|
-
[
|
|
20
|
-
<py.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
{ externals: [pydanticModule, typingModule] },
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
expect(res).toRenderTo(
|
|
38
|
-
d`
|
|
13
|
+
expect(
|
|
14
|
+
<TestOutput path="models.py" externals={[pydanticModule, typingModule]}>
|
|
15
|
+
<py.PydanticClassDeclaration
|
|
16
|
+
name="User"
|
|
17
|
+
decorators={[code`@${typingModule["."].final}`]}
|
|
18
|
+
>
|
|
19
|
+
<py.VariableDeclaration
|
|
20
|
+
instanceVariable
|
|
21
|
+
omitNone
|
|
22
|
+
name="id"
|
|
23
|
+
type="int"
|
|
24
|
+
/>
|
|
25
|
+
</py.PydanticClassDeclaration>
|
|
26
|
+
</TestOutput>,
|
|
27
|
+
).toRenderTo(
|
|
28
|
+
`
|
|
39
29
|
from pydantic import BaseModel
|
|
40
30
|
from typing import final
|
|
41
31
|
|
|
@@ -44,36 +34,30 @@ describe("PydanticClassDeclaration", () => {
|
|
|
44
34
|
class User(BaseModel):
|
|
45
35
|
id: int
|
|
46
36
|
|
|
47
|
-
|
|
48
37
|
`,
|
|
49
38
|
);
|
|
50
39
|
});
|
|
51
40
|
|
|
52
41
|
it("emits a pydantic model with BaseModel, fields, and Field import", () => {
|
|
53
|
-
|
|
54
|
-
[
|
|
55
|
-
<py.
|
|
56
|
-
<py.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
{ externals: [pydanticModule] },
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
expect(res).toRenderTo(
|
|
76
|
-
d`
|
|
42
|
+
expect(
|
|
43
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
44
|
+
<py.PydanticClassDeclaration name="User">
|
|
45
|
+
<py.VariableDeclaration
|
|
46
|
+
instanceVariable
|
|
47
|
+
omitNone
|
|
48
|
+
name="id"
|
|
49
|
+
type="int"
|
|
50
|
+
/>
|
|
51
|
+
<py.VariableDeclaration
|
|
52
|
+
instanceVariable
|
|
53
|
+
name="name"
|
|
54
|
+
type="str"
|
|
55
|
+
initializer={code`${pydanticModule["."].Field}(default="anon")`}
|
|
56
|
+
/>
|
|
57
|
+
</py.PydanticClassDeclaration>
|
|
58
|
+
</TestOutput>,
|
|
59
|
+
).toRenderTo(
|
|
60
|
+
`
|
|
77
61
|
from pydantic import BaseModel
|
|
78
62
|
from pydantic import Field
|
|
79
63
|
|
|
@@ -82,41 +66,35 @@ describe("PydanticClassDeclaration", () => {
|
|
|
82
66
|
id: int
|
|
83
67
|
name: str = Field(default="anon")
|
|
84
68
|
|
|
85
|
-
|
|
86
69
|
`,
|
|
87
70
|
);
|
|
88
71
|
});
|
|
89
72
|
|
|
90
73
|
it("inherits from another pydantic model via bases", () => {
|
|
91
74
|
const baseRef = refkey();
|
|
92
|
-
|
|
93
|
-
[
|
|
94
|
-
<py.
|
|
95
|
-
<py.
|
|
96
|
-
<py.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
<py.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
{ externals: [pydanticModule] },
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
expect(res).toRenderTo(
|
|
119
|
-
d`
|
|
75
|
+
expect(
|
|
76
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
77
|
+
<py.StatementList>
|
|
78
|
+
<py.PydanticClassDeclaration name="User" refkey={baseRef}>
|
|
79
|
+
<py.VariableDeclaration
|
|
80
|
+
instanceVariable
|
|
81
|
+
omitNone
|
|
82
|
+
name="id"
|
|
83
|
+
type="int"
|
|
84
|
+
/>
|
|
85
|
+
</py.PydanticClassDeclaration>
|
|
86
|
+
<py.PydanticClassDeclaration name="Admin" bases={[baseRef]}>
|
|
87
|
+
<py.VariableDeclaration
|
|
88
|
+
instanceVariable
|
|
89
|
+
omitNone
|
|
90
|
+
name="role"
|
|
91
|
+
type="str"
|
|
92
|
+
/>
|
|
93
|
+
</py.PydanticClassDeclaration>
|
|
94
|
+
</py.StatementList>
|
|
95
|
+
</TestOutput>,
|
|
96
|
+
).toRenderTo(
|
|
97
|
+
`
|
|
120
98
|
from pydantic import BaseModel
|
|
121
99
|
|
|
122
100
|
|
|
@@ -126,47 +104,41 @@ describe("PydanticClassDeclaration", () => {
|
|
|
126
104
|
class Admin(User):
|
|
127
105
|
role: str
|
|
128
106
|
|
|
129
|
-
|
|
130
107
|
`,
|
|
131
108
|
);
|
|
132
109
|
});
|
|
133
110
|
|
|
134
111
|
it("supports required, optional, Field default, and plain default", () => {
|
|
135
|
-
|
|
136
|
-
[
|
|
137
|
-
<py.
|
|
138
|
-
<py.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
{ externals: [pydanticModule] },
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
expect(res).toRenderTo(
|
|
169
|
-
d`
|
|
112
|
+
expect(
|
|
113
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
114
|
+
<py.PydanticClassDeclaration name="Item">
|
|
115
|
+
<py.VariableDeclaration
|
|
116
|
+
instanceVariable
|
|
117
|
+
omitNone
|
|
118
|
+
name="sku"
|
|
119
|
+
type="str"
|
|
120
|
+
/>
|
|
121
|
+
<py.VariableDeclaration
|
|
122
|
+
instanceVariable
|
|
123
|
+
name="notes"
|
|
124
|
+
type={<py.UnionTypeExpression children={["str", "None"]} />}
|
|
125
|
+
/>
|
|
126
|
+
<py.VariableDeclaration
|
|
127
|
+
instanceVariable
|
|
128
|
+
name="label"
|
|
129
|
+
type="str"
|
|
130
|
+
initializer={code`${pydanticModule["."].Field}(default="untitled")`}
|
|
131
|
+
/>
|
|
132
|
+
<py.VariableDeclaration
|
|
133
|
+
instanceVariable
|
|
134
|
+
name="qty"
|
|
135
|
+
type="int"
|
|
136
|
+
initializer={1}
|
|
137
|
+
/>
|
|
138
|
+
</py.PydanticClassDeclaration>
|
|
139
|
+
</TestOutput>,
|
|
140
|
+
).toRenderTo(
|
|
141
|
+
`
|
|
170
142
|
from pydantic import BaseModel
|
|
171
143
|
from pydantic import Field
|
|
172
144
|
|
|
@@ -177,7 +149,6 @@ describe("PydanticClassDeclaration", () => {
|
|
|
177
149
|
label: str = Field(default="untitled")
|
|
178
150
|
qty: int = 1
|
|
179
151
|
|
|
180
|
-
|
|
181
152
|
`,
|
|
182
153
|
);
|
|
183
154
|
});
|
|
@@ -186,24 +157,19 @@ describe("PydanticClassDeclaration", () => {
|
|
|
186
157
|
const doc = (
|
|
187
158
|
<py.ClassDoc description={[<Prose>Payload for an API request.</Prose>]} />
|
|
188
159
|
);
|
|
189
|
-
|
|
190
|
-
[
|
|
191
|
-
<py.
|
|
192
|
-
<py.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
{ externals: [pydanticModule] },
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
expect(res).toRenderTo(
|
|
206
|
-
d`
|
|
160
|
+
expect(
|
|
161
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
162
|
+
<py.PydanticClassDeclaration name="RequestBody" doc={doc}>
|
|
163
|
+
<py.VariableDeclaration
|
|
164
|
+
instanceVariable
|
|
165
|
+
omitNone
|
|
166
|
+
name="value"
|
|
167
|
+
type="str"
|
|
168
|
+
/>
|
|
169
|
+
</py.PydanticClassDeclaration>
|
|
170
|
+
</TestOutput>,
|
|
171
|
+
).toRenderTo(
|
|
172
|
+
`
|
|
207
173
|
from pydantic import BaseModel
|
|
208
174
|
|
|
209
175
|
|
|
@@ -214,15 +180,14 @@ describe("PydanticClassDeclaration", () => {
|
|
|
214
180
|
|
|
215
181
|
value: str
|
|
216
182
|
|
|
217
|
-
|
|
218
183
|
`,
|
|
219
184
|
);
|
|
220
185
|
});
|
|
221
186
|
|
|
222
187
|
it("resolves refkey across files with pydantic imports", () => {
|
|
223
188
|
const modelRef = refkey();
|
|
224
|
-
|
|
225
|
-
[
|
|
189
|
+
expect(
|
|
190
|
+
<TestOutputDirectory externals={[pydanticModule]}>
|
|
226
191
|
<py.SourceFile path="models.py">
|
|
227
192
|
<py.PydanticClassDeclaration name="User" refkey={modelRef}>
|
|
228
193
|
<py.VariableDeclaration
|
|
@@ -232,7 +197,7 @@ describe("PydanticClassDeclaration", () => {
|
|
|
232
197
|
type="int"
|
|
233
198
|
/>
|
|
234
199
|
</py.PydanticClassDeclaration>
|
|
235
|
-
</py.SourceFile
|
|
200
|
+
</py.SourceFile>
|
|
236
201
|
<py.SourceFile path="service.py">
|
|
237
202
|
<py.FunctionDeclaration
|
|
238
203
|
name="load_user"
|
|
@@ -241,58 +206,50 @@ describe("PydanticClassDeclaration", () => {
|
|
|
241
206
|
>
|
|
242
207
|
{"return User(id=user_id)"}
|
|
243
208
|
</py.FunctionDeclaration>
|
|
244
|
-
</py.SourceFile
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
);
|
|
248
|
-
|
|
249
|
-
assertFileContents(res, {
|
|
209
|
+
</py.SourceFile>
|
|
210
|
+
</TestOutputDirectory>,
|
|
211
|
+
).toRenderTo({
|
|
250
212
|
"models.py": `
|
|
251
|
-
|
|
213
|
+
from pydantic import BaseModel
|
|
252
214
|
|
|
253
215
|
|
|
254
|
-
|
|
255
|
-
|
|
216
|
+
class User(BaseModel):
|
|
217
|
+
id: int
|
|
256
218
|
|
|
257
|
-
|
|
219
|
+
`,
|
|
258
220
|
"service.py": `
|
|
259
|
-
|
|
221
|
+
from typing import TYPE_CHECKING
|
|
260
222
|
|
|
261
|
-
|
|
262
|
-
|
|
223
|
+
if TYPE_CHECKING:
|
|
224
|
+
from models import User
|
|
263
225
|
|
|
264
226
|
|
|
265
|
-
|
|
266
|
-
|
|
227
|
+
def load_user(user_id: int) -> User:
|
|
228
|
+
return User(id=user_id)
|
|
267
229
|
|
|
268
|
-
|
|
230
|
+
`,
|
|
269
231
|
});
|
|
270
232
|
});
|
|
271
233
|
|
|
272
234
|
it("emits model_config = ConfigDict(...) from top-level config props", () => {
|
|
273
|
-
|
|
274
|
-
[
|
|
275
|
-
<py.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
{ externals: [pydanticModule] },
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
expect(res).toRenderTo(
|
|
295
|
-
d`
|
|
235
|
+
expect(
|
|
236
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
237
|
+
<py.PydanticClassDeclaration
|
|
238
|
+
name="User"
|
|
239
|
+
frozen
|
|
240
|
+
extra="forbid"
|
|
241
|
+
validateAssignment
|
|
242
|
+
>
|
|
243
|
+
<py.VariableDeclaration
|
|
244
|
+
instanceVariable
|
|
245
|
+
omitNone
|
|
246
|
+
name="id"
|
|
247
|
+
type="int"
|
|
248
|
+
/>
|
|
249
|
+
</py.PydanticClassDeclaration>
|
|
250
|
+
</TestOutput>,
|
|
251
|
+
).toRenderTo(
|
|
252
|
+
`
|
|
296
253
|
from pydantic import BaseModel
|
|
297
254
|
from pydantic import ConfigDict
|
|
298
255
|
|
|
@@ -301,37 +258,31 @@ describe("PydanticClassDeclaration", () => {
|
|
|
301
258
|
model_config = ConfigDict(frozen=True, extra="forbid", validate_assignment=True)
|
|
302
259
|
id: int
|
|
303
260
|
|
|
304
|
-
|
|
305
261
|
`,
|
|
306
262
|
);
|
|
307
263
|
});
|
|
308
264
|
|
|
309
265
|
it("emits model_config = ConfigDict(...) from modelConfig", () => {
|
|
310
|
-
|
|
311
|
-
[
|
|
312
|
-
<py.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
{ externals: [pydanticModule] },
|
|
331
|
-
);
|
|
332
|
-
|
|
333
|
-
expect(res).toRenderTo(
|
|
334
|
-
d`
|
|
266
|
+
expect(
|
|
267
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
268
|
+
<py.PydanticClassDeclaration
|
|
269
|
+
name="User"
|
|
270
|
+
modelConfig={{
|
|
271
|
+
frozen: true,
|
|
272
|
+
extra: "forbid",
|
|
273
|
+
validateAssignment: true,
|
|
274
|
+
}}
|
|
275
|
+
>
|
|
276
|
+
<py.VariableDeclaration
|
|
277
|
+
instanceVariable
|
|
278
|
+
omitNone
|
|
279
|
+
name="id"
|
|
280
|
+
type="int"
|
|
281
|
+
/>
|
|
282
|
+
</py.PydanticClassDeclaration>
|
|
283
|
+
</TestOutput>,
|
|
284
|
+
).toRenderTo(
|
|
285
|
+
`
|
|
335
286
|
from pydantic import BaseModel
|
|
336
287
|
from pydantic import ConfigDict
|
|
337
288
|
|
|
@@ -340,28 +291,22 @@ describe("PydanticClassDeclaration", () => {
|
|
|
340
291
|
model_config = ConfigDict(frozen=True, extra="forbid", validate_assignment=True)
|
|
341
292
|
id: int
|
|
342
293
|
|
|
343
|
-
|
|
344
294
|
`,
|
|
345
295
|
);
|
|
346
296
|
});
|
|
347
297
|
|
|
348
298
|
it("gives precedence to top-level config props over modelConfig", () => {
|
|
349
|
-
|
|
350
|
-
[
|
|
351
|
-
<py.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
{ externals: [pydanticModule] },
|
|
361
|
-
);
|
|
362
|
-
|
|
363
|
-
expect(res).toRenderTo(
|
|
364
|
-
d`
|
|
299
|
+
expect(
|
|
300
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
301
|
+
<py.PydanticClassDeclaration
|
|
302
|
+
name="User"
|
|
303
|
+
modelConfig={{ frozen: false, extra: "allow" }}
|
|
304
|
+
frozen
|
|
305
|
+
extra="forbid"
|
|
306
|
+
/>
|
|
307
|
+
</TestOutput>,
|
|
308
|
+
).toRenderTo(
|
|
309
|
+
`
|
|
365
310
|
from pydantic import BaseModel
|
|
366
311
|
from pydantic import ConfigDict
|
|
367
312
|
|
|
@@ -369,32 +314,26 @@ describe("PydanticClassDeclaration", () => {
|
|
|
369
314
|
class User(BaseModel):
|
|
370
315
|
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
371
316
|
|
|
372
|
-
|
|
373
317
|
`,
|
|
374
318
|
);
|
|
375
319
|
});
|
|
376
320
|
|
|
377
321
|
it("supports additional typed ConfigDict props", () => {
|
|
378
|
-
|
|
379
|
-
[
|
|
380
|
-
<py.
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
{ externals: [pydanticModule] },
|
|
394
|
-
);
|
|
395
|
-
|
|
396
|
-
expect(res).toRenderTo(
|
|
397
|
-
d`
|
|
322
|
+
expect(
|
|
323
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
324
|
+
<py.PydanticClassDeclaration
|
|
325
|
+
name="User"
|
|
326
|
+
useEnumValues
|
|
327
|
+
coerceNumbersToStr
|
|
328
|
+
validateReturn
|
|
329
|
+
strMinLength={1}
|
|
330
|
+
strMaxLength={128}
|
|
331
|
+
serJsonBytes="base64"
|
|
332
|
+
valJsonBytes="hex"
|
|
333
|
+
/>
|
|
334
|
+
</TestOutput>,
|
|
335
|
+
).toRenderTo(
|
|
336
|
+
`
|
|
398
337
|
from pydantic import BaseModel
|
|
399
338
|
from pydantic import ConfigDict
|
|
400
339
|
|
|
@@ -402,30 +341,24 @@ describe("PydanticClassDeclaration", () => {
|
|
|
402
341
|
class User(BaseModel):
|
|
403
342
|
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)
|
|
404
343
|
|
|
405
|
-
|
|
406
344
|
`,
|
|
407
345
|
);
|
|
408
346
|
});
|
|
409
347
|
|
|
410
348
|
it("imports SecretStr when used as a field type", () => {
|
|
411
|
-
|
|
412
|
-
[
|
|
413
|
-
<py.
|
|
414
|
-
<py.
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
{ externals: [pydanticModule] },
|
|
425
|
-
);
|
|
426
|
-
|
|
427
|
-
expect(res).toRenderTo(
|
|
428
|
-
d`
|
|
349
|
+
expect(
|
|
350
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
351
|
+
<py.PydanticClassDeclaration name="Credentials">
|
|
352
|
+
<py.VariableDeclaration
|
|
353
|
+
instanceVariable
|
|
354
|
+
omitNone
|
|
355
|
+
name="token"
|
|
356
|
+
type={pydanticModule["."].SecretStr}
|
|
357
|
+
/>
|
|
358
|
+
</py.PydanticClassDeclaration>
|
|
359
|
+
</TestOutput>,
|
|
360
|
+
).toRenderTo(
|
|
361
|
+
`
|
|
429
362
|
from pydantic import BaseModel
|
|
430
363
|
from typing import TYPE_CHECKING
|
|
431
364
|
|
|
@@ -436,26 +369,20 @@ describe("PydanticClassDeclaration", () => {
|
|
|
436
369
|
class Credentials(BaseModel):
|
|
437
370
|
token: SecretStr
|
|
438
371
|
|
|
439
|
-
|
|
440
372
|
`,
|
|
441
373
|
);
|
|
442
374
|
});
|
|
443
375
|
|
|
444
376
|
it("emits arbitrary model_config via modelConfigExpression", () => {
|
|
445
|
-
|
|
446
|
-
[
|
|
447
|
-
<py.
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
{ externals: [pydanticModule] },
|
|
455
|
-
);
|
|
456
|
-
|
|
457
|
-
expect(res).toRenderTo(
|
|
458
|
-
d`
|
|
377
|
+
expect(
|
|
378
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
379
|
+
<py.PydanticClassDeclaration
|
|
380
|
+
name="M"
|
|
381
|
+
modelConfigExpression={code`${pydanticModule["."].ConfigDict}(frozen=True, extra="allow")`}
|
|
382
|
+
/>
|
|
383
|
+
</TestOutput>,
|
|
384
|
+
).toRenderTo(
|
|
385
|
+
`
|
|
459
386
|
from pydantic import BaseModel
|
|
460
387
|
from pydantic import ConfigDict
|
|
461
388
|
|
|
@@ -463,66 +390,54 @@ describe("PydanticClassDeclaration", () => {
|
|
|
463
390
|
class M(BaseModel):
|
|
464
391
|
model_config = ConfigDict(frozen=True, extra="allow")
|
|
465
392
|
|
|
466
|
-
|
|
467
393
|
`,
|
|
468
394
|
);
|
|
469
395
|
});
|
|
470
396
|
|
|
471
397
|
it("supports RootModel as explicit bases entry", () => {
|
|
472
|
-
|
|
473
|
-
[
|
|
474
|
-
<py.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
{ externals: [pydanticModule] },
|
|
482
|
-
);
|
|
483
|
-
|
|
484
|
-
expect(res).toRenderTo(
|
|
485
|
-
d`
|
|
398
|
+
expect(
|
|
399
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
400
|
+
<py.PydanticClassDeclaration
|
|
401
|
+
name="Tags"
|
|
402
|
+
bases={[code`${pydanticModule["."].RootModel}[list[str]]`]}
|
|
403
|
+
/>
|
|
404
|
+
</TestOutput>,
|
|
405
|
+
).toRenderTo(
|
|
406
|
+
`
|
|
486
407
|
from pydantic import RootModel
|
|
487
408
|
|
|
488
409
|
|
|
489
410
|
class Tags(RootModel[list[str]]):
|
|
490
411
|
pass
|
|
491
412
|
|
|
492
|
-
|
|
493
413
|
`,
|
|
494
414
|
);
|
|
495
415
|
});
|
|
496
416
|
|
|
497
417
|
it("places Pydantic validators above classmethod", () => {
|
|
498
|
-
|
|
499
|
-
[
|
|
500
|
-
<py.
|
|
501
|
-
<py.
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
{ externals: [pydanticModule] },
|
|
522
|
-
);
|
|
523
|
-
|
|
524
|
-
expect(res).toRenderTo(
|
|
525
|
-
d`
|
|
418
|
+
expect(
|
|
419
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
420
|
+
<py.PydanticClassDeclaration name="User">
|
|
421
|
+
<py.VariableDeclaration
|
|
422
|
+
instanceVariable
|
|
423
|
+
omitNone
|
|
424
|
+
name="name"
|
|
425
|
+
type="str"
|
|
426
|
+
/>
|
|
427
|
+
<py.ClassMethodDeclaration
|
|
428
|
+
name="strip_name"
|
|
429
|
+
decorators={[
|
|
430
|
+
code`@${pydanticModule["."].field_validator}("name", mode="before")`,
|
|
431
|
+
]}
|
|
432
|
+
parameters={[{ name: "value", type: "str" }]}
|
|
433
|
+
returnType="str"
|
|
434
|
+
>
|
|
435
|
+
{"return value.strip()"}
|
|
436
|
+
</py.ClassMethodDeclaration>
|
|
437
|
+
</py.PydanticClassDeclaration>
|
|
438
|
+
</TestOutput>,
|
|
439
|
+
).toRenderTo(
|
|
440
|
+
`
|
|
526
441
|
from pydantic import BaseModel
|
|
527
442
|
from pydantic import field_validator
|
|
528
443
|
|
|
@@ -535,7 +450,6 @@ describe("PydanticClassDeclaration", () => {
|
|
|
535
450
|
return value.strip()
|
|
536
451
|
|
|
537
452
|
|
|
538
|
-
|
|
539
453
|
`,
|
|
540
454
|
);
|
|
541
455
|
});
|
|
@@ -543,23 +457,18 @@ describe("PydanticClassDeclaration", () => {
|
|
|
543
457
|
|
|
544
458
|
describe("Pydantic ecosystem emitters", () => {
|
|
545
459
|
it("typing module resolves Any and similar annotations", () => {
|
|
546
|
-
|
|
547
|
-
[
|
|
548
|
-
<py.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
{ externals: [typingModule] },
|
|
559
|
-
);
|
|
560
|
-
|
|
561
|
-
expect(res).toRenderTo(
|
|
562
|
-
d`
|
|
460
|
+
expect(
|
|
461
|
+
<TestOutput path="models.py" externals={[typingModule]}>
|
|
462
|
+
<py.FunctionDeclaration
|
|
463
|
+
name="identity"
|
|
464
|
+
parameters={[{ name: "x", type: typingModule["."].Any }]}
|
|
465
|
+
returnType={typingModule["."].Any}
|
|
466
|
+
>
|
|
467
|
+
{"return x"}
|
|
468
|
+
</py.FunctionDeclaration>
|
|
469
|
+
</TestOutput>,
|
|
470
|
+
).toRenderTo(
|
|
471
|
+
`
|
|
563
472
|
from typing import TYPE_CHECKING
|
|
564
473
|
|
|
565
474
|
if TYPE_CHECKING:
|
|
@@ -569,30 +478,24 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
569
478
|
def identity(x: Any) -> Any:
|
|
570
479
|
return x
|
|
571
480
|
|
|
572
|
-
|
|
573
481
|
`,
|
|
574
482
|
);
|
|
575
483
|
});
|
|
576
484
|
|
|
577
485
|
it("pydantic.types constrains field annotations", () => {
|
|
578
|
-
|
|
579
|
-
[
|
|
580
|
-
<py.
|
|
581
|
-
<py.
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
{ externals: [pydanticModule] },
|
|
592
|
-
);
|
|
593
|
-
|
|
594
|
-
expect(res).toRenderTo(
|
|
595
|
-
d`
|
|
486
|
+
expect(
|
|
487
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
488
|
+
<py.PydanticClassDeclaration name="Score">
|
|
489
|
+
<py.VariableDeclaration
|
|
490
|
+
instanceVariable
|
|
491
|
+
omitNone
|
|
492
|
+
name="points"
|
|
493
|
+
type={pydanticModule.types.PositiveInt}
|
|
494
|
+
/>
|
|
495
|
+
</py.PydanticClassDeclaration>
|
|
496
|
+
</TestOutput>,
|
|
497
|
+
).toRenderTo(
|
|
498
|
+
`
|
|
596
499
|
from pydantic import BaseModel
|
|
597
500
|
from typing import TYPE_CHECKING
|
|
598
501
|
|
|
@@ -603,14 +506,13 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
603
506
|
class Score(BaseModel):
|
|
604
507
|
points: PositiveInt
|
|
605
508
|
|
|
606
|
-
|
|
607
509
|
`,
|
|
608
510
|
);
|
|
609
511
|
});
|
|
610
512
|
|
|
611
513
|
it("postponed annotations support forward references in fields", () => {
|
|
612
|
-
|
|
613
|
-
[
|
|
514
|
+
expect(
|
|
515
|
+
<TestOutputDirectory externals={[pydanticModule]}>
|
|
614
516
|
<py.SourceFile
|
|
615
517
|
path="models.py"
|
|
616
518
|
futureImports={[<py.FutureStatement feature="annotations" />]}
|
|
@@ -628,42 +530,33 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
628
530
|
type={code`"Node" | None`}
|
|
629
531
|
/>
|
|
630
532
|
</py.PydanticClassDeclaration>
|
|
631
|
-
</py.SourceFile
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
expect(res).toRenderTo(
|
|
637
|
-
d`
|
|
638
|
-
from __future__ import annotations
|
|
639
|
-
|
|
640
|
-
from pydantic import BaseModel
|
|
533
|
+
</py.SourceFile>
|
|
534
|
+
</TestOutputDirectory>,
|
|
535
|
+
).toRenderTo({
|
|
536
|
+
"models.py": `
|
|
537
|
+
from __future__ import annotations
|
|
641
538
|
|
|
539
|
+
from pydantic import BaseModel
|
|
642
540
|
|
|
643
|
-
class Node(BaseModel):
|
|
644
|
-
label: str
|
|
645
|
-
child: "Node" | None = None
|
|
646
541
|
|
|
542
|
+
class Node(BaseModel):
|
|
543
|
+
label: str
|
|
544
|
+
child: "Node" | None = None
|
|
647
545
|
|
|
648
|
-
|
|
649
|
-
);
|
|
546
|
+
`,
|
|
547
|
+
});
|
|
650
548
|
});
|
|
651
549
|
|
|
652
550
|
it("model_config can use pydantic.alias_generators", () => {
|
|
653
|
-
|
|
654
|
-
[
|
|
655
|
-
<py.
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
{ externals: [pydanticModule] },
|
|
663
|
-
);
|
|
664
|
-
|
|
665
|
-
expect(res).toRenderTo(
|
|
666
|
-
d`
|
|
551
|
+
expect(
|
|
552
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
553
|
+
<py.PydanticClassDeclaration
|
|
554
|
+
name="M"
|
|
555
|
+
modelConfigExpression={code`${pydanticModule["."].ConfigDict}(alias_generator=${pydanticModule.alias_generators.to_camel})`}
|
|
556
|
+
/>
|
|
557
|
+
</TestOutput>,
|
|
558
|
+
).toRenderTo(
|
|
559
|
+
`
|
|
667
560
|
from pydantic import BaseModel
|
|
668
561
|
from pydantic import ConfigDict
|
|
669
562
|
from pydantic.alias_generators import to_camel
|
|
@@ -672,63 +565,51 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
672
565
|
class M(BaseModel):
|
|
673
566
|
model_config = ConfigDict(alias_generator=to_camel)
|
|
674
567
|
|
|
675
|
-
|
|
676
568
|
`,
|
|
677
569
|
);
|
|
678
570
|
});
|
|
679
571
|
|
|
680
572
|
it("pydantic_settings exposes BaseSettings", () => {
|
|
681
|
-
|
|
682
|
-
[
|
|
683
|
-
<py.
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
{ externals: [pydanticSettingsModule] },
|
|
691
|
-
);
|
|
692
|
-
|
|
693
|
-
expect(res).toRenderTo(
|
|
694
|
-
d`
|
|
573
|
+
expect(
|
|
574
|
+
<TestOutput path="config.py" externals={[pydanticSettingsModule]}>
|
|
575
|
+
<py.ClassDeclaration
|
|
576
|
+
name="AppSettings"
|
|
577
|
+
bases={[pydanticSettingsModule["."].BaseSettings]}
|
|
578
|
+
/>
|
|
579
|
+
</TestOutput>,
|
|
580
|
+
).toRenderTo(
|
|
581
|
+
`
|
|
695
582
|
from pydantic_settings import BaseSettings
|
|
696
583
|
|
|
697
584
|
|
|
698
585
|
class AppSettings(BaseSettings):
|
|
699
586
|
pass
|
|
700
587
|
|
|
701
|
-
|
|
702
588
|
`,
|
|
703
589
|
);
|
|
704
590
|
});
|
|
705
591
|
|
|
706
592
|
it("emits @computed_field above @property via PropertyDeclaration", () => {
|
|
707
|
-
|
|
708
|
-
[
|
|
709
|
-
<py.
|
|
710
|
-
<py.
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
{ externals: [pydanticModule] },
|
|
728
|
-
);
|
|
729
|
-
|
|
730
|
-
expect(res).toRenderTo(
|
|
731
|
-
d`
|
|
593
|
+
expect(
|
|
594
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
595
|
+
<py.PydanticClassDeclaration name="Square">
|
|
596
|
+
<py.VariableDeclaration
|
|
597
|
+
instanceVariable
|
|
598
|
+
omitNone
|
|
599
|
+
name="width"
|
|
600
|
+
type="float"
|
|
601
|
+
/>
|
|
602
|
+
<py.PropertyDeclaration
|
|
603
|
+
name="area"
|
|
604
|
+
type="float"
|
|
605
|
+
decorators={[code`@${pydanticModule["."].computed_field}`]}
|
|
606
|
+
>
|
|
607
|
+
{"return self.width ** 2"}
|
|
608
|
+
</py.PropertyDeclaration>
|
|
609
|
+
</py.PydanticClassDeclaration>
|
|
610
|
+
</TestOutput>,
|
|
611
|
+
).toRenderTo(
|
|
612
|
+
`
|
|
732
613
|
from pydantic import BaseModel
|
|
733
614
|
from pydantic import computed_field
|
|
734
615
|
|
|
@@ -741,37 +622,31 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
741
622
|
return self.width ** 2
|
|
742
623
|
|
|
743
624
|
|
|
744
|
-
|
|
745
625
|
`,
|
|
746
626
|
);
|
|
747
627
|
});
|
|
748
628
|
|
|
749
629
|
it("emits computed_field on an instance method", () => {
|
|
750
|
-
|
|
751
|
-
[
|
|
752
|
-
<py.
|
|
753
|
-
<py.
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
{ externals: [pydanticModule] },
|
|
771
|
-
);
|
|
772
|
-
|
|
773
|
-
expect(res).toRenderTo(
|
|
774
|
-
d`
|
|
630
|
+
expect(
|
|
631
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
632
|
+
<py.PydanticClassDeclaration name="Square">
|
|
633
|
+
<py.VariableDeclaration
|
|
634
|
+
instanceVariable
|
|
635
|
+
omitNone
|
|
636
|
+
name="width"
|
|
637
|
+
type="float"
|
|
638
|
+
/>
|
|
639
|
+
<py.MethodDeclaration
|
|
640
|
+
name="area"
|
|
641
|
+
decorators={[code`@${pydanticModule["."].computed_field}`]}
|
|
642
|
+
returnType="float"
|
|
643
|
+
>
|
|
644
|
+
{"return self.width ** 2"}
|
|
645
|
+
</py.MethodDeclaration>
|
|
646
|
+
</py.PydanticClassDeclaration>
|
|
647
|
+
</TestOutput>,
|
|
648
|
+
).toRenderTo(
|
|
649
|
+
`
|
|
775
650
|
from pydantic import BaseModel
|
|
776
651
|
from pydantic import computed_field
|
|
777
652
|
|
|
@@ -783,40 +658,34 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
783
658
|
return self.width ** 2
|
|
784
659
|
|
|
785
660
|
|
|
786
|
-
|
|
787
661
|
`,
|
|
788
662
|
);
|
|
789
663
|
});
|
|
790
664
|
|
|
791
665
|
it("emits model_validator above classmethod", () => {
|
|
792
|
-
|
|
793
|
-
[
|
|
794
|
-
<py.
|
|
795
|
-
<py.
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
{ externals: [pydanticModule] },
|
|
816
|
-
);
|
|
817
|
-
|
|
818
|
-
expect(res).toRenderTo(
|
|
819
|
-
d`
|
|
666
|
+
expect(
|
|
667
|
+
<TestOutput path="models.py" externals={[pydanticModule]}>
|
|
668
|
+
<py.PydanticClassDeclaration name="Bag">
|
|
669
|
+
<py.VariableDeclaration
|
|
670
|
+
instanceVariable
|
|
671
|
+
omitNone
|
|
672
|
+
name="items"
|
|
673
|
+
type="list"
|
|
674
|
+
/>
|
|
675
|
+
<py.ClassMethodDeclaration
|
|
676
|
+
name="ensure_items"
|
|
677
|
+
decorators={[
|
|
678
|
+
code`@${pydanticModule["."].model_validator}(mode="before")`,
|
|
679
|
+
]}
|
|
680
|
+
parameters={[{ name: "data", type: "dict" }]}
|
|
681
|
+
returnType="dict"
|
|
682
|
+
>
|
|
683
|
+
{"return data"}
|
|
684
|
+
</py.ClassMethodDeclaration>
|
|
685
|
+
</py.PydanticClassDeclaration>
|
|
686
|
+
</TestOutput>,
|
|
687
|
+
).toRenderTo(
|
|
688
|
+
`
|
|
820
689
|
from pydantic import BaseModel
|
|
821
690
|
from pydantic import model_validator
|
|
822
691
|
|
|
@@ -829,7 +698,6 @@ describe("Pydantic ecosystem emitters", () => {
|
|
|
829
698
|
return data
|
|
830
699
|
|
|
831
700
|
|
|
832
|
-
|
|
833
701
|
`,
|
|
834
702
|
);
|
|
835
703
|
});
|