@@ -32,12 +32,37 @@ import {
3232 * - Callable from collections.abc instead of typing
3333 * - Clean up unused typing imports
3434 */
35+ function replaceBalancedBrackets ( code : string , prefix : string , replacer : ( inner : string ) => string ) : string {
36+ let result = "" ;
37+ let i = 0 ;
38+ while ( i < code . length ) {
39+ const idx = code . indexOf ( prefix + "[" , i ) ;
40+ if ( idx === - 1 ) {
41+ result += code . slice ( i ) ;
42+ break ;
43+ }
44+ result += code . slice ( i , idx ) ;
45+ const start = idx + prefix . length + 1 ; // after '['
46+ let depth = 1 ;
47+ let j = start ;
48+ while ( j < code . length && depth > 0 ) {
49+ if ( code [ j ] === "[" ) depth ++ ;
50+ else if ( code [ j ] === "]" ) depth -- ;
51+ j ++ ;
52+ }
53+ const inner = code . slice ( start , j - 1 ) ;
54+ result += replacer ( inner ) ;
55+ i = j ;
56+ }
57+ return result ;
58+ }
59+
3560function modernizePython ( code : string ) : string {
36- // Replace Optional[X] with X | None (handles nested brackets)
37- code = code . replace ( / O p t i o n a l \[ ( [ ^ \[ \] ] * (?: \[ [ ^ \[ \] ] * \] ) * [ ^ \[ \] ] * ) \] / g , "$1 | None" ) ;
61+ // Replace Optional[X] with X | None (handles arbitrarily nested brackets)
62+ code = replaceBalancedBrackets ( code , " Optional" , ( inner ) => ` ${ inner } | None` ) ;
3863
3964 // Replace Union[X, Y] with X | Y
40- code = code . replace ( / U n i o n \[ ( [ ^ \[ \] ] * (?: \[ [ ^ \[ \] ] * \] ) * [ ^ \[ \] ] * ) \] / g , ( _match , inner : string ) => {
65+ code = replaceBalancedBrackets ( code , "Union" , ( inner ) => {
4166 return inner . split ( "," ) . map ( ( s : string ) => s . trim ( ) ) . join ( " | " ) ;
4267 } ) ;
4368
0 commit comments