public static IntPtr tp_getattro(IntPtr ob, IntPtr key) {
ModuleObject self = (ModuleObject)GetManagedObject(ob);
if (!Runtime.PyString_Check(key)) {
Exceptions.SetError(Exceptions.TypeError, "string expected");
return IntPtr.Zero;
}
IntPtr op = Runtime.PyDict_GetItem(self.dict, key);
if (op != IntPtr.Zero) {
Runtime.Incref(op);
return op;
}
string name = Runtime.GetManagedString(key);
if (name == "__dict__") {
Runtime.Incref(self.dict);
return self.dict;
}
ManagedType attr = self.GetAttribute(name);
if (attr == null) {
Exceptions.SetError(Exceptions.AttributeError, name);
return IntPtr.Zero;
}
// XXX - hack required to recognize exception types. These types
// may need to be wrapped in old-style class wrappers in versions
// of Python where new-style classes cannot be used as exceptions.
if (Runtime.wrap_exceptions) {
if (attr is ClassBase) {
ClassBase c = attr as ClassBase;
if (c.is_exception) {
IntPtr p = attr.pyHandle;
IntPtr r = Exceptions.GetExceptionClassWrapper(p);
Runtime.PyDict_SetItemString(self.dict, name, r);
Runtime.Incref(r);
return r;
}
}
}
Runtime.Incref(attr.pyHandle);
return attr.pyHandle;
}