1
1
using System ;
2
+ using System . Collections . Generic ;
2
3
using System . Diagnostics ;
4
+ using System . Linq ;
5
+ using System . Reflection ;
3
6
using System . Runtime . InteropServices ;
4
7
using System . Runtime . Serialization ;
5
8
@@ -84,36 +87,58 @@ public static NewReference tp_new(BorrowedReference tp, BorrowedReference args,
84
87
// That type must itself have a managed implementation. We check
85
88
// that by making sure its metatype is the CLR metatype.
86
89
87
- if ( Runtime . PyTuple_Size ( bases ) != 1 )
90
+
91
+ List < Type > interfaces = new List < Type > ( ) ;
92
+ List < ClassBase > baseType = new List < ClassBase > ( ) ;
93
+
94
+ var cnt = Runtime . PyTuple_GetSize ( bases ) ;
95
+
96
+ for ( uint i = 0 ; i < cnt ; i ++ )
97
+ {
98
+ var base_type2 = Runtime . PyTuple_GetItem ( bases , ( int ) i ) ;
99
+ var cb2 = ( ClassBase ) GetManagedObject ( base_type2 ) ;
100
+ if ( cb2 != null )
101
+ {
102
+ if ( cb2 . type . Valid && cb2 . type . Value . IsInterface )
103
+ interfaces . Add ( cb2 . type . Value ) ;
104
+ else baseType . Add ( cb2 ) ;
105
+ }
106
+ }
107
+
108
+ if ( baseType . Count == 0 )
109
+ {
110
+ baseType . Add ( new ClassBase ( typeof ( object ) ) ) ;
111
+ }
112
+
113
+
114
+ if ( baseType . Count > 1 )
88
115
{
89
116
return Exceptions . RaiseTypeError ( "cannot use multiple inheritance with managed classes" ) ;
90
117
}
91
118
92
- BorrowedReference base_type = Runtime . PyTuple_GetItem ( bases , 0 ) ;
93
- BorrowedReference mt = Runtime . PyObject_TYPE ( base_type ) ;
119
+ /*
120
+ BorrowedReference mt = Runtime.PyObject_TYPE(baseType );
94
121
95
122
if (!(mt == PyCLRMetaType || mt == Runtime.PyTypeType))
96
123
{
97
124
return Exceptions.RaiseTypeError("invalid metatype");
98
- }
125
+ }*/
99
126
100
127
// Ensure that the reflected type is appropriate for subclassing,
101
128
// disallowing subclassing of delegates, enums and array types.
102
129
103
- if ( GetManagedObject ( base_type ) is ClassBase cb )
130
+ var cb = baseType . First ( ) ;
131
+ try
104
132
{
105
- try
133
+ if ( ! cb . CanSubclass ( ) )
106
134
{
107
- if ( ! cb . CanSubclass ( ) )
108
- {
109
- return Exceptions . RaiseTypeError ( "delegates, enums and array types cannot be subclassed" ) ;
110
- }
111
- }
112
- catch ( SerializationException )
113
- {
114
- return Exceptions . RaiseTypeError ( $ "Underlying C# Base class { cb . type } has been deleted") ;
135
+ return Exceptions . RaiseTypeError ( "delegates, enums and array types cannot be subclassed" ) ;
115
136
}
116
137
}
138
+ catch ( SerializationException )
139
+ {
140
+ return Exceptions . RaiseTypeError ( $ "Underlying C# Base class { cb . type } has been deleted") ;
141
+ }
117
142
118
143
BorrowedReference slots = Runtime . PyDict_GetItem ( dict , PyIdentifier . __slots__ ) ;
119
144
if ( slots != null )
@@ -127,21 +152,25 @@ public static NewReference tp_new(BorrowedReference tp, BorrowedReference args,
127
152
// into python.
128
153
if ( null != dict )
129
154
{
155
+ var btt = baseType . FirstOrDefault ( ) . type . ValueOrNull ;
156
+ var ctor = btt ? . GetConstructors ( BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic )
157
+ . FirstOrDefault ( x => x . GetParameters ( ) . Any ( ) == false ) ;
130
158
using var clsDict = new PyDict ( dict ) ;
131
159
132
160
if ( clsDict . HasKey ( "__assembly__" ) || clsDict . HasKey ( "__namespace__" )
133
- || ( cb . type . Valid && cb . type . Value != null && cb . type . Value . GetConstructor ( Array . Empty < Type > ( ) ) != null ) )
161
+ || ( ctor != null ) )
134
162
{
135
163
if ( ! clsDict . HasKey ( "__namespace__" ) )
136
164
{
137
165
clsDict [ "__namespace__" ] =
138
166
( clsDict [ "__module__" ] . ToString ( ) ) . ToPython ( ) ;
139
167
}
140
- return TypeManager . CreateSubType ( name , base_type , clsDict ) ;
168
+ return TypeManager . CreateSubType ( name , baseType , interfaces , clsDict ) ;
141
169
}
142
170
143
171
}
144
172
173
+ var base_type = Runtime . PyTuple_GetItem ( bases , 0 ) ;
145
174
// otherwise just create a basic type without reflecting back into the managed side.
146
175
IntPtr func = Util . ReadIntPtr ( Runtime . PyTypeType , TypeOffset . tp_new ) ;
147
176
NewReference type = NativeCall . Call_3 ( func , tp , args , kw ) ;
0 commit comments