github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/runtime/type.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package grumpy
    16  
    17  import (
    18  	"fmt"
    19  	"reflect"
    20  )
    21  
    22  type typeFlag int
    23  
    24  const (
    25  	// Set when instances can be created via __new__. This is the default.
    26  	// We need to be able to prohibit instantiation of certain internal
    27  	// types like NoneType. CPython accomplishes this via tp_new == NULL but
    28  	// we don't have a tp_new.
    29  	typeFlagInstantiable typeFlag = 1 << iota
    30  	// Set when the type can be used as a base class. This is the default.
    31  	// Corresponds to the Py_TPFLAGS_BASETYPE flag in CPython.
    32  	typeFlagBasetype typeFlag = 1 << iota
    33  	typeFlagDefault           = typeFlagInstantiable | typeFlagBasetype
    34  )
    35  
    36  // Type represents Python 'type' objects.
    37  type Type struct {
    38  	Object
    39  	name  string `attr:"__name__"`
    40  	basis reflect.Type
    41  	bases []*Type
    42  	mro   []*Type
    43  	flags typeFlag
    44  	slots typeSlots
    45  }
    46  
    47  var basisTypes = map[reflect.Type]*Type{
    48  	objectBasis: ObjectType,
    49  	typeBasis:   TypeType,
    50  }
    51  
    52  // newClass creates a Python type with the given name, base classes and type
    53  // dict. It is similar to the Python expression 'type(name, bases, dict)'.
    54  func newClass(f *Frame, meta *Type, name string, bases []*Type, dict *Dict) (*Type, *BaseException) {
    55  	numBases := len(bases)
    56  	if numBases == 0 {
    57  		return nil, f.RaiseType(TypeErrorType, "class must have base classes")
    58  	}
    59  	var basis reflect.Type
    60  	for _, base := range bases {
    61  		if base.flags&typeFlagBasetype == 0 {
    62  			format := "type '%s' is not an acceptable base type"
    63  			return nil, f.RaiseType(TypeErrorType, fmt.Sprintf(format, base.Name()))
    64  		}
    65  		basis = basisSelect(basis, base.basis)
    66  	}
    67  	if basis == nil {
    68  		return nil, f.RaiseType(TypeErrorType, "class layout error")
    69  	}
    70  	t := newType(meta, name, basis, bases, dict)
    71  	// Populate slots for any special methods overridden in dict.
    72  	slotsValue := reflect.ValueOf(&t.slots).Elem()
    73  	for i := 0; i < numSlots; i++ {
    74  		dictFunc, raised := dict.GetItemString(f, slotNames[i])
    75  		if raised != nil {
    76  			return nil, raised
    77  		}
    78  		if dictFunc != nil {
    79  			slotField := slotsValue.Field(i)
    80  			slotValue := reflect.New(slotField.Type().Elem())
    81  			if slotValue.Interface().(slot).wrapCallable(dictFunc) {
    82  				slotField.Set(slotValue)
    83  			}
    84  		}
    85  	}
    86  	if err := prepareType(t); err != "" {
    87  		return nil, f.RaiseType(TypeErrorType, err)
    88  	}
    89  	// Set the __module__ attr if it's not already specified.
    90  	mod, raised := dict.GetItemString(f, "__module__")
    91  	if raised != nil {
    92  		return nil, raised
    93  	}
    94  	if mod == nil {
    95  		if raised := dict.SetItemString(f, "__module__", builtinStr.ToObject()); raised != nil {
    96  			return nil, raised
    97  		}
    98  	}
    99  	return t, nil
   100  }
   101  
   102  func newType(meta *Type, name string, basis reflect.Type, bases []*Type, dict *Dict) *Type {
   103  	return &Type{
   104  		Object: Object{typ: meta, dict: dict},
   105  		name:   name,
   106  		basis:  basis,
   107  		bases:  bases,
   108  		flags:  typeFlagDefault,
   109  	}
   110  }
   111  
   112  func newBasisType(name string, basis reflect.Type, basisFunc interface{}, base *Type) *Type {
   113  	if _, ok := basisTypes[basis]; ok {
   114  		logFatal(fmt.Sprintf("type for basis already exists: %s", basis))
   115  	}
   116  	if basis.Kind() != reflect.Struct {
   117  		logFatal(fmt.Sprintf("basis must be a struct not: %s", basis.Kind()))
   118  	}
   119  	if basis.NumField() == 0 {
   120  		logFatal(fmt.Sprintf("1st field of basis must be base type's basis"))
   121  	}
   122  	if basis.Field(0).Type != base.basis {
   123  		logFatal(fmt.Sprintf("1st field of basis must be base type's basis not: %s", basis.Field(0).Type))
   124  	}
   125  	basisFuncValue := reflect.ValueOf(basisFunc)
   126  	basisFuncType := basisFuncValue.Type()
   127  	if basisFuncValue.Kind() != reflect.Func || basisFuncType.NumIn() != 1 || basisFuncType.NumOut() != 1 ||
   128  		basisFuncType.In(0) != reflect.PtrTo(objectBasis) || basisFuncType.Out(0) != reflect.PtrTo(basis) {
   129  		logFatal(fmt.Sprintf("expected basis func of type func(*Object) *%s", nativeTypeName(basis)))
   130  	}
   131  	t := newType(TypeType, name, basis, []*Type{base}, nil)
   132  	t.slots.Basis = &basisSlot{func(o *Object) reflect.Value {
   133  		return basisFuncValue.Call([]reflect.Value{reflect.ValueOf(o)})[0].Elem()
   134  	}}
   135  	basisTypes[basis] = t
   136  	return t
   137  }
   138  
   139  func newSimpleType(name string, base *Type) *Type {
   140  	return newType(TypeType, name, base.basis, []*Type{base}, nil)
   141  }
   142  
   143  // prepareBuiltinType initializes the builtin typ by populating dict with
   144  // struct field descriptors and slot wrappers, and then calling prepareType.
   145  func prepareBuiltinType(typ *Type, init builtinTypeInit) {
   146  	dict := map[string]*Object{"__module__": builtinStr.ToObject()}
   147  	if init != nil {
   148  		init(dict)
   149  	}
   150  	// For basis types, export field descriptors.
   151  	if basis := typ.basis; basisTypes[basis] == typ {
   152  		numFields := basis.NumField()
   153  		for i := 0; i < numFields; i++ {
   154  			field := basis.Field(i)
   155  			if attr := field.Tag.Get("attr"); attr != "" {
   156  				fieldMode := fieldDescriptorRO
   157  				if mode := field.Tag.Get("attr_mode"); mode == "rw" {
   158  					fieldMode = fieldDescriptorRW
   159  				}
   160  				dict[attr] = makeStructFieldDescriptor(typ, field.Name, attr, fieldMode)
   161  			}
   162  		}
   163  	}
   164  	// Create dict entries for slot methods.
   165  	slotsValue := reflect.ValueOf(&typ.slots).Elem()
   166  	for i := 0; i < numSlots; i++ {
   167  		slotField := slotsValue.Field(i)
   168  		if !slotField.IsNil() {
   169  			slot := slotField.Interface().(slot)
   170  			if fun := slot.makeCallable(typ, slotNames[i]); fun != nil {
   171  				dict[slotNames[i]] = fun
   172  			}
   173  		}
   174  	}
   175  	typ.setDict(newStringDict(dict))
   176  	if err := prepareType(typ); err != "" {
   177  		logFatal(err)
   178  	}
   179  }
   180  
   181  // prepareType calculates typ's mro and inherits its flags and slots from its
   182  // base classes.
   183  func prepareType(typ *Type) string {
   184  	typ.mro = mroCalc(typ)
   185  	if typ.mro == nil {
   186  		return fmt.Sprintf("mro error for: %s", typ.name)
   187  	}
   188  	for _, base := range typ.mro {
   189  		if base.flags&typeFlagInstantiable == 0 {
   190  			typ.flags &^= typeFlagInstantiable
   191  		}
   192  		if base.flags&typeFlagBasetype == 0 {
   193  			typ.flags &^= typeFlagBasetype
   194  		}
   195  	}
   196  	// Inherit slots from typ's mro.
   197  	slotsValue := reflect.ValueOf(&typ.slots).Elem()
   198  	for i := 0; i < numSlots; i++ {
   199  		slotField := slotsValue.Field(i)
   200  		if slotField.IsNil() {
   201  			for _, base := range typ.mro {
   202  				baseSlotFunc := reflect.ValueOf(base.slots).Field(i)
   203  				if !baseSlotFunc.IsNil() {
   204  					slotField.Set(baseSlotFunc)
   205  					break
   206  				}
   207  			}
   208  		}
   209  	}
   210  	return ""
   211  }
   212  
   213  // Precondition: At least one of seqs is non-empty.
   214  func mroMerge(seqs [][]*Type) []*Type {
   215  	var res []*Type
   216  	numSeqs := len(seqs)
   217  	hasNonEmptySeqs := true
   218  	for hasNonEmptySeqs {
   219  		var cand *Type
   220  		for i := 0; i < numSeqs && cand == nil; i++ {
   221  			// The next candidate will be absent from or at the head
   222  			// of all lists. If we try a candidate and we find it's
   223  			// somewhere past the head of one of the lists, reject.
   224  			seq := seqs[i]
   225  			if len(seq) == 0 {
   226  				continue
   227  			}
   228  			cand = seq[0]
   229  		RejectCandidate:
   230  			for _, seq := range seqs {
   231  				numElems := len(seq)
   232  				for j := 1; j < numElems; j++ {
   233  					if seq[j] == cand {
   234  						cand = nil
   235  						break RejectCandidate
   236  					}
   237  				}
   238  			}
   239  		}
   240  		if cand == nil {
   241  			// We could not find a candidate meaning that the
   242  			// hierarchy is inconsistent.
   243  			return nil
   244  		}
   245  		res = append(res, cand)
   246  		hasNonEmptySeqs = false
   247  		for i, seq := range seqs {
   248  			if len(seq) > 0 {
   249  				if seq[0] == cand {
   250  					// Remove the candidate from all lists
   251  					// (it will only be found at the head of
   252  					// any list because otherwise it would
   253  					// have been rejected above.)
   254  					seqs[i] = seq[1:]
   255  				}
   256  				if len(seqs[i]) > 0 {
   257  					hasNonEmptySeqs = true
   258  				}
   259  			}
   260  		}
   261  	}
   262  	return res
   263  }
   264  
   265  func mroCalc(t *Type) []*Type {
   266  	seqs := [][]*Type{{t}}
   267  	for _, b := range t.bases {
   268  		seqs = append(seqs, b.mro)
   269  	}
   270  	seqs = append(seqs, t.bases)
   271  	return mroMerge(seqs)
   272  }
   273  
   274  func toTypeUnsafe(o *Object) *Type {
   275  	return (*Type)(o.toPointer())
   276  }
   277  
   278  // ToObject upcasts t to an Object.
   279  func (t *Type) ToObject() *Object {
   280  	return &t.Object
   281  }
   282  
   283  // Name returns t's name field.
   284  func (t *Type) Name() string {
   285  	return t.name
   286  }
   287  
   288  // FullName returns t's fully qualified name including the module.
   289  func (t *Type) FullName(f *Frame) (string, *BaseException) {
   290  	moduleAttr, raised := t.Dict().GetItemString(f, "__module__")
   291  	if raised != nil {
   292  		return "", raised
   293  	}
   294  	if moduleAttr == nil {
   295  		return t.Name(), nil
   296  	}
   297  	if moduleAttr.isInstance(StrType) {
   298  		if s := toStrUnsafe(moduleAttr).Value(); s != "__builtin__" {
   299  			return fmt.Sprintf("%s.%s", s, t.Name()), nil
   300  		}
   301  	}
   302  	return t.Name(), nil
   303  }
   304  
   305  func (t *Type) isSubclass(super *Type) bool {
   306  	for _, b := range t.mro {
   307  		if b == super {
   308  			return true
   309  		}
   310  	}
   311  	return false
   312  }
   313  
   314  func (t *Type) mroLookup(f *Frame, name *Str) (*Object, *BaseException) {
   315  	for _, t := range t.mro {
   316  		v, raised := t.Dict().GetItem(f, name.ToObject())
   317  		if v != nil || raised != nil {
   318  			return v, raised
   319  		}
   320  	}
   321  	return nil, nil
   322  }
   323  
   324  var typeBasis = reflect.TypeOf(Type{})
   325  
   326  func typeBasisFunc(o *Object) reflect.Value {
   327  	return reflect.ValueOf(toTypeUnsafe(o)).Elem()
   328  }
   329  
   330  // TypeType is the object representing the Python 'type' type.
   331  //
   332  // Don't use newType() since that depends on the initialization of
   333  // TypeType.
   334  var TypeType = &Type{
   335  	name:  "type",
   336  	basis: typeBasis,
   337  	bases: []*Type{ObjectType},
   338  	flags: typeFlagDefault,
   339  	slots: typeSlots{Basis: &basisSlot{typeBasisFunc}},
   340  }
   341  
   342  func typeCall(f *Frame, callable *Object, args Args, kwargs KWArgs) (*Object, *BaseException) {
   343  	t := toTypeUnsafe(callable)
   344  	newFunc := t.slots.New
   345  	if newFunc == nil {
   346  		return nil, f.RaiseType(TypeErrorType, fmt.Sprintf("type %s has no __new__", t.Name()))
   347  	}
   348  	o, raised := newFunc.Fn(f, t, args, kwargs)
   349  	if raised != nil {
   350  		return nil, raised
   351  	}
   352  	if init := o.Type().slots.Init; init != nil {
   353  		if _, raised := init.Fn(f, o, args, kwargs); raised != nil {
   354  			return nil, raised
   355  		}
   356  	}
   357  	return o, nil
   358  }
   359  
   360  // typeGetAttribute is very similar to objectGetAttribute except that it uses
   361  // MRO to resolve dict attributes rather than just the type's own dict and the
   362  // exception message is slightly different.
   363  func typeGetAttribute(f *Frame, o *Object, name *Str) (*Object, *BaseException) {
   364  	t := toTypeUnsafe(o)
   365  	// Look for a data descriptor in the metaclass.
   366  	var metaGet *getSlot
   367  	metaType := t.typ
   368  	metaAttr, raised := metaType.mroLookup(f, name)
   369  	if raised != nil {
   370  		return nil, raised
   371  	}
   372  	if metaAttr != nil {
   373  		metaGet = metaAttr.typ.slots.Get
   374  		if metaGet != nil && (metaAttr.typ.slots.Set != nil || metaAttr.typ.slots.Delete != nil) {
   375  			return metaGet.Fn(f, metaAttr, t.ToObject(), metaType)
   376  		}
   377  	}
   378  	// Look in dict of this type and its bases.
   379  	attr, raised := t.mroLookup(f, name)
   380  	if raised != nil {
   381  		return nil, raised
   382  	}
   383  	if attr != nil {
   384  		if get := attr.typ.slots.Get; get != nil {
   385  			return get.Fn(f, attr, None, t)
   386  		}
   387  		return attr, nil
   388  	}
   389  	// Use the (non-data) descriptor from the metaclass.
   390  	if metaGet != nil {
   391  		return metaGet.Fn(f, metaAttr, t.ToObject(), metaType)
   392  	}
   393  	// Return the ordinary attr from metaclass.
   394  	if metaAttr != nil {
   395  		return metaAttr, nil
   396  	}
   397  	msg := fmt.Sprintf("type object '%s' has no attribute '%s'", t.Name(), name.Value())
   398  	return nil, f.RaiseType(AttributeErrorType, msg)
   399  }
   400  
   401  func typeNew(f *Frame, t *Type, args Args, kwargs KWArgs) (*Object, *BaseException) {
   402  	switch len(args) {
   403  	case 0:
   404  		return nil, f.RaiseType(TypeErrorType, "type() takes 1 or 3 arguments")
   405  	case 1:
   406  		return args[0].typ.ToObject(), nil
   407  	}
   408  	// case 3+
   409  	if raised := checkMethodArgs(f, "__new__", args, StrType, TupleType, DictType); raised != nil {
   410  		return nil, raised
   411  	}
   412  	name := toStrUnsafe(args[0]).Value()
   413  	bases := toTupleUnsafe(args[1]).elems
   414  	dict := toDictUnsafe(args[2])
   415  	baseTypes := make([]*Type, len(bases))
   416  	meta := t
   417  	for i, o := range bases {
   418  		if !o.isInstance(TypeType) {
   419  			s, raised := Repr(f, o)
   420  			if raised != nil {
   421  				return nil, raised
   422  			}
   423  			return nil, f.RaiseType(TypeErrorType, fmt.Sprintf("not a valid base class: %s", s.Value()))
   424  		}
   425  		// Choose the most derived metaclass among all the bases to be
   426  		// the metaclass for the new type.
   427  		if o.typ.isSubclass(meta) {
   428  			meta = o.typ
   429  		} else if !meta.isSubclass(o.typ) {
   430  			msg := "metaclass conflict: the metaclass of a derived class must " +
   431  				"a be a (non-strict) subclass of the metaclasses of all its bases"
   432  			return nil, f.RaiseType(TypeErrorType, msg)
   433  		}
   434  		baseTypes[i] = toTypeUnsafe(o)
   435  	}
   436  	ret, raised := newClass(f, meta, name, baseTypes, dict)
   437  	if raised != nil {
   438  		return nil, raised
   439  	}
   440  	return ret.ToObject(), nil
   441  }
   442  
   443  func typeRepr(f *Frame, o *Object) (*Object, *BaseException) {
   444  	s, raised := toTypeUnsafe(o).FullName(f)
   445  	if raised != nil {
   446  		return nil, raised
   447  	}
   448  	return NewStr(fmt.Sprintf("<type '%s'>", s)).ToObject(), nil
   449  }
   450  
   451  func initTypeType(map[string]*Object) {
   452  	TypeType.typ = TypeType
   453  	TypeType.slots.Call = &callSlot{typeCall}
   454  	TypeType.slots.GetAttribute = &getAttributeSlot{typeGetAttribute}
   455  	TypeType.slots.New = &newSlot{typeNew}
   456  	TypeType.slots.Repr = &unaryOpSlot{typeRepr}
   457  }
   458  
   459  // basisParent returns the immediate ancestor of basis, which is its first
   460  // field. Returns nil when basis is objectBasis (the root of basis hierarchy.)
   461  func basisParent(basis reflect.Type) reflect.Type {
   462  	if basis == objectBasis {
   463  		return nil
   464  	}
   465  	return basis.Field(0).Type
   466  }
   467  
   468  // basisSelect returns b1 if b2 inherits from it, b2 if b1 inherits from b2,
   469  // otherwise nil. b1 can be nil in which case b2 is always returned.
   470  func basisSelect(b1, b2 reflect.Type) reflect.Type {
   471  	if b1 == nil {
   472  		return b2
   473  	}
   474  	// Search up b1's inheritance chain to see if b2 is present.
   475  	basis := b1
   476  	for basis != nil && basis != b2 {
   477  		basis = basisParent(basis)
   478  	}
   479  	if basis != nil {
   480  		return b1
   481  	}
   482  	// Search up b2's inheritance chain to see if b1 is present.
   483  	basis = b2
   484  	for basis != nil && basis != b1 {
   485  		basis = basisParent(basis)
   486  	}
   487  	if basis != nil {
   488  		return b2
   489  	}
   490  	return nil
   491  }