(
cls: PyObjectRef,
instance: PyObjectRef,
vm: &VirtualMachine,
)
| 244 | /// Internal ABC helper for instance checks. Should be never used outside abc module. |
| 245 | #[pyfunction] |
| 246 | fn _abc_instancecheck( |
| 247 | cls: PyObjectRef, |
| 248 | instance: PyObjectRef, |
| 249 | vm: &VirtualMachine, |
| 250 | ) -> PyResult<PyObjectRef> { |
| 251 | let impl_data = get_impl(&cls, vm)?; |
| 252 | |
| 253 | // Get instance.__class__ |
| 254 | let subclass = instance.get_attr("__class__", vm)?; |
| 255 | |
| 256 | // Check cache |
| 257 | if in_weak_set(&impl_data.cache, &subclass, vm)? { |
| 258 | return Ok(vm.ctx.true_value.clone().into()); |
| 259 | } |
| 260 | |
| 261 | let subtype: PyObjectRef = instance.class().to_owned().into(); |
| 262 | if subtype.is(&subclass) { |
| 263 | let invalidation_counter = get_invalidation_counter(); |
| 264 | if impl_data.get_cache_version() == invalidation_counter |
| 265 | && in_weak_set(&impl_data.negative_cache, &subclass, vm)? |
| 266 | { |
| 267 | return Ok(vm.ctx.false_value.clone().into()); |
| 268 | } |
| 269 | // Fall back to __subclasscheck__ |
| 270 | return vm.call_method(&cls, "__subclasscheck__", (subclass,)); |
| 271 | } |
| 272 | |
| 273 | // Call __subclasscheck__ on subclass |
| 274 | let result = vm.call_method(&cls, "__subclasscheck__", (subclass.clone(),))?; |
| 275 | |
| 276 | match result.clone().try_to_bool(vm) { |
| 277 | Ok(true) => Ok(result), |
| 278 | Ok(false) => { |
| 279 | // Also try with subtype |
| 280 | vm.call_method(&cls, "__subclasscheck__", (subtype,)) |
| 281 | } |
| 282 | Err(e) => Err(e), |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | /// Check if subclass is in registry (recursive) |
| 287 | fn subclasscheck_check_registry( |
no test coverage detected