@@ -39,7 +39,7 @@ public partial class PythonType : IPythonMembersList, IDynamicMetaObjectProvider
3939 private PythonTypeAttributes _attrs ; // attributes of the type
4040 private int _flags ; // CPython-like flags on the type
4141 private int _version = GetNextVersion ( ) ; // version of the type
42- private List < WeakReference > _subtypes ; // all of the subtypes of the PythonType
42+ private List < WeakReference < PythonType > > _subtypes ; // all of the subtypes of the PythonType
4343 private PythonContext _pythonContext ; // the context the type was created from, or null for system types.
4444 private bool ? _objectNew , _objectInit ; // true if the type doesn't override __new__ / __init__ from object.
4545 internal Dictionary < CachedGetKey , FastGetBase > _cachedGets ; // cached gets on user defined type instances
@@ -76,7 +76,6 @@ public partial class PythonType : IPythonMembersList, IDynamicMetaObjectProvider
7676 [ MultiRuntimeAware ]
7777 private static int MasterVersion = 1 ;
7878 private static readonly CommonDictionaryStorage _pythonTypes = new CommonDictionaryStorage ( ) ;
79- private static readonly WeakReference [ ] _emptyWeakRef = Array . Empty < WeakReference > ( ) ;
8079 private static readonly object _subtypesLock = new object ( ) ;
8180 internal static readonly Func < string , Exception , Exception > DefaultMakeException = ( message , innerException ) => new Exception ( message , innerException ) ;
8281 internal static readonly Func < string , Exception > DefaultMakeExceptionNoInnerException = ( message ) => new Exception ( message ) ;
@@ -681,17 +680,15 @@ public void __setattr__(CodeContext/*!*/ context, string name, object value) {
681680
682681 public PythonList __subclasses__ ( CodeContext /*!*/ context ) {
683682 PythonList ret = new PythonList ( ) ;
684- IList < WeakReference > subtypes = SubTypes ;
683+ var subtypes = SubTypes ;
685684
686685 if ( subtypes != null ) {
687686 PythonContext pc = context . LanguageContext ;
688687
689- foreach ( WeakReference wr in subtypes ) {
690- if ( wr . IsAlive ) {
691- PythonType pt = ( PythonType ) wr . Target ;
692-
688+ foreach ( var wr in subtypes ) {
689+ if ( wr . TryGetTarget ( out PythonType pt ) ) {
693690 if ( pt . PythonContext == null || pt . PythonContext == pc ) {
694- ret . AddNoLock ( wr . Target ) ;
691+ ret . AddNoLock ( pt ) ;
695692 }
696693 }
697694 }
@@ -1271,8 +1268,8 @@ internal void AddSlot(string name, PythonTypeSlot slot) {
12711268 private void ClearObjectNewInSubclasses ( PythonType pt ) {
12721269 lock ( _subtypesLock ) {
12731270 if ( pt . _subtypes != null ) {
1274- foreach ( WeakReference wr in pt . _subtypes ) {
1275- if ( wr . Target is PythonType type ) {
1271+ foreach ( var wr in pt . _subtypes ) {
1272+ if ( wr . TryGetTarget ( out PythonType type ) ) {
12761273 type . _objectNew = null ;
12771274
12781275 ClearObjectNewInSubclasses ( type ) ;
@@ -1285,8 +1282,8 @@ private void ClearObjectNewInSubclasses(PythonType pt) {
12851282 private void ClearObjectInitInSubclasses ( PythonType pt ) {
12861283 lock ( _subtypesLock ) {
12871284 if ( pt . _subtypes != null ) {
1288- foreach ( WeakReference wr in pt . _subtypes ) {
1289- if ( wr . Target is PythonType type ) {
1285+ foreach ( var wr in pt . _subtypes ) {
1286+ if ( wr . TryGetTarget ( out PythonType type ) ) {
12901287 type . _objectInit = null ;
12911288
12921289 ClearObjectInitInSubclasses ( type ) ;
@@ -2459,9 +2456,9 @@ private void EnsureInstanceCtor() {
24592456 #region Private implementation details
24602457
24612458 private void UpdateVersion ( ) {
2462- foreach ( WeakReference wr in SubTypes ) {
2463- if ( wr . IsAlive ) {
2464- ( ( PythonType ) wr . Target ) . UpdateVersion ( ) ;
2459+ foreach ( var wr in SubTypes ) {
2460+ if ( wr . TryGetTarget ( out PythonType pt ) ) {
2461+ pt . UpdateVersion ( ) ;
24652462 }
24662463 }
24672464
@@ -2497,25 +2494,26 @@ private void EnsureDict() {
24972494 /// </summary>
24982495 private void AddSubType ( PythonType subtype ) {
24992496 if ( _subtypes == null ) {
2500- Interlocked . CompareExchange < List < WeakReference > > ( ref _subtypes , new List < WeakReference > ( ) , null ) ;
2497+ Interlocked . CompareExchange ( ref _subtypes , new List < WeakReference < PythonType > > ( ) , null ) ;
25012498 }
25022499
25032500 lock ( _subtypesLock ) {
2504- _subtypes . Add ( new WeakReference ( subtype ) ) ;
2501+ _subtypes . Add ( new WeakReference < PythonType > ( subtype ) ) ;
25052502 }
25062503 }
25072504
25082505 private void RemoveSubType ( PythonType subtype ) {
2509- int i = 0 ;
2510- if ( _subtypes != null ) {
2511- lock ( _subtypesLock ) {
2512- while ( i < _subtypes . Count ) {
2513- if ( ! _subtypes [ i ] . IsAlive || _subtypes [ i ] . Target == subtype ) {
2514- _subtypes . RemoveAt ( i ) ;
2515- continue ;
2516- }
2517- i ++ ;
2506+ if ( _subtypes is null ) return ;
2507+
2508+ lock ( _subtypesLock ) {
2509+ int i = 0 ;
2510+ while ( i < _subtypes . Count ) {
2511+ var wr = _subtypes [ i ] ;
2512+ if ( ! wr . TryGetTarget ( out PythonType target ) || target == subtype ) {
2513+ _subtypes . RemoveAt ( i ) ;
2514+ continue ;
25182515 }
2516+ i ++ ;
25192517 }
25202518 }
25212519 }
@@ -2524,9 +2522,9 @@ private void RemoveSubType(PythonType subtype) {
25242522 /// Gets a list of weak references to all the subtypes of this class. May return null
25252523 /// if there are no subtypes of the class.
25262524 /// </summary>
2527- private IList < WeakReference > SubTypes {
2525+ private IList < WeakReference < PythonType > > SubTypes {
25282526 get {
2529- if ( _subtypes == null ) return _emptyWeakRef ;
2527+ if ( _subtypes == null ) return Array . Empty < WeakReference < PythonType > > ( ) ;
25302528
25312529 lock ( _subtypesLock ) {
25322530 return _subtypes . ToArray ( ) ;
0 commit comments