| 245 | } |
| 246 | |
| 247 | fn super_check(ty: PyTypeRef, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyTypeRef> { |
| 248 | let typ = match obj.clone().downcast::<PyType>() { |
| 249 | Ok(cls) if cls.fast_issubclass(&ty) => return Ok(cls), |
| 250 | Ok(cls) => Some(cls), |
| 251 | Err(_) => None, |
| 252 | }; |
| 253 | |
| 254 | if obj.fast_isinstance(&ty) { |
| 255 | return Ok(obj.class().to_owned()); |
| 256 | } |
| 257 | |
| 258 | let class_attr = obj.get_attr("__class__", vm)?; |
| 259 | if let Ok(cls) = class_attr.downcast::<PyType>() |
| 260 | && !cls.is(&ty) |
| 261 | && cls.fast_issubclass(&ty) |
| 262 | { |
| 263 | return Ok(cls); |
| 264 | } |
| 265 | |
| 266 | let (type_or_instance, obj_str) = match typ { |
| 267 | Some(t) => ("type", t.name().to_owned()), |
| 268 | None => ("instance of", obj.class().name().to_owned()), |
| 269 | }; |
| 270 | |
| 271 | Err(vm.new_type_error(format!( |
| 272 | "super(type, obj): obj ({} {}) is not an instance or subtype of type ({}).", |
| 273 | type_or_instance, |
| 274 | obj_str, |
| 275 | ty.name(), |
| 276 | ))) |
| 277 | } |
| 278 | |
| 279 | pub fn init(context: &'static Context) { |
| 280 | let super_type = &context.types.super_type; |