8000 Make a subclass of a type and implement Fast subclass flags · go-python/gpython@317101a · GitHub
[go: up one dir, main page]

Skip to content

Commit 317101a

Browse files
committed
Make a subclass of a type and implement Fast subclass flags
1 parent e90b958 commit 317101a

File tree

2 files changed

+58
-32
lines changed

2 files changed

+58
-32
lines changed

py/dict.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package py
77

88
var StringDictType = NewType("dict", "dict() -> new empty dictionary\ndict(mapping) -> new dictionary initialized from a mapping object's\n (key, value) pairs\ndict(iterable) -> new dictionary initialized as if via:\n d = {}\n for k, v in iterable:\n d[k] = v\ndict(**kwargs) -> new dictionary initialized with the name=value pairs\n in the keyword argument list. For example: dict(one=1, two=2)")
99

10+
var DictType = NewType("dict", "dict() -> new empty dictionary\ndict(mapping) -> new dictionary initialized from a mapping object's\n (key, value) pairs\ndict(iterable) -> new dictionary initialized as if via:\n d = {}\n for k, v in iterable:\n d[k] = v\ndict(**kwargs) -> new dictionary initialized with the name=value pairs\n in the keyword argument list. For example: dict(one=1, two=2)")
11+
1012
// String to object dictionary
1113
//
1214
// Used for variables etc where the keys can only be strings

py/type.go

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,15 @@ var TypeType *Type = &Type{
172172
Name: "type",
173173
Doc: "type(object) -> the object's type\ntype(name, bases, dict) -> a new type",
174174
}
175-
var BaseObjectType = NewTypeX("object", "The most base type", ObjectNew, ObjectInit)
175+
var ObjectType = TypeType.NewType("object", "The most base type", ObjectNew, ObjectInit)
176176

177177
func init() {
178178
// Initialises like this to avoid initialisation loops
179179
TypeType.New = TypeNew
180180
TypeType.Init = TypeInit
181181
TypeType.ObjectType = TypeType
182182
// FIXME put this into NewType
183-
BaseObjectType.Flags |= TPFLAGS_BASETYPE
183+
ObjectType.Flags |= TPFLAGS_BASETYPE
184184
}
185185

186186
// Type of this object
@@ -212,6 +212,26 @@ func NewTypeX(Name string, Doc string, New NewFunc, Init InitFunc) *Type {
212212
}
213213
}
214214

215+
// Make a subclass of a type
216+
//
217+
// For making Go types
218+
func (t *Type) NewType(Name string, Doc string, New NewFunc, Init InitFunc) *Type {
219+
// inherit constructors
220+
if New == nil {
221+
New = t.New
222+
}
223+
if Init == nil {
224+
Init = t.Init
225+
}
226+
return &Type{
227+
ObjectType: t,
228+
Name: Name,
229+
Doc: Doc,
230+
New: New,
231+
Init: Init,
232+
}
233+
}
234+
215235
// Determine the most derived metatype.
216236
func (metatype *Type) CalculateMetaclass(bases Tuple) *Type {
217237
// Determine the proper metatype to deal with this,
@@ -259,7 +279,7 @@ func (a *Type) IsSubtype(b *Type) bool {
259279
break
260280
}
261281
}
262-
return b == BaseObjectType
282+
return b == ObjectType
263283
}
264284
}
265285

@@ -298,7 +318,7 @@ func (t *Type) Lookup(name string) Object {
298318

299319
// FIXME caching
300320
// if (MCACHE_CACHEABLE_NAME(name) &&
301-
// PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) {
321+
// PyType_HasFeature(type, TPFLAGS_VALID_VERSION_TAG)) {
302322
// // fast path
303323
// h = MCACHE_HASH_METHOD(type, name);
304324
// if (method_cache[h].version == type->tp_version_tag &&
@@ -706,10 +726,10 @@ func (t *Type) mro_internal() {
706726

707727
func (t *Type) inherit_special(base *Type) {
708728
// /* Copying basicsize is connected to the GC flags */
709-
// if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
710-
// (base->tp_flags & Py_TPFLAGS_HAVE_GC) &&
729+
// if (!(type->tp_flags & TPFLAGS_HAVE_GC) &&
730+
// (base->tp_flags & TPFLAGS_HAVE_GC) &&
711731
// (!type->tp_traverse && !type->tp_clear)) {
712-
// type->tp_flags |= Py_TPFLAGS_HAVE_GC;
732+
// type->tp_flags |= TPFLAGS_HAVE_GC;
713733
// if (type->tp_traverse == nil)
714734
// type->tp_traverse = base->tp_traverse;
715735
// if (type->tp_clear == nil)
@@ -727,7 +747,7 @@ func (t *Type) inherit_special(base *Type) {
727747
// other built-in type as the default also
728748
// inherit object.__new__. */
729749
// if (base != &PyBaseObject_Type ||
730-
// (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
750+
// (type->tp_flags & TPFLAGS_HEAPTYPE)) {
731751
// if (type->tp_new == nil)
732752
// type->tp_new = base->tp_new;
733753
// }
@@ -745,23 +765,27 @@ func (t *Type) inherit_special(base *Type) {
745765
// COPYVAL(tp_weaklistoffset);
746766
// COPYVAL(tp_dictoffset);
747767

748-
// /* Setup fast subclass flags */
749-
// if (PyType_IsSubtype(base, (PyTypeObject*)PyExc_BaseException))
750-
// type->tp_flags |= Py_TPFLAGS_BASE_EXC_SUBCLASS;
751-
// else if (PyType_IsSubtype(base, &PyType_Type))
752-
// type->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS;
753-
// else if (PyType_IsSubtype(base, &PyLong_Type))
754-
// type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS;
755-
// else if (PyType_IsSubtype(base, &PyBytes_Type))
756-
// type->tp_flags |= Py_TPFLAGS_BYTES_SUBCLASS;
757-
// else if (PyType_IsSubtype(base, &PyUnicode_Type))
758-
// type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS;
759-
// else if (PyType_IsSubtype(base, &PyTuple_Type))
760-
// type->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS;
761-
// else if (PyType_IsSubtype(base, &PyList_Type))
762-
// type->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS;
763-
// else if (PyType_IsSubtype(base, &PyDict_Type))
764-
// type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
768+
// Setup fast subclass flags
769+
switch {
770+
case base.IsSubtype(BaseException):
771+
t.Flags |= TPFLAGS_BASE_EXC_SUBCLASS
772+
case base.IsSubtype(TypeType):
773+
t.Flags |= TPFLAGS_TYPE_SUBCLASS
774+
case base.IsSubtype(IntType):
775+
t.Flags |= TPFLAGS_LONG_SUBCLASS
776+
case base.IsSubtype(BigIntType):
777+
t.Flags |= TPFLAGS_LONG_SUBCLASS
778+
case base.IsSubtype(BytesType):
779+
t.Flags |= TPFLAGS_BYTES_SUBCLASS
780+
case base.IsSubtype(StringType):
781+
t.Flags |= TPFLAGS_UNICODE_SUBCLASS
782+
case base.IsSubtype(TupleType):
783+
t.Flags |= TPFLAGS_TUPLE_SUBCLASS
784+
case base.IsSubtype(ListType):
785+
t.Flags |= TPFLAGS_LIST_SUBCLASS
786+
case base.IsSubtype(DictType):
787+
t.Flags |= TPFLAGS_DICT_SUBCLASS
788+
}
765789

766790
}
767791

@@ -833,13 +857,13 @@ func (t *Type) Ready() {
833857

834858
// Initialize tp_base (defaults to BaseObject unless that's us)
835859
base := t.Base
836-
if base == nil && t != BaseObjectType {
837-
base = BaseObjectType
860+
if base == nil && t != ObjectType {
861+
base = ObjectType
838862
t.Base = base
839863
}
840864

841865
// Now the only way base can still be nil is if type is
842-
// BaseObjectType.
866+
// ObjectType.
843867

844868
// Initialize the base class
845869
if base != nil && base.Dict == nil {
@@ -850,7 +874,7 @@ func (t *Type) Ready() {
850874
// compilable separately on Windows can call PyType_Ready() instead of
851875
// initializing the ob_type field of their type objects.
852876
// The test for base != nil is really unnecessary, since base is only
853-
// nil when type is BaseObjectType, and we know its ob_type is
877+
// nil when type is ObjectType, and we know its ob_type is
854878
// not nil (it's initialized to &PyType_Type). But coverity doesn't
855879
// know that.
856880

@@ -976,7 +1000,7 @@ func (t *Type) solid_base() *Type {
9761000
if t.Base != nil {
9771001
base = t.Base.solid_base()
9781002
} else {
979-
base = BaseObjectType
1003+
base = ObjectType
9801004
}
9811005
if t.extra_ivars(base) {
9821006
return t
@@ -1082,7 +1106,7 @@ func TypeNew(metatype *Type, args Tuple, kwargs StringDict) Object {
10821106

10831107
// Adjust for empty tuple bases
10841108
if len(bases) == 0 {
1085-
bases = Tuple{Object(BaseObjectType)}
1109+
bases = Tuple{Object(ObjectType)}
10861110
}
10871111

10881112
// Calculate best base, and check that all bases are type objects
@@ -1469,7 +1493,7 @@ func ObjectNew(t *Type, args Tuple, kwargs StringDict) Object {
14691493
}
14701494

14711495
// FIXME abstrac types
1472-
// if (type->tp_flags & Py_TPFLAGS_IS_ABSTRACT) {
1496+
// if (type->tp_flags & TPFLAGS_IS_ABSTRACT) {
14731497
// PyObject *abstract_methods = NULL;
14741498
// PyObject *builtins;
14751499
// PyObject *sorted;

0 commit comments

Comments
 (0)
0