@@ -106,24 +106,63 @@ static NewReference tp_new_impl(BorrowedReference tp, BorrowedReference args, Bo
106106
107107 /// <summary>
108108 /// Construct a new .NET String object from Python args
109+ ///
110+ /// This manual implementation of all individual relevant constructors
111+ /// is required because System.String can't be allocated uninitialized.
112+ ///
113+ /// Additionally, it implements `String(pythonStr)`
109114 /// </summary>
110115 private static NewReference NewString ( BorrowedReference args , BorrowedReference tp )
111116 {
112- if ( Runtime . PyTuple_Size ( args ) == 1 )
117+ var argCount = Runtime . PyTuple_Size ( args ) ;
118+
119+ string ? result = null ;
120+ if ( argCount == 1 )
113121 {
114122 BorrowedReference ob = Runtime . PyTuple_GetItem ( args , 0 ) ;
115123 if ( Runtime . PyString_Check ( ob ) )
116124 {
117125 if ( Runtime . GetManagedString ( ob ) is string val )
118- return CLRObject . GetReference ( val , tp ) ;
126+ result = val ;
119127 }
128+ else if ( Converter . ToManagedValue ( ob , typeof ( char [ ] ) , out object ? arr , false ) )
129+ {
130+ result = new String ( ( char [ ] ) arr ! ) ;
131+ }
132+ }
133+ else if ( argCount == 2 )
134+ {
135+ BorrowedReference p1 = Runtime . PyTuple_GetItem ( args , 0 ) ;
136+ BorrowedReference p2 = Runtime . PyTuple_GetItem ( args , 1 ) ;
120137
121- // TODO: Initialise using constructors instead
122-
123- Exceptions . SetError ( Exceptions . TypeError , "no constructors match given arguments" ) ;
124- return default ;
138+ if (
139+ Converter . ToManagedValue ( p1 , typeof ( char ) , out object ? chr , false ) &&
140+ Converter . ToManagedValue ( p2 , typeof ( int ) , out object ? count , false )
141+ )
142+ {
143+ result = new String ( ( char ) chr ! , ( int ) count ! ) ;
144+ }
145+ }
146+ else if ( argCount == 3 )
147+ {
148+ BorrowedReference p1 = Runtime . PyTuple_GetItem ( args , 0 ) ;
149+ BorrowedReference p2 = Runtime . PyTuple_GetItem ( args , 1 ) ;
150+ BorrowedReference p3 = Runtime . PyTuple_GetItem ( args , 2 ) ;
151+
152+ if (
153+ Converter . ToManagedValue ( p1 , typeof ( char [ ] ) , out object ? arr , false ) &&
154+ Converter . ToManagedValue ( p2 , typeof ( int ) , out object ? offset , false ) &&
155+ Converter . ToManagedValue ( p3 , typeof ( int ) , out object ? length , false )
156+ )
157+ {
158+ result = new String ( ( char [ ] ) arr ! , ( int ) offset ! , ( int ) length ! ) ;
159+ }
125160 }
126161
162+ if ( result != null )
163+ return CLRObject . GetReference ( result ! , tp ) ;
164+
165+ Exceptions . SetError ( Exceptions . TypeError , "no constructors match given arguments" ) ;
127166 return default ;
128167 }
129168
0 commit comments