4
4
// and using the cache clearing machinery to clear the caches when the
5
5
// heirachy changes
6
6
7
+ // FIXME should make Mro and Bases be []*Type
8
+
7
9
package py
8
10
9
11
import (
@@ -187,7 +189,7 @@ var ObjectType = &Type{
187
189
}
188
190
189
191
func init () {
190
- // Initialises like this to avoid initialisation loops
192
+ // Initialised like this to avoid initialisation loops
191
193
TypeType .New = TypeNew
192
194
TypeType .Init = TypeInit
193
195
TypeType .ObjectType = TypeType
@@ -219,6 +221,35 @@ func (t *Type) GetDict() StringDict {
219
221
return t .Dict
220
222
}
221
223
224
+ // delayedReady holds types waiting to be intialised
225
+ var delayedReady = []* Type {}
226
+
227
+ // TypeDelayReady stores the list of types to initialise
228
+ //
229
+ // Call MakeReady when all initialised
230
+ func TypeDelayReady (t * Type ) {
231
+ delayedReady = append (delayedReady , t )
232
+ }
233
+
234
+ // TypeMakeReady readies all the types
235
+ func TypeMakeReady () (err error ) {
236
+ for _ , t := range delayedReady {
237
+ err = t .Ready ()
238
+ if err != nil {
239
+ return fmt .Errorf ("Error initialising go type %s: %v" , t .Name , err )
240
+ }
241
+ }
242
+ delayedReady = nil
243
+ return nil
244
+ }
245
+
246
+ func init () {
247
+ err := TypeMakeReady ()
248
+ if err != nil {
249
+ log .Fatal (err )
250
+ }
251
+ }
252
+
222
253
// Make a new type from a name
223
254
//
224
255
// For making Go types
@@ -229,7 +260,7 @@ func NewType(Name string, Doc string) *Type {
229
260
Doc : Doc ,
230
261
Dict : StringDict {},
231
262
}
232
- //t.Ready( )
263
+ TypeDelayReady ( t )
233
264
return t
234
265
}
235
266
@@ -245,7 +276,7 @@ func NewTypeX(Name string, Doc string, New NewFunc, Init InitFunc) *Type {
245
276
Init : Init ,
246
277
Dict : StringDict {},
247
278
}
248
- //t.Ready( )
279
+ TypeDelayReady ( t )
249
280
return t
250
281
}
251
282
@@ -269,8 +300,9 @@ func (t *Type) NewTypeFlags(Name string, Doc string, New NewFunc, Init InitFunc,
269
300
Init : Init ,
270
301
Flags : Flags ,
271
302
Dict : StringDict {},
303
+ Bases : Tuple {t },
272
304
}
273
- //tt.Ready( )
305
+ TypeDelayReady ( t )
274
306
return tt
275
307
}
276
308
@@ -307,12 +339,14 @@ func (metatype *Type) CalculateMetaclass(bases Tuple) (*Type, error) {
307
339
}
308
340
309
341
// type test with subclassing support
342
+ // reads a IsSubtype of b
310
343
func (a * Type ) IsSubtype (b * Type ) bool {
311
344
mro := a .Mro
312
- if mro != nil {
345
+ if len ( mro ) != 0 {
313
346
// Deal with multiple inheritance without recursion
314
347
// by walking the MRO tuple
315
- for _ , base := range mro {
348
+ for _ , baseObj := range mro {
349
+ base := baseObj .(* Type )
316
350
if base == b {
317
351
return true
318
352
}
@@ -939,7 +973,7 @@ func remove_subclass(base, t *Type) {
939
973
940
974
// Ready the type for use
941
975
//
942
- // Raises an exception on problems
976
+ // Returns an error on problems
943
977
func (t * Type ) Ready () error {
944
978
// PyObject *dict, *bases;
945
979
// PyTypeObject *base;
@@ -1699,7 +1733,28 @@ func (ty *Type) M__ne__(other Object) (Object, error) {
1699
1733
return True , nil
1700
1734
}
1701
1735
1736
+ func (ty * Type ) M__str__ () (Object , error ) {
1737
+ if res , ok , err := ty .CallMethod ("__str__" , Tuple {ty }, nil ); ok {
1738
+ return res , err
1739
+ }
1740
+ return ty .M__repr__ ()
1741
+ }
1742
+
1743
+ func (ty * Type ) M__repr__ () (Object , error ) {
1744
+ if res , ok , err := ty .CallMethod ("__repr__" , Tuple {ty }, nil ); ok {
1745
+ return res , err
1746
+ }
1747
+ if ty .Name == "" {
1748
+ // FIXME not a good way to tell objects from classes!
1749
+ return String (fmt .Sprintf ("<%s object at %p>" , ty .Type ().Name , ty )), nil
1750
+ }
1751
+ return String (fmt .Sprintf ("<class '%s'>" , ty .Name )), nil
1752
+
1753
+ }
1754
+
1702
1755
// Make sure it satisfies the interface
1703
1756
var _ Object = (* Type )(nil )
1704
1757
var _ I__call__ = (* Type )(nil )
1705
1758
var _ IGetDict = (* Type )(nil )
1759
+ var _ I__repr__ = (* Type )(nil )
1760
+ var _ I__str__ = (* Type )(nil )
0 commit comments