@@ -6,21 +6,20 @@ import { assert } from "jsr:@std/assert";
66const header = ( relativePath : string ) =>
77 `# DO NOT EDIT: This file is auto-generated by ${ relativePath } \n` +
88 "from enum import Enum\n" +
9- "from typing import Any, Literal, Optional, Union\n" +
109 "import msgspec\n\n" ;
1110
1211export function extractExportedNames ( content : string ) : string [ ] {
1312 const names = new Set < string > ( ) ;
1413
15- // Match class definitions and enum assignments
14+ // Match class definitions and union type assignments
1615 const classRegex = / ^ c l a s s \s + ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) / gm;
17- const enumRegex = / ^ ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) \s * = \s * U n i o n \[ / gm;
16+ const unionRegex = / ^ ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) \s * = \s * . + \| . + / gm;
1817
1918 let match ;
2019 while ( ( match = classRegex . exec ( content ) ) !== null ) {
2120 names . add ( match [ 1 ] ) ;
2221 }
23- while ( ( match = enumRegex . exec ( content ) ) !== null ) {
22+ while ( ( match = unionRegex . exec ( content ) ) !== null ) {
2423 names . add ( match [ 1 ] ) ;
2524 }
2625
@@ -51,10 +50,7 @@ export function generatePython(
5150 return output + content ;
5251}
5352
54- function generateTypes (
55- doc : Doc ,
56- name : string ,
57- ) {
53+ function generateTypes ( doc : Doc , name : string ) {
5854 const writer = new Writer ( ) ;
5955
6056 let definitions = "" ;
@@ -97,9 +93,7 @@ function generateTypes(
9793 return definitions + writer . output ( ) ;
9894}
9995
100- function sortByRequired < T extends { required : boolean } > (
101- properties : T [ ] ,
102- ) : T [ ] {
96+ function sortByRequired < T extends { required : boolean } > ( properties : T [ ] ) : T [ ] {
10397 return [ ...properties ] . sort ( ( a , b ) => {
10498 if ( a . required === b . required ) return 0 ;
10599 return a . required ? - 1 : 1 ;
@@ -116,9 +110,8 @@ function generateNode(node: Node, writer: Writer) {
116110 . with ( { type : "boolean" } , ( ) => w ( "bool" ) )
117111 . with ( { type : "string" } , ( ) => w ( "str" ) )
118112 . with ( { type : "literal" } , ( node ) => w ( `Literal["${ node . value } "]` ) )
119- . with (
120- { type : "record" } ,
121- ( node ) => w ( `dict[str, ${ mapPythonType ( node . valueType ) } ]` ) ,
113+ . with ( { type : "record" } , ( node ) =>
114+ w ( `dict[str, ${ mapPythonType ( node . valueType ) } ]` ) ,
122115 )
123116 . with ( { type : "enum" } , ( node ) => {
124117 wn ( `class ${ node . name } (str, Enum):` ) ;
@@ -134,9 +127,10 @@ function generateNode(node: Node, writer: Writer) {
134127 if ( m . name ) {
135128 name = m . name ;
136129 } else {
137- const ident = m . type === "object"
138- ? m . properties ?. find ( ( p ) => p . required ) ?. key ?? ""
139- : "" ;
130+ const ident =
131+ m . type === "object"
132+ ? ( m . properties ?. find ( ( p ) => p . required ) ?. key ?? "" )
133+ : "" ;
140134 name = `${ node . name } ${ cap ( ident ) } ` ;
141135 }
142136 if ( ! generatedDependentClasses . has ( name ) ) {
@@ -148,17 +142,17 @@ function generateNode(node: Node, writer: Writer) {
148142 return name ;
149143 } ) ;
150144 writer . append ( depWriter . output ( ) ) ;
151- wn ( `${ node . name } = Union[ ${ classes . join ( ", " ) } ] ` ) ;
145+ wn ( `${ node . name } = ${ classes . join ( " | " ) } ` ) ;
152146 } )
153147 . with ( { type : "object" } , ( node ) => {
154148 match ( context . parent )
155149 . with ( { type : "union" } , ( ) => {
156150 const name = context . closestName ( ) ;
157151 const ident = node . properties . find ( ( p ) => p . required ) ?. key ?? "" ;
158152 wn (
159- `class ${ name } ${
160- cap ( ident )
161- } (msgspec.Struct, kw_only=True, omit_defaults=True):`,
153+ `class ${ name } ${ cap (
154+ ident ,
155+ ) } (msgspec.Struct, kw_only=True, omit_defaults=True):`,
162156 ) ;
163157 } )
164158 . with ( P . nullish , ( ) => {
@@ -179,9 +173,8 @@ function generateNode(node: Node, writer: Writer) {
179173
180174 for ( const { key, required, description, value } of sortedProperties ) {
181175 w ( ` ${ key } : ` ) ;
182- if ( ! required ) w ( "Union[" ) ;
183176 generateNode ( value , writer ) ;
184- if ( ! required ) w ( ", None] = None" ) ;
177+ if ( ! required ) w ( " | None = None" ) ;
185178 wn ( "" ) ;
186179 if ( description ) {
187180 wn ( ` """${ description } """` ) ;
@@ -193,7 +186,6 @@ function generateNode(node: Node, writer: Writer) {
193186 const depWriter = new Writer ( ) ;
194187 const { w : d , wn : dn } = depWriter . shorthand ( ) ;
195188 const classes : string [ ] = [ ] ;
196- w ( "Union[" ) ;
197189 for ( const [ name , properties ] of Object . entries ( node . members ) ) {
198190 for ( const { value } of properties ) {
199191 if ( isComplexType ( value ) ) {
@@ -213,15 +205,17 @@ function generateNode(node: Node, writer: Writer) {
213205
214206 const sortedProperties = sortByRequired ( properties ) ;
215207
216- for (
217- const { key, required, description, value } of sortedProperties
218- ) {
208+ for ( const {
209+ key,
210+ required,
211+ description,
212+ value,
213+ } of sortedProperties ) {
219214 d ( ` ${ key } : ` ) ;
220- if ( ! required ) d ( "Union[" ) ;
221215 ! isComplexType ( value )
222216 ? generateNode ( value , depWriter )
223217 : d ( value . name ?? value . type ) ;
224- if ( ! required ) d ( ", None] = None" ) ;
218+ if ( ! required ) d ( " | None = None" ) ;
225219 dn ( "" ) ;
226220 if ( description ) {
227221 dn ( ` """${ description } """` ) ;
@@ -230,9 +224,9 @@ function generateNode(node: Node, writer: Writer) {
230224 dn ( "" ) ;
231225 }
232226 }
233- w ( classes . join ( ", " ) ) ;
227+ w ( classes . join ( " | " ) ) ;
234228 writer . prepend ( depWriter . output ( ) ) ;
235- wn ( "] " ) ;
229+ wn ( "" ) ;
236230 } )
237231 . with ( { type : "intersection" } , ( node ) => {
238232 assert (
0 commit comments