@@ -65,10 +65,11 @@ const (
65
65
)
66
66
67
67
type Type struct {
68
- Name string // For printing, in format "<module>.<name>"
69
- Doc string // Documentation string
70
- Methods StringDict // *PyMethodDef
71
- Members StringDict // *PyMemberDef
68
+ ObjectType * Type // Type of this object
69
+ Name string // For printing, in format "<module>.<name>"
70
+ Doc string // Documentation string
71
+ Methods StringDict // *PyMethodDef
72
+ Members StringDict // *PyMemberDef
72
73
// Getset *PyGetSetDef
73
74
Base * Type
74
75
Dict StringDict
@@ -163,24 +164,32 @@ type Type struct {
163
164
*/
164
165
}
165
166
166
- var TypeType = NewType ( "type" , "type(object) -> the object's type\n type(name, bases, dict) -> a new type" )
167
+ var TypeType * Type = & Type { Name : "type" , Doc : "type(object) -> the object's type\n type(name, bases, dict) -> a new type" }
167
168
var BaseObjectType = NewType ("object" , "The most base type" )
168
169
169
170
func init () {
171
+ TypeType .ObjectType = TypeType
170
172
// FIXME put this into NewType
171
173
TypeType .New = TypeNew
174
+ TypeType .Init = TypeInit
175
+ BaseObjectType .Flags |= TPFLAGS_BASETYPE
176
+ BaseObjectType .New = ObjectNew
177
+ BaseObjectType .Init = ObjectInit
172
178
}
173
179
174
180
// Type of this object
175
- func (o * Type ) Type () * Type {
176
- return TypeType
181
+ func (t * Type ) Type () * Type {
182
+ return t . ObjectType
177
183
}
178
184
179
185
// Make a new type from a name
186
+ //
187
+ // For making Go types
180
188
func NewType (Name string , Doc string ) * Type {
181
189
return & Type {
182
- Name : Name ,
183
- Doc : Doc ,
190
+ ObjectType : TypeType ,
191
+ Name : Name ,
192
+ Doc : Doc ,
184
193
}
185
194
}
186
195
@@ -235,18 +244,16 @@ func (a *Type) IsSubtype(b *Type) bool {
235
244
}
236
245
}
237
246
238
- // Call a type
247
+ // Call type()
239
248
func (t * Type ) M__call__ (args Tuple , kwargs StringDict ) Object {
240
- var obj Object
241
-
242
249
if t .New == nil {
243
250
// FIXME TypeError
244
251
panic (fmt .Sprintf ("TypeError: cannot create '%s' instances" , t .Name ))
245
252
}
246
253
247
- obj = t .New (t , args , kwargs )
254
+ obj : = t .New (t , args , kwargs )
248
255
// Ugly exception: when the call was type(something),
249
- // don't call Init on the result.
256
+ // don't call tp_init on the result.
250
257
if t == TypeType && len (args ) == 1 && len (kwargs ) == 0 {
251
258
return obj
252
259
}
@@ -255,9 +262,9 @@ func (t *Type) M__call__(args Tuple, kwargs StringDict) Object {
255
262
if ! obj .Type ().IsSubtype (t ) {
256
263
return obj
257
264
}
258
- t = obj .Type ()
259
- if t .Init != nil {
260
- t .Init (obj , args , kwargs )
265
+ objType : = obj .Type ()
266
+ if objType .Init != nil {
267
+ objType .Init (obj , args , kwargs )
261
268
}
262
269
return obj
263
270
}
@@ -569,8 +576,16 @@ func (t *Type) mro_internal() {
569
576
result = t .mro_implementation ()
570
577
} else {
571
578
checkit = true
572
- mro := lookup_method (t , "mro" )
573
- result = Call (mro , nil , nil )
579
+ // FIXME this is what it was originally
580
+ // but we haven't put mro in slots or anything
581
+ // mro := lookup_method(t, "mro")
582
+ mro := lookup_maybe (t , "mro" )
583
+ if mro == nil {
584
+ // Default to internal implementation
585
+ result = t .mro_implementation ()
586
+ } else {
587
+ result = Call (mro , nil , nil )
588
+ }
574
589
}
575
590
tuple := SequenceTuple (result )
576
591
if checkit {
@@ -924,33 +939,13 @@ func best_base(bases Tuple) *Type {
924
939
}
925
940
926
941
// Generic object allocator
927
- func (t * Type ) Alloc (nitems int ) Object {
928
- // PyObject *obj;
929
- // const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
930
- // /* note that we need to add one, for the sentinel */
931
-
932
- // if (PyType_IS_GC(type))
933
- // obj = _PyObject_GC_Malloc(size);
934
- // else
935
- // obj = (PyObject *)PyObject_MALLOC(size);
936
-
937
- // if (obj == nil)
938
- // return PyErr_NoMemory();
942
+ func (t * Type ) Alloc () * Type {
943
+ obj := new (Type )
939
944
940
- // memset(obj, '\0', size);
945
+ // Set the type of the new object to this type
946
+ obj .ObjectType = t
941
947
942
- // if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
943
- // Py_INCREF(type);
944
-
945
- // if (type->tp_itemsize == 0)
946
- // PyObject_INIT(obj, type);
947
- // else
948
- // (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
949
-
950
- // if (PyType_IS_GC(type))
951
- // _PyObject_GC_TRACK(obj);
952
- // return obj;
953
- return None
948
+ return obj
954
949
}
955
950
956
951
// Create a new type
@@ -973,8 +968,7 @@ func TypeNew(metatype *Type, args Tuple, kwargs StringDict) *Type {
973
968
// a msg saying type() needs exactly 3.
974
969
if len (args )+ len (kwargs ) != 3 {
975
970
// FIXME TypeError
976
- panic (fmt .Sprintf ("PyExc_TypeError: type() takes 1 or 3 arguments" ))
977
- return nil
971
+ panic (fmt .Sprintf ("TypeError: type() takes 1 or 3 arguments" ))
978
972
}
979
973
980
974
// Check arguments: (name, bases, dict)
@@ -1144,7 +1138,10 @@ func TypeNew(metatype *Type, args Tuple, kwargs StringDict) *Type {
1144
1138
}
1145
1139
1146
1140
// Allocate the type object
1147
- new_type = metatype .Alloc (nslots ).(* Type )
1141
+ _ = nslots // FIXME
1142
+ new_type = metatype .Alloc ()
1143
+ new_type .New = ObjectNew // FIXME metatype.New // FIXME?
1144
+ new_type .Init = ObjectInit // FIXME metatype.New // FIXME?
1148
1145
1149
1146
// Keep name and slots alive in the extended type object
1150
1147
et := new_type
@@ -1165,7 +1162,7 @@ func TypeNew(metatype *Type, args Tuple, kwargs StringDict) *Type {
1165
1162
1166
1163
// Set __module__ in the dict
1167
1164
if _ , ok := dict ["__module__" ]; ! ok {
1168
- fmt .Printf ("FIXME neet to get the current vm globals somehow" )
1165
+ fmt .Printf ("FIXME neet to get the current vm globals somehow\n " )
1169
1166
// tmp = PyEval_GetGlobals()
1170
1167
// if tmp != nil {
1171
1168
// tmp, ok := tmp["__name__"]
@@ -1294,6 +1291,137 @@ func TypeNew(metatype *Type, args Tuple, kwargs StringDict) *Type {
1294
1291
return new_type
1295
1292
}
1296
1293
1294
+ func TypeInit (cls Object , args Tuple , kwargs StringDict ) {
1295
+ if len (kwargs ) != 0 {
1296
+ // FIXME TypeError
1297
+ panic (fmt .Sprintf ("TypeError: type.__init__() takes no keyword arguments" ))
1298
+ }
1299
+
1300
+ if len (args ) != 1 && len (args ) != 3 {
1301
+ // FIXME TypeError
1302
+ panic (fmt .Sprintf ("TypeError: type.__init__() takes 1 or 3 arguments" ))
1303
+ }
1304
+
1305
+ // Call object.__init__(self) now.
1306
+ // XXX Could call super(type, cls).__init__() but what's the point?
1307
+ ObjectInit (cls , nil , nil )
1308
+ }
1309
+
1310
+ // The base type of all types (eventually)... except itself.
1311
+
1312
+ // You may wonder why object.__new__() only complains about arguments
1313
+ // when object.__init__() is not overridden, and vice versa.
1314
+ //
1315
+ // Consider the use cases:
1316
+ //
1317
+ // 1. When neither is overridden, we want to hear complaints about
1318
+ // excess (i.e., any) arguments, since their presence could
1319
+ // indicate there's a bug.
1320
+ //
1321
+ // 2. When defining an Immutable type, we are likely to override only
1322
+ // __new__(), since __init__() is called too late to initialize an
1323
+ // Immutable object. Since __new__() defines the signature for the
1324
+ // type, it would be a pain to have to override __init__() just to
1325
+ // stop it from complaining about excess arguments.
1326
+ //
1327
+ // 3. When defining a Mutable type, we are likely to override only
1328
+ // __init__(). So here the converse reasoning applies: we don't
1329
+ // want to have to override __new__() just to stop it from
1330
+ // complaining.
1331
+ //
1332
+ // 4. When __init__() is overridden, and the subclass __init__() calls
1333
+ // object.__init__(), the latter should complain about excess
1334
+ // arguments; ditto for __new__().
1335
+ //
1336
+ // Use cases 2 and 3 make it unattractive to unconditionally check for
1337
+ // excess arguments. The best solution that addresses all four use
1338
+ // cases is as follows: __init__() complains about excess arguments
1339
+ // unless __new__() is overridden and __init__() is not overridden
1340
+ // (IOW, if __init__() is overridden or __new__() is not overridden);
1341
+ // symmetrically, __new__() complains about excess arguments unless
1342
+ // __init__() is overridden and __new__() is not overridden
1343
+ // (IOW, if __new__() is overridden or __init__() is not overridden).
1344
+ //
1345
+ // However, for backwards compatibility, this breaks too much code.
1346
+ // Therefore, in 2.6, we'll *warn* about excess arguments when both
1347
+ // methods are overridden; for all other cases we'll use the above
1348
+ // rules.
1349
+
1350
+ // Return true if any arguments supplied
1351
+ func excess_args (args Tuple , kwargs StringDict ) bool {
1352
+ return len (args ) != 0 || len (kwargs ) != 0
1353
+ }
1354
+
1355
+ func ObjectInit (self Object , args Tuple , kwargs StringDict ) {
1356
+ t := self .Type ()
1357
+ // FIXME bodge to compare function pointers
1358
+ if excess_args (args , kwargs ) && (fmt .Sprintf ("%x" , t .New ) == fmt .Sprintf ("%x" , ObjectNew ) || fmt .Sprintf ("%x" , t .Init ) != fmt .Sprintf ("%x" , ObjectInit )) {
1359
+ // FIXME type error
1360
+ panic (fmt .Sprintf ("TypeError: object.__init__() takes no parameters" ))
1361
+ }
1362
+ }
1363
+
1364
+ func ObjectNew (t * Type , args Tuple , kwargs StringDict ) * Type {
1365
+ // FIXME bodge to compare function pointers
1366
+ if excess_args (args , kwargs ) && (fmt .Sprintf ("%x" , t .Init ) == fmt .Sprintf ("%x" , ObjectInit ) || fmt .Sprintf ("%x" , t .New ) != fmt .Sprintf ("%x" , ObjectNew )) {
1367
+ // FIXME type error
1368
+ panic (fmt .Sprintf ("TypeError: object() takes no parameters" ))
1369
+ }
1370
+
1371
+ // FIXME abstrac types
1372
+ // if (type->tp_flags & Py_TPFLAGS_IS_ABSTRACT) {
1373
+ // PyObject *abstract_methods = NULL;
1374
+ // PyObject *builtins;
1375
+ // PyObject *sorted;
1376
+ // PyObject *sorted_methods = NULL;
1377
+ // PyObject *joined = NULL;
1378
+ // PyObject *comma;
1379
+ // _Py_static_string(comma_id, ", ");
1380
+ // _Py_IDENTIFIER(sorted);
1381
+
1382
+ // // Compute ", ".join(sorted(type.__abstractmethods__))
1383
+ // // into joined.
1384
+ // abstract_methods = type_abstractmethods(type, NULL);
1385
+ // if (abstract_methods == NULL) {
1386
+ // goto error;
1387
+ // }
1388
+ // builtins = PyEval_GetBuiltins();
1389
+ // if (builtins == NULL) {
1390
+ // goto error;
1391
+ // }
1392
+ // sorted = _PyDict_GetItemId(builtins, &PyId_sorted);
1393
+ // if (sorted == NULL) {
1394
+ // goto error;
1395
+ // }
1396
+ // sorted_methods = PyObject_CallFunctionObjArgs(sorted,
1397
+ // abstract_methods,
1398
+ // NULL);
1399
+ // if (sorted_methods == NULL) {
1400
+ // goto error;
1401
+ // }
1402
+ // comma = _PyUnicode_FromId(&comma_id);
1403
+ // if (comma == NULL) {
1404
+ // goto error;
1405
+ // }
1406
+ // joined = PyUnicode_Join(comma, sorted_methods);
1407
+ // if (joined == NULL) {
1408
+ // goto error;
1409
+ // }
1410
+
1411
+ // PyErr_Format(PyExc_TypeError,
1412
+ // "Can't instantiate abstract class %s "
1413
+ // "with abstract methods %U",
1414
+ // type->tp_name,
1415
+ // joined);
1416
+ // error:
1417
+ // Py_XDECREF(joined);
1418
+ // Py_XDECREF(sorted_methods);
1419
+ // Py_XDECREF(abstract_methods);
1420
+ // return NULL;
1421
+ // }
1422
+ return t .Alloc ()
1423
+ }
1424
+
1297
1425
// Make sure it satisfies the interface
1298
1426
var _ Object = (* Type )(nil )
1299
1427
var _ I__call__ = (* Type )(nil )
0 commit comments