@@ -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 ) ;
@@ -680,17 +679,15 @@ public void __setattr__(CodeContext/*!*/ context, string name, object value) {
680679
681680 public PythonList __subclasses__ ( CodeContext /*!*/ context ) {
682681 PythonList ret = new PythonList ( ) ;
683- IList < WeakReference > subtypes = SubTypes ;
682+ var subtypes = SubTypes ;
684683
685684 if ( subtypes != null ) {
686685 PythonContext pc = context . LanguageContext ;
687686
688- foreach ( WeakReference wr in subtypes ) {
689- if ( wr . IsAlive ) {
690- PythonType pt = ( PythonType ) wr . Target ;
691-
687+ foreach ( var wr in subtypes ) {
688+ if ( wr . TryGetTarget ( out PythonType pt ) ) {
692689 if ( pt . PythonContext == null || pt . PythonContext == pc ) {
693- ret . AddNoLock ( wr . Target ) ;
690+ ret . AddNoLock ( pt ) ;
694691 }
695692 }
696693 }
@@ -1270,8 +1267,8 @@ internal void AddSlot(string name, PythonTypeSlot slot) {
12701267 private void ClearObjectNewInSubclasses ( PythonType pt ) {
12711268 lock ( _subtypesLock ) {
12721269 if ( pt . _subtypes != null ) {
1273- foreach ( WeakReference wr in pt . _subtypes ) {
1274- if ( wr . Target is PythonType type ) {
1270+ foreach ( var wr in pt . _subtypes ) {
1271+ if ( wr . TryGetTarget ( out PythonType type ) ) {
12751272 type . _objectNew = null ;
12761273
12771274 ClearObjectNewInSubclasses ( type ) ;
@@ -1284,8 +1281,8 @@ private void ClearObjectNewInSubclasses(PythonType pt) {
12841281 private void ClearObjectInitInSubclasses ( PythonType pt ) {
12851282 lock ( _subtypesLock ) {
12861283 if ( pt . _subtypes != null ) {
1287- foreach ( WeakReference wr in pt . _subtypes ) {
1288- if ( wr . Target is PythonType type ) {
1284+ foreach ( var wr in pt . _subtypes ) {
1285+ if ( wr . TryGetTarget ( out PythonType type ) ) {
12891286 type . _objectInit = null ;
12901287
12911288 ClearObjectInitInSubclasses ( type ) ;
@@ -2465,9 +2462,9 @@ private void EnsureInstanceCtor() {
24652462 #region Private implementation details
24662463
24672464 private void UpdateVersion ( ) {
2468- foreach ( WeakReference wr in SubTypes ) {
2469- if ( wr . IsAlive ) {
2470- ( ( PythonType ) wr . Target ) . UpdateVersion ( ) ;
2465+ foreach ( var wr in SubTypes ) {
2466+ if ( wr . TryGetTarget ( out PythonType pt ) ) {
2467+ pt . UpdateVersion ( ) ;
24712468 }
24722469 }
24732470
@@ -2497,31 +2494,32 @@ private void EnsureDict() {
24972494 null ) ;
24982495 }
24992496 }
2500-
2497+
25012498 /// <summary>
25022499 /// Internal helper function to add a subtype
25032500 /// </summary>
25042501 private void AddSubType ( PythonType subtype ) {
25052502 if ( _subtypes == null ) {
2506- Interlocked . CompareExchange < List < WeakReference > > ( ref _subtypes , new List < WeakReference > ( ) , null ) ;
2503+ Interlocked . CompareExchange ( ref _subtypes , new List < WeakReference < PythonType > > ( ) , null ) ;
25072504 }
25082505
25092506 lock ( _subtypesLock ) {
2510- _subtypes . Add ( new WeakReference ( subtype ) ) ;
2507+ _subtypes . Add ( new WeakReference < PythonType > ( subtype ) ) ;
25112508 }
25122509 }
25132510
25142511 private void RemoveSubType ( PythonType subtype ) {
2515- int i = 0 ;
2516- if ( _subtypes != null ) {
2517- lock ( _subtypesLock ) {
2518- while ( i < _subtypes . Count ) {
2519- if ( ! _subtypes [ i ] . IsAlive || _subtypes [ i ] . Target == subtype ) {
2520- _subtypes . RemoveAt ( i ) ;
2521- continue ;
2522- }
2523- i ++ ;
2512+ if ( _subtypes is null ) return ;
2513+
2514+ lock ( _subtypesLock ) {
2515+ int i = 0 ;
2516+ while ( i < _subtypes . Count ) {
2517+ var wr = _subtypes [ i ] ;
2518+ if ( ! wr . TryGetTarget ( out PythonType target ) || target == subtype ) {
2519+ _subtypes . RemoveAt ( i ) ;
2520+ continue ;
25242521 }
2522+ i ++ ;
25252523 }
25262524 }
25272525 }
@@ -2530,9 +2528,9 @@ private void RemoveSubType(PythonType subtype) {
25302528 /// Gets a list of weak references to all the subtypes of this class. May return null
25312529 /// if there are no subtypes of the class.
25322530 /// </summary>
2533- private IList < WeakReference > SubTypes {
2531+ private IList < WeakReference < PythonType > > SubTypes {
25342532 get {
2535- if ( _subtypes == null ) return _emptyWeakRef ;
2533+ if ( _subtypes == null ) return Array . Empty < WeakReference < PythonType > > ( ) ;
25362534
25372535 lock ( _subtypesLock ) {
25382536 return _subtypes . ToArray ( ) ;
0 commit comments