Commit b5edf37f authored by Kevin Modzelewski's avatar Kevin Modzelewski

Guarding fix around calling __getattr__'s

It would memorize whether or not to call __getattr__, and didn't do enough
guarding to make sure that that was the case.
parent de60220f
......@@ -977,6 +977,27 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs*
rewrite_args->out_rtn = grewrite_args.out_rtn;
rewrite_args->out_return_convention = grewrite_args.out_return_convention;
}
// Guarding here is a bit tricky, since we need to make sure that we call getattr
// (or not) at the right times.
// Right now this section is a bit conservative.
if (rewrite_args) {
if (grewrite_args.out_return_convention == GetattrRewriteArgs::NO_RETURN) {
// Do nothing
} else if (grewrite_args.out_return_convention == GetattrRewriteArgs::VALID_RETURN) {
// TODO we should have a HAS_RETURN that takes out the NULL case
assert(res);
if (res)
grewrite_args.out_rtn->addGuardNotEq(0);
else
grewrite_args.out_rtn->addGuard(0);
} else if (grewrite_args.out_return_convention == GetattrRewriteArgs::NOEXC_POSSIBLE) {
// TODO maybe we could handle this
rewrite_args = NULL;
} else {
RELEASE_ASSERT(0, "%d", grewrite_args.out_return_convention);
}
}
} else {
try {
res = getattrInternalGeneric(self, name, NULL, false, false, NULL, NULL);
......
# Test some weird hasattr guarding scenarios
# I think this applies equally well to getattr
def f(o):
print hasattr(o, "a")
print getattr(o, "a", None)
class C(object):
def __getattr__(self, key):
print "getattr", key
raise AttributeError(key)
for i in xrange(300):
print i
c = C()
try:
f(c)
except AttributeError as e:
print e
c.a = 1
setattr(c, str(i), i)
f(c)
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