Commit e80012b0 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Support __getattr__ overloading for old style classes

parent 67a8482a
......@@ -155,7 +155,11 @@ static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing)
static const std::string getattr_str("__getattr__");
Box* getattr = classLookup(inst->inst_cls, getattr_str);
RELEASE_ASSERT(getattr == NULL, "unimplemented");
if (getattr) {
getattr = processDescriptor(getattr, inst, inst->inst_cls);
return runtimeCall(getattr, ArgPassSpec(1), _attr, NULL, NULL, NULL, NULL);
}
if (!raise_on_missing)
return NULL;
......
......@@ -2136,6 +2136,17 @@ static CompiledFunction* pickVersion(CLFunction* f, int num_output_args, Box* oa
return chosen_cf;
}
static std::string getFunctionName(CLFunction* f) {
if (f->source)
return f->source->getName();
else if (f->versions.size()) {
std::ostringstream oss;
oss << "<function at " << f->versions[0]->code << ">";
return oss.str();
}
return "<unknown function>";
}
static void placeKeyword(const std::vector<AST_expr*>& arg_names, std::vector<bool>& params_filled,
const std::string& kw_name, Box* kw_val, Box*& oarg1, Box*& oarg2, Box*& oarg3, Box** oargs,
BoxedDict* okwargs) {
......@@ -2316,17 +2327,9 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
Box* ovarargs = new BoxedTuple(unused_positional);
getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs;
} else if (unused_positional.size()) {
std::string name = "<unknown function>";
if (f->source)
name = f->source->getName();
else if (f->versions.size()) {
std::ostringstream oss;
oss << "<function at " << f->versions[0]->code << ">";
name = oss.str();
}
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", name.c_str(), f->num_args,
(f->num_args == 1 ? "" : "s"), argspec.num_args + argspec.num_keywords + varargs.size());
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", getFunctionName(f).c_str(),
f->num_args, (f->num_args == 1 ? "" : "s"),
argspec.num_args + argspec.num_keywords + varargs.size());
}
////
......@@ -2341,7 +2344,7 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
const std::vector<AST_expr*>* arg_names = f->source ? f->source->arg_names.args : NULL;
if (arg_names == nullptr && argspec.num_keywords && !f->takes_kwargs) {
raiseExcHelper(TypeError, "<function @%p>() doesn't take keyword arguments", f->versions[0]->code);
raiseExcHelper(TypeError, "%s() doesn't take keyword arguments", getFunctionName(f).c_str());
}
if (argspec.num_keywords)
......@@ -2374,7 +2377,7 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
for (auto& p : d_kwargs->d) {
if (p.first->cls != str_cls)
raiseExcHelper(TypeError, "<function>() keywords must be strings");
raiseExcHelper(TypeError, "%s() keywords must be strings", getFunctionName(f).c_str());
BoxedString* s = static_cast<BoxedString*>(p.first);
......@@ -2385,8 +2388,8 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
Box*& v = okwargs->d[p.first];
if (v) {
raiseExcHelper(TypeError, "<function>() got multiple values for keyword argument '%s'",
s->s.c_str());
raiseExcHelper(TypeError, "%s() got multiple values for keyword argument '%s'",
getFunctionName(f).c_str(), s->s.c_str());
}
v = p.second;
}
......@@ -2399,7 +2402,7 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
if (params_filled[i])
continue;
// TODO not right error message
raiseExcHelper(TypeError, "<function>() did not get a value for positional argument %d", i);
raiseExcHelper(TypeError, "%s() did not get a value for positional argument %d", getFunctionName(f).c_str(), i);
}
RewriterVar* r_defaults_array = NULL;
......
......@@ -111,3 +111,13 @@ print issubclass(OldStyleClass, object)
print isinstance(OldStyleClass(), OldStyleClass)
print issubclass(OldStyleClass, OldStyleClass)
class GetattrTest:
def __getattr__(self, attr):
print "getattr", attr
return 1
g = GetattrTest()
g.b = 2
print g.a
print g.b
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