@@ -40,7 +40,7 @@ public partial class PythonType : IPythonMembersList, IDynamicMetaObjectProvider
4040 private PythonTypeAttributes _attrs ; // attributes of the type
4141 private int _flags ; // CPython-like flags on the type
4242 private int _version = GetNextVersion ( ) ; // version of the type
43- private List < WeakReference > _subtypes ; // all of the subtypes of the PythonType
43+ private List < WeakReference < PythonType > > _subtypes ; // all of the subtypes of the PythonType
4444 private PythonContext _pythonContext ; // the context the type was created from, or null for system types.
4545 private bool ? _objectNew , _objectInit ; // true if the type doesn't override __new__ / __init__ from object.
4646 internal Dictionary < CachedGetKey , FastGetBase > _cachedGets ; // cached gets on user defined type instances
@@ -79,7 +79,6 @@ public partial class PythonType : IPythonMembersList, IDynamicMetaObjectProvider
7979 private static int MasterVersion = 1 ;
8080 private static readonly CommonDictionaryStorage _pythonTypes = new CommonDictionaryStorage ( ) ;
8181 internal static readonly PythonType _pythonTypeType = DynamicHelpers . GetPythonTypeFromType ( typeof ( PythonType ) ) ;
82- private static readonly WeakReference [ ] _emptyWeakRef = new WeakReference [ 0 ] ;
8382 private static object _subtypesLock = new object ( ) ;
8483 internal static readonly Func < string , Exception , Exception > DefaultMakeException = ( message , innerException ) => new Exception ( message , innerException ) ;
8584 internal static readonly Func < string , Exception > DefaultMakeExceptionNoInnerException = ( message ) => new Exception ( message ) ;
@@ -658,17 +657,15 @@ public void __setattr__(CodeContext/*!*/ context, string name, object value) {
658657
659658 public PythonList __subclasses__ ( CodeContext /*!*/ context ) {
660659 PythonList ret = new PythonList ( ) ;
661- IList < WeakReference > subtypes = SubTypes ;
660+ var subtypes = SubTypes ;
662661
663662 if ( subtypes != null ) {
664663 PythonContext pc = context . LanguageContext ;
665664
666- foreach ( WeakReference wr in subtypes ) {
667- if ( wr . IsAlive ) {
668- PythonType pt = ( PythonType ) wr . Target ;
669-
665+ foreach ( var wr in subtypes ) {
666+ if ( wr . TryGetTarget ( out PythonType pt ) ) {
670667 if ( pt . PythonContext == null || pt . PythonContext == pc ) {
671- ret . AddNoLock ( wr . Target ) ;
668+ ret . AddNoLock ( pt ) ;
672669 }
673670 }
674671 }
@@ -1267,8 +1264,8 @@ internal void AddSlot(string name, PythonTypeSlot slot) {
12671264 private void ClearObjectNewInSubclasses ( PythonType pt ) {
12681265 lock ( _subtypesLock ) {
12691266 if ( pt . _subtypes != null ) {
1270- foreach ( WeakReference wr in pt . _subtypes ) {
1271- if ( wr . Target is PythonType type ) {
1267+ foreach ( var wr in pt . _subtypes ) {
1268+ if ( wr . TryGetTarget ( out PythonType type ) ) {
12721269 type . _objectNew = null ;
12731270
12741271 ClearObjectNewInSubclasses ( type ) ;
@@ -1281,8 +1278,8 @@ private void ClearObjectNewInSubclasses(PythonType pt) {
12811278 private void ClearObjectInitInSubclasses ( PythonType pt ) {
12821279 lock ( _subtypesLock ) {
12831280 if ( pt . _subtypes != null ) {
1284- foreach ( WeakReference wr in pt . _subtypes ) {
1285- if ( wr . Target is PythonType type ) {
1281+ foreach ( var wr in pt . _subtypes ) {
1282+ if ( wr . TryGetTarget ( out PythonType type ) ) {
12861283 type . _objectInit = null ;
12871284
12881285 ClearObjectInitInSubclasses ( type ) ;
@@ -2452,9 +2449,9 @@ private void EnsureInstanceCtor() {
24522449 #region Private implementation details
24532450
24542451 private void UpdateVersion ( ) {
2455- foreach ( WeakReference wr in SubTypes ) {
2456- if ( wr . IsAlive ) {
2457- ( ( PythonType ) wr . Target ) . UpdateVersion ( ) ;
2452+ foreach ( var wr in SubTypes ) {
2453+ if ( wr . TryGetTarget ( out PythonType pt ) ) {
2454+ pt . UpdateVersion ( ) ;
24582455 }
24592456 }
24602457
@@ -2484,31 +2481,32 @@ private void EnsureDict() {
24842481 null ) ;
24852482 }
24862483 }
2487-
2484+
24882485 /// <summary>
24892486 /// Internal helper function to add a subtype
24902487 /// </summary>
24912488 private void AddSubType ( PythonType subtype ) {
24922489 if ( _subtypes == null ) {
2493- Interlocked . CompareExchange < List < WeakReference > > ( ref _subtypes , new List < WeakReference > ( ) , null ) ;
2490+ Interlocked . CompareExchange ( ref _subtypes , new List < WeakReference < PythonType > > ( ) , null ) ;
24942491 }
24952492
24962493 lock ( _subtypesLock ) {
2497- _subtypes . Add ( new WeakReference ( subtype ) ) ;
2494+ _subtypes . Add ( new WeakReference < PythonType > ( subtype ) ) ;
24982495 }
24992496 }
25002497
25012498 private void RemoveSubType ( PythonType subtype ) {
2502- int i = 0 ;
2503- if ( _subtypes != null ) {
2504- lock ( _subtypesLock ) {
2505- while ( i < _subtypes . Count ) {
2506- if ( ! _subtypes [ i ] . IsAlive || _subtypes [ i ] . Target == subtype ) {
2507- _subtypes . RemoveAt ( i ) ;
2508- continue ;
2509- }
2510- i ++ ;
2499+ if ( _subtypes is null ) return ;
2500+
2501+ lock ( _subtypesLock ) {
2502+ int i = 0 ;
2503+ while ( i < _subtypes . Count ) {
2504+ var wr = _subtypes [ i ] ;
2505+ if ( ! wr . TryGetTarget ( out PythonType target ) || target == subtype ) {
2506+ _subtypes . RemoveAt ( i ) ;
2507+ continue ;
25112508 }
2509+ i ++ ;
25122510 }
25132511 }
25142512 }
@@ -2517,9 +2515,9 @@ private void RemoveSubType(PythonType subtype) {
25172515 /// Gets a list of weak references to all the subtypes of this class. May return null
25182516 /// if there are no subtypes of the class.
25192517 /// </summary>
2520- private IList < WeakReference > SubTypes {
2518+ private IList < WeakReference < PythonType > > SubTypes {
25212519 get {
2522- if ( _subtypes == null ) return _emptyWeakRef ;
2520+ if ( _subtypes == null ) return Array . Empty < WeakReference < PythonType > > ( ) ;
25232521
25242522 lock ( _subtypesLock ) {
25252523 return _subtypes . ToArray ( ) ;
0 commit comments