44// and using the cache clearing machinery to clear the caches when the
55// heirachy changes
66
7+ // FIXME should make Mro and Bases be []*Type
8+
79package py
810
911import (
@@ -187,7 +189,7 @@ var ObjectType = &Type{
187189}
188190
189191func init () {
190- // Initialises like this to avoid initialisation loops
192+ // Initialised like this to avoid initialisation loops
191193 TypeType .New = TypeNew
192194 TypeType .Init = TypeInit
193195 TypeType .ObjectType = TypeType
@@ -219,6 +221,35 @@ func (t *Type) GetDict() StringDict {
219221 return t .Dict
220222}
221223
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+
222253// Make a new type from a name
223254//
224255// For making Go types
@@ -229,7 +260,7 @@ func NewType(Name string, Doc string) *Type {
229260 Doc : Doc ,
230261 Dict : StringDict {},
231262 }
232- //t.Ready( )
263+ TypeDelayReady ( t )
233264 return t
234265}
235266
@@ -245,7 +276,7 @@ func NewTypeX(Name string, Doc string, New NewFunc, Init InitFunc) *Type {
245276 Init : Init ,
246277 Dict : StringDict {},
247278 }
248- //t.Ready( )
279+ TypeDelayReady ( t )
249280 return t
250281}
251282
@@ -269,8 +300,9 @@ func (t *Type) NewTypeFlags(Name string, Doc string, New NewFunc, Init InitFunc,
269300 Init : Init ,
270301 Flags : Flags ,
271302 Dict : StringDict {},
303+ Bases : Tuple {t },
272304 }
273- //tt.Ready( )
305+ TypeDelayReady ( t )
274306 return tt
275307}
276308
@@ -307,12 +339,14 @@ func (metatype *Type) CalculateMetaclass(bases Tuple) (*Type, error) {
307339}
308340
309341// type test with subclassing support
342+ // reads a IsSubtype of b
310343func (a * Type ) IsSubtype (b * Type ) bool {
311344 mro := a .Mro
312- if mro != nil {
345+ if len ( mro ) != 0 {
313346 // Deal with multiple inheritance without recursion
314347 // by walking the MRO tuple
315- for _ , base := range mro {
348+ for _ , baseObj := range mro {
349+ base := baseObj .(* Type )
316350 if base == b {
317351 return true
318352 }
@@ -939,7 +973,7 @@ func remove_subclass(base, t *Type) {
939973
940974// Ready the type for use
941975//
942- // Raises an exception on problems
976+ // Returns an error on problems
943977func (t * Type ) Ready () error {
944978 // PyObject *dict, *bases;
945979 // PyTypeObject *base;
@@ -1699,7 +1733,28 @@ func (ty *Type) M__ne__(other Object) (Object, error) {
16991733 return True , nil
17001734}
17011735
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+
17021755// Make sure it satisfies the interface
17031756var _ Object = (* Type )(nil )
17041757var _ I__call__ = (* Type )(nil )
17051758var _ IGetDict = (* Type )(nil )
1759+ var _ I__repr__ = (* Type )(nil )
1760+ var _ I__str__ = (* Type )(nil )
0 commit comments