22// The .NET Foundation licenses this file to you under the Apache 2.0 License.
33// See the LICENSE file in the project root for more information.
44
5+ #nullable enable
6+
57using System ;
68using System . Buffers ;
79using System . Collections ;
810using System . Collections . Generic ;
11+ using System . Diagnostics . CodeAnalysis ;
912using System . Numerics ;
1013
1114namespace IronPython . Runtime {
1215
1316 public class ListGenericWrapper < T > : IList < T > {
14- private readonly IList < object > _value ;
17+ private readonly IList < object ? > _value ;
1518 // PEP 237: int/long unification (GH #52)
1619 private static readonly bool IsBigIntWrapper = typeof ( T ) == typeof ( BigInteger ) || typeof ( T ) == typeof ( BigInteger ? ) ;
1720
18- public ListGenericWrapper ( IList < object > value ) { _value = value ; }
21+ public ListGenericWrapper ( IList < object ? > value ) {
22+ _value = value ?? throw new ArgumentNullException ( nameof ( value ) ) ;
23+ }
1924
2025 #region IList<T> Members
2126
@@ -40,11 +45,17 @@ public void RemoveAt(int index) {
4045
4146 public T this [ int index ] {
4247 get {
43- object item = _value [ index ] ;
48+ object ? item = _value [ index ] ;
4449 if ( IsBigIntWrapper && item is int i32 ) {
4550 item = new BigInteger ( i32 ) ;
4651 }
47- return ( T ) item ;
52+ try {
53+ return ( T ) item ! ;
54+ } catch ( NullReferenceException nex ) {
55+ throw new InvalidCastException ( string . Format ( "Error in ListGenericWrapper.this[]. Could not cast: from null to {0}" , typeof ( T ) . ToString ( ) ) , nex ) ;
56+ } catch ( InvalidCastException iex ) {
57+ throw new InvalidCastException ( string . Format ( "Error in ListGenericWrapper.this[]. Could not cast: from {1} to {0}" , typeof ( T ) . ToString ( ) , item ! . GetType ( ) . ToString ( ) ) , iex ) ;
58+ }
4859 }
4960
5061 set => _value [ index ] = value ;
@@ -112,61 +123,65 @@ IEnumerator IEnumerable.GetEnumerator() {
112123 #endregion
113124 }
114125
126+ #if NETCOREAPP3_1 // In netcoreapp3.1, IDictionary<K, V> has constraint where K : notnull
127+ #nullable disable warnings
128+ #endif
129+
115130 public class DictionaryGenericWrapper < K , V > : IDictionary < K , V > {
116- private readonly IDictionary < object , object > self ;
131+ private readonly IDictionary < object ? , object ? > self ;
117132 // PEP 237: int/long unification (GH #52)
118133 private static readonly bool IsBigIntWrapperK = typeof ( K ) == typeof ( BigInteger ) || typeof ( K ) == typeof ( BigInteger ? ) ;
119134 private static readonly bool IsBigIntWrapperV = typeof ( V ) == typeof ( BigInteger ) || typeof ( V ) == typeof ( BigInteger ? ) ;
120135
121- public DictionaryGenericWrapper ( IDictionary < object , object > self ) {
122- this . self = self ;
136+ public DictionaryGenericWrapper ( IDictionary < object ? , object ? > self ) {
137+ this . self = self ?? throw new ArgumentNullException ( nameof ( self ) ) ;
123138 }
124139
125140 #region IDictionary<K,V> Members
126141
127142 public void Add ( K key , V value ) {
128- object okey = key ;
129- if ( IsValidKey32 ( key , out object i32 ) && self . ContainsKey ( i32 ) ) {
143+ object ? okey = key ;
144+ if ( IsValidKey32 ( key , out object ? i32 ) && self . ContainsKey ( i32 ) ) {
130145 okey = i32 ;
131146 }
132147 self . Add ( okey , value ) ;
133148 }
134149
135150 public bool ContainsKey ( K key ) {
136- return self . ContainsKey ( key ) || ( IsValidKey32 ( key , out object i32 ) && self . ContainsKey ( i32 ) ) ;
151+ return self . ContainsKey ( key ) || ( IsValidKey32 ( key , out object ? i32 ) && self . ContainsKey ( i32 ) ) ;
137152 }
138153
139154 public ICollection < K > Keys {
140155 get {
141156 List < K > res = new List < K > ( Count ) ;
142- foreach ( object o in self . Keys ) {
157+ foreach ( object ? o in self . Keys ) {
143158 res . Add ( CastKey ( o ) ) ;
144159 }
145160 return res ;
146161 }
147162 }
148163
149164 public bool Remove ( K key ) {
150- return self . Remove ( key ) || ( IsValidKey32 ( key , out object i32 ) && self . Remove ( i32 ) ) ;
165+ return self . Remove ( key ) || ( IsValidKey32 ( key , out object ? i32 ) && self . Remove ( i32 ) ) ;
151166 }
152167
153168 public bool TryGetValue ( K key , out V value ) {
154- if ( self . TryGetValue ( key , out object outValue ) ) {
169+ if ( self . TryGetValue ( key , out object ? outValue ) ) {
155170 value = CastValue ( outValue ) ;
156171 return true ;
157172 }
158- if ( IsValidKey32 ( key , out object i32 ) && self . TryGetValue ( i32 , out object outValue2 ) ) {
173+ if ( IsValidKey32 ( key , out object ? i32 ) && self . TryGetValue ( i32 , out object ? outValue2 ) ) {
159174 value = CastValue ( outValue2 ) ;
160175 return true ;
161176 }
162- value = default ;
177+ value = default ( V ) ! ;
163178 return false ;
164179 }
165180
166181 public ICollection < V > Values {
167182 get {
168183 List < V > res = new List < V > ( ) ;
169- foreach ( object o in self . Values ) {
184+ foreach ( object ? o in self . Values ) {
170185 res . Add ( CastValue ( o ) ) ;
171186 }
172187 return res ;
@@ -191,23 +206,23 @@ public V this[K key] {
191206 #region ICollection<KeyValuePair<K,V>> Members
192207
193208 public void Add ( KeyValuePair < K , V > item ) {
194- object key = item . Key ;
195- if ( IsValidKey32 ( item . Key , out object i32 ) && self . ContainsKey ( i32 ) ) {
209+ object ? key = item . Key ;
210+ if ( IsValidKey32 ( item . Key , out object ? i32 ) && self . ContainsKey ( i32 ) ) {
196211 key = i32 ;
197212 }
198- self . Add ( new KeyValuePair < object , object > ( key , item . Value ) ) ;
213+ self . Add ( new KeyValuePair < object ? , object ? > ( key , item . Value ) ) ;
199214 }
200215
201216 public void Clear ( ) {
202217 self . Clear ( ) ;
203218 }
204219
205220 public bool Contains ( KeyValuePair < K , V > item ) {
206- object key = item . Key ;
207- if ( IsValidKey32 ( item . Key , out object i32 ) && self . ContainsKey ( i32 ) ) {
221+ object ? key = item . Key ;
222+ if ( IsValidKey32 ( item . Key , out object ? i32 ) && self . ContainsKey ( i32 ) ) {
208223 key = i32 ;
209224 }
210- return self . Contains ( new KeyValuePair < object , object > ( key , item . Value ) ) ;
225+ return self . Contains ( new KeyValuePair < object ? , object ? > ( key , item . Value ) ) ;
211226 }
212227
213228 public void CopyTo ( KeyValuePair < K , V > [ ] array , int arrayIndex ) {
@@ -225,19 +240,19 @@ public bool IsReadOnly {
225240 }
226241
227242 public bool Remove ( KeyValuePair < K , V > item ) {
228- object key = item . Key ;
229- if ( IsValidKey32 ( item . Key , out object i32 ) && self . ContainsKey ( i32 ) ) {
243+ object ? key = item . Key ;
244+ if ( IsValidKey32 ( item . Key , out object ? i32 ) && self . ContainsKey ( i32 ) ) {
230245 key = i32 ;
231246 }
232- return self . Remove ( new KeyValuePair < object , object > ( key , item . Value ) ) ;
247+ return self . Remove ( new KeyValuePair < object ? , object ? > ( key , item . Value ) ) ;
233248 }
234249
235250 #endregion
236251
237252 #region IEnumerable<KeyValuePair<K,V>> Members
238253
239254 public IEnumerator < KeyValuePair < K , V > > GetEnumerator ( ) {
240- foreach ( KeyValuePair < object , object > kv in self ) {
255+ foreach ( KeyValuePair < object ? , object ? > kv in self ) {
241256 yield return new KeyValuePair < K , V > ( CastKey ( kv . Key ) , CastValue ( kv . Value ) ) ;
242257 }
243258 }
@@ -252,21 +267,33 @@ IEnumerator IEnumerable.GetEnumerator() {
252267
253268 #endregion
254269
255- private static K CastKey ( object key ) {
270+ private static K CastKey ( object ? key ) {
256271 if ( IsBigIntWrapperK && key is int i32 ) {
257272 key = new BigInteger ( i32 ) ;
258273 }
259- return ( K ) key ;
274+ try {
275+ return ( K ) key ! ;
276+ } catch ( NullReferenceException nex ) {
277+ throw new InvalidCastException ( string . Format ( "Error in DictionaryGenericWrapper.CastKey. Could not cast: from null to {0}" , typeof ( K ) . ToString ( ) ) , nex ) ;
278+ } catch ( InvalidCastException iex ) {
279+ throw new InvalidCastException ( string . Format ( "Error in DictionaryGenericWrapper.CastKey. Could not cast: from {1} to {0}" , typeof ( K ) . ToString ( ) , key ! . GetType ( ) . ToString ( ) ) , iex ) ;
280+ }
260281 }
261282
262- private static V CastValue ( object val ) {
283+ private static V CastValue ( object ? val ) {
263284 if ( IsBigIntWrapperV && val is int i32 ) {
264285 val = new BigInteger ( i32 ) ;
265286 }
266- return ( V ) val ;
287+ try {
288+ return ( V ) val ! ;
289+ } catch ( NullReferenceException nex ) {
290+ throw new InvalidCastException ( string . Format ( "Error in DictionaryGenericWrapper.CastValue. Could not cast: from null to {0}" , typeof ( V ) . ToString ( ) ) , nex ) ;
291+ } catch ( InvalidCastException iex ) {
292+ throw new InvalidCastException ( string . Format ( "Error in DictionaryGenericWrapper.CastValue. Could not cast: from {1} to {0}" , typeof ( V ) . ToString ( ) , val ! . GetType ( ) . ToString ( ) ) , iex ) ;
293+ }
267294 }
268295
269- private static bool IsValidKey32 ( K key , out object key32 ) {
296+ private static bool IsValidKey32 ( K key , [ NotNullWhen ( true ) ] out object ? key32 ) {
270297 if ( IsBigIntWrapperK && key is BigInteger bi && bi >= int . MinValue && bi <= int . MaxValue ) {
271298 key32 = ( int ) bi ;
272299 return true ;
@@ -276,26 +303,33 @@ private static bool IsValidKey32(K key, out object key32) {
276303 }
277304 }
278305
306+ #if NETCOREAPP3_1
307+ #nullable enable
308+ #endif
309+
279310 public class IEnumeratorOfTWrapper < T > : IEnumerator < T > {
280311 private readonly IEnumerator enumerable ;
281312 // PEP 237: int/long unification (GH #52)
282313 private static readonly bool IsBigIntWrapper = typeof ( T ) == typeof ( BigInteger ) || typeof ( T ) == typeof ( BigInteger ? ) ;
283314
284315 public IEnumeratorOfTWrapper ( IEnumerator enumerable ) {
285- this . enumerable = enumerable ;
316+ this . enumerable = enumerable ?? throw new ArgumentNullException ( nameof ( enumerable ) ) ;
286317 }
287318
288319 #region IEnumerator<T> Members
320+
289321 public T Current {
290322 get {
323+ object ? current = enumerable . Current ;
324+ if ( IsBigIntWrapper && current is int i32 ) {
325+ current = new BigInteger ( i32 ) ;
326+ }
291327 try {
292- object current = enumerable . Current ;
293- if ( IsBigIntWrapper && current is int i32 ) {
294- current = new BigInteger ( i32 ) ;
295- }
296- return ( T ) current ;
297- } catch ( System . InvalidCastException iex ) {
298- throw new System . InvalidCastException ( string . Format ( "Error in IEnumeratorOfTWrapper.Current. Could not cast: from {1} to {0}" , typeof ( T ) . ToString ( ) , enumerable . Current . GetType ( ) . ToString ( ) ) , iex ) ;
328+ return ( T ) current ! ;
329+ } catch ( NullReferenceException nex ) {
330+ throw new InvalidCastException ( string . Format ( "Error in IEnumeratorOfTWrapper.Current. Could not cast: from null to {0}" , typeof ( T ) . ToString ( ) ) , nex ) ;
331+ } catch ( InvalidCastException iex ) {
332+ throw new InvalidCastException ( string . Format ( "Error in IEnumeratorOfTWrapper.Current. Could not cast: from {1} to {0}" , typeof ( T ) . ToString ( ) , current ! . GetType ( ) . ToString ( ) ) , iex ) ;
299333 }
300334 }
301335 }
@@ -311,7 +345,7 @@ public void Dispose() {
311345
312346 #region IEnumerator Members
313347
314- object IEnumerator . Current {
348+ object ? IEnumerator . Current {
315349 get { return enumerable . Current ; }
316350 }
317351
@@ -326,12 +360,11 @@ public void Reset() {
326360 #endregion
327361 }
328362
329- [ PythonType ( "enumerable_wrapper" ) ]
330363 public class IEnumerableOfTWrapper < T > : IEnumerable < T > , IEnumerable {
331364 private readonly IEnumerable enumerable ;
332365
333366 public IEnumerableOfTWrapper ( IEnumerable enumerable ) {
334- this . enumerable = enumerable ;
367+ this . enumerable = enumerable ?? throw new ArgumentNullException ( nameof ( enumerable ) ) ;
335368 }
336369
337370 #region IEnumerable<T> Members
@@ -351,8 +384,6 @@ IEnumerator IEnumerable.GetEnumerator() {
351384 #endregion
352385 }
353386
354- #nullable enable
355-
356387 public sealed class MemoryBufferWrapper : IPythonBuffer {
357388 private readonly ReadOnlyMemory < byte > _rom ;
358389 private readonly Memory < byte > ? _memory ;
@@ -425,6 +456,4 @@ public IPythonBuffer GetBuffer(BufferFlags flags) {
425456 return new MemoryBufferWrapper ( _rom , flags ) ;
426457 }
427458 }
428-
429- #nullable restore
430459}
0 commit comments