8000 Implement STORE_ATTR / py.SetAttr · go-python/gpython@35eacd5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 35eacd5

Browse files
committed
Implement STORE_ATTR / py.SetAttr
1 parent 01e2121 commit 35eacd5

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

py/internal.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func SetItem(self Object, key Object, value Object) Object {
103103
func GetAttrOrNil(self Object, key string) (res Object) {
104104
// Call __getattribute unconditionally if it exists
105105
if I, ok := self.(I__getattribute__); ok {
106-
res = I.M__getattribute__(Object(String(key)))
106+
res = I.M__getattribute__(key)
107107
goto found
108108
} else if res, ok = TypeCall1(self, "__getattribute__", Object(String(key))); ok {
109109
// FIXME catch AttributeError here
@@ -122,7 +122,7 @@ func GetAttrOrNil(self Object, key string) (res Object) {
122122

123123
// And now only if not found call __getattr__
124124
if I, ok := self.(I__getattr__); ok {
125-
res = I.M__getattr__(Object(String(key)))
125+
res = I.M__getattr__(key)
126126
goto found
127127
} else if res, ok = TypeCall1(self, "__getattr__", Object(String(key))); ok {
128128
goto found
@@ -172,3 +172,33 @@ func GetAttr(self Object, keyObj Object) Object {
172172
// FIXME should be TypeError
173173
panic(fmt.Sprintf("TypeError: attribute name must be string, not '%s'", self.Type().Name))
174174
}
175+
176+
// SetAttrString
177+
func SetAttrString(self Object, key string, value Object) Object {
178+
if I, ok := self.(I__setattr__); ok {
179+
return I.M__setattr__(key, value)
180+
} else if res, ok := TypeCall2(self, "__setattr__", String(key), value); ok {
181+
return res
182+
}
183+
184+
// Set the attribute on *Type
185+
if t, ok := self.(*Type); ok {
186+
if t.Dict == nil {
187+
t.Dict = make(StringDict)
188+
}
189+
t.Dict[key] = value
190+
return None
191+
}
192+
193+
// FIXME should be TypeError
194+
panic(fmt.Sprintf("TypeError: '%s' object does not support setting attributes", self.Type().Name))
195+
}
196+
197+
// SetAttr
198+
func SetAttr(self Object, keyObj Object, value Object) Object {
199+
if key, ok := keyObj.(String); ok {
200+
return GetAttrString(self, string(key))
201+
}
202+
// FIXME should be TypeError
203+
panic(fmt.Sprintf("TypeError: attribute name must be string, not '%s'", self.Type().Name))
204+
}
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ type I__bool__ interface {
320320
// control over attribute access.
321321
//object.__getattr__(self, name)
322322
type I__getattr__ interface {
323-
M__getattr__(name Object) Object
323+
M__getattr__(name string) Object
324324
}
325325

326326
// Called unconditionally to implement attribute accesses for
@@ -338,7 +338,7 @@ type I__getattr__ interface {
338338
//built-in functions. See Special method lookup.
339339
//object.__getattribute__(self, name)
340340
type I__getattribute__ interface {
341-
M__getattribute__(name Object) Object
341+
M__getattribute__(name string) Object
342342
}
343343

344344
// Called when an attribute assignment is attempted. This is called
@@ -351,15 +351,15 @@ type I__getattribute__ interface {
351351
// object.__setattr__(self, name, value).
352352
//object.__setattr__(self, name, value)
353353
type I__setattr__ interface {
354-
M__setattr__(name, value Object) Object
354+
M__setattr__(name string, value Object) Object
355355
}
356356

357357
// Like __setattr__() but for attribute deletion instead of
358358
// assignment. This should only be implemented if del obj.name is
359359
// meaningful for the object.
360360
//object.__delattr__(self, name)
361361
type I__delattr__ interface {
362-
M__delattr__(name Object) Object
362+
M__delattr__(name string) Object
363363
}
364364

365365
// Called when dir() is called on the object. A sequence must be

vm/eval.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,11 @@ func do_UNPACK_SEQUENCE(vm *Vm, count int32) {
492492
// Implements TOS.name = TOS1, where namei is the index of name in
493493
// co_names.
494494
func do_STORE_ATTR(vm *Vm, namei int32) {
495-
vm.NotImplemented("STORE_ATTR", namei)
495+
w := vm.frame.Code.Names[namei]
496+
v := vm.TOP()
497+
u := vm.SECOND()
498+
vm.DROPN(2)
499+
py.SetAttrString(v, w, u) /* v.w = u */
496500
}
497501

498502
// Implements del TOS.name, using namei as index into co_names.
@@ -1010,6 +1014,11 @@ func Run(globals, locals py.StringDict, code *py.Code) (res py.Object, err error
10101014
vm.extended = false
10111015
jumpTable[opcode](vm, arg)
10121016
fmt.Printf("* Stack = %#v\n", vm.stack)
1017+
// if len(vm.stack) > 0 {
1018+
// if t, ok := vm.TOP().(*py.Type); ok {
1019+
// fmt.Printf(" * TOP = %#v\n", t)
1020+
// }
1021+
// }
10131022
}
10141023
if len(vm.stack) != 1 {
10151024
fmt.Printf("vmstack = %#v\n", vm.stack)

0 commit comments

Comments
 (0)
0