Commit 5767d26e authored by Kevin Modzelewski's avatar Kevin Modzelewski

add delattrGeneric

like we had to do for getattrGeneric and setattrGeneric

I guess all the other slots will eventually follow as well.
parent 47ccea66
......@@ -145,7 +145,10 @@ extern "C" PyObject* PyObject_SelfIter(PyObject* obj) noexcept {
extern "C" int PyObject_GenericSetAttr(PyObject* obj, PyObject* name, PyObject* value) noexcept {
try {
setattrGeneric(obj, static_cast<BoxedString*>(name)->s.c_str(), value, NULL);
if (value == NULL)
delattrGeneric(obj, static_cast<BoxedString*>(name)->s, NULL);
else
setattrGeneric(obj, static_cast<BoxedString*>(name)->s.c_str(), value, NULL);
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
......
......@@ -1682,6 +1682,7 @@ bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewrit
}
void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args) {
assert(val);
assert(gc::isValidGCObject(val));
// TODO this should be in type_setattro
......@@ -3652,18 +3653,7 @@ void Box::delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args) {
abort();
}
extern "C" void delattrInternal(Box* obj, const std::string& attr, bool allow_custom,
DelattrRewriteArgs* rewrite_args) {
// custom __delattr__
if (allow_custom) {
Box* delAttr = typeLookup(obj->cls, delattr_str, NULL);
if (delAttr != NULL) {
Box* boxstr = boxString(attr);
Box* rtn = runtimeCall2(delAttr, ArgPassSpec(2), obj, boxstr);
return;
}
}
extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewriteArgs* rewrite_args) {
// first check whether the deleting attribute is a descriptor
Box* clsAttr = typeLookup(obj->cls, attr, NULL);
if (clsAttr != NULL) {
......@@ -3715,6 +3705,17 @@ extern "C" void delattrInternal(Box* obj, const std::string& attr, bool allow_cu
}
}
extern "C" void delattrInternal(Box* obj, const std::string& attr, DelattrRewriteArgs* rewrite_args) {
Box* delAttr = typeLookup(obj->cls, delattr_str, NULL);
if (delAttr != NULL) {
Box* boxstr = boxString(attr);
Box* rtn = runtimeCall2(delAttr, ArgPassSpec(2), obj, boxstr);
return;
}
delattrGeneric(obj, attr, rewrite_args);
}
// del target.attr
extern "C" void delattr(Box* obj, const char* attr) {
static StatCounter slowpath_delattr("slowpath_delattr");
......@@ -3728,7 +3729,7 @@ extern "C" void delattr(Box* obj, const char* attr) {
}
delattrInternal(obj, attr, true, NULL);
delattrInternal(obj, attr, NULL);
}
extern "C" Box* createBoxedIterWrapper(Box* o) {
......
......@@ -51,6 +51,7 @@ extern "C" void my_assert(bool b);
extern "C" Box* getattr(Box* obj, const char* attr);
extern "C" void setattr(Box* obj, const char* attr, Box* attr_val);
extern "C" void delattr(Box* obj, const char* attr);
extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewriteArgs* rewrite_args);
extern "C" bool nonzero(Box* obj);
extern "C" Box* runtimeCall(Box*, ArgPassSpec, Box*, Box*, Box*, Box**, const std::vector<const std::string*>*);
extern "C" Box* callattr(Box*, const std::string*, CallattrFlags, ArgPassSpec, Box*, Box*, Box*, Box**,
......
class C(object):
def __delattr__(self, attr):
print "delattr", attr
if attr.startswith("c"):
print "yum"
else:
object.__delattr__(self, attr)
def __setattr__(self, attr, value):
print attr, value
if attr.startswith("c"):
......@@ -18,3 +25,8 @@ c.b = 2
c.c = 3
print sorted(c.__dict__.items())
print c.a, c.b, c.c
del c.a
del c.b
del c.c
print sorted(c.__dict__.items())
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment