MCPcopy Index your code
hub / github.com/RustPython/RustPython / _abc_subclasscheck

Function _abc_subclasscheck

crates/vm/src/stdlib/_abc.rs:322–405  ·  view source on GitHub ↗
(
        cls: PyObjectRef,
        subclass: PyObjectRef,
        vm: &VirtualMachine,
    )

Source from the content-addressed store, hash-verified

320 /// Internal ABC helper for subclass checks. Should be never used outside abc module.
321 #[pyfunction]
322 fn _abc_subclasscheck(
323 cls: PyObjectRef,
324 subclass: PyObjectRef,
325 vm: &VirtualMachine,
326 ) -> PyResult<bool> {
327 // Type check
328 if !subclass.class().fast_issubclass(vm.ctx.types.type_type) {
329 return Err(vm.new_type_error("issubclass() arg 1 must be a class"));
330 }
331
332 let impl_data = get_impl(&cls, vm)?;
333
334 // 1. Check cache
335 if in_weak_set(&impl_data.cache, &subclass, vm)? {
336 return Ok(true);
337 }
338
339 // 2. Check negative cache; may have to invalidate
340 let invalidation_counter = get_invalidation_counter();
341 if impl_data.get_cache_version() < invalidation_counter {
342 // Invalidate the negative cache
343 // Clone set ref and drop lock before calling into VM to avoid reentrancy
344 let set = impl_data.negative_cache.read().clone();
345 if let Some(ref set) = set {
346 vm.call_method(set.as_ref(), "clear", ())?;
347 }
348 impl_data.set_cache_version(invalidation_counter);
349 } else if in_weak_set(&impl_data.negative_cache, &subclass, vm)? {
350 return Ok(false);
351 }
352
353 // 3. Check the subclass hook
354 let ok = vm.call_method(&cls, "__subclasshook__", (subclass.clone(),))?;
355 if ok.is(&vm.ctx.true_value) {
356 add_to_weak_set(&impl_data.cache, &subclass, vm)?;
357 return Ok(true);
358 }
359 if ok.is(&vm.ctx.false_value) {
360 add_to_weak_set(&impl_data.negative_cache, &subclass, vm)?;
361 return Ok(false);
362 }
363 if !ok.is(&vm.ctx.not_implemented) {
364 return Err(vm.new_exception_msg(
365 vm.ctx.exceptions.assertion_error.to_owned(),
366 "__subclasshook__ must return either False, True, or NotImplemented".into(),
367 ));
368 }
369
370 // 4. Check if it's a direct subclass
371 let subclass_type: PyTypeRef = subclass
372 .clone()
373 .downcast()
374 .map_err(|_| vm.new_type_error("expected a type object"))?;
375 let cls_type: PyTypeRef = cls
376 .clone()
377 .downcast()
378 .map_err(|_| vm.new_type_error("expected a type object"))?;
379 if subclass_type.fast_issubclass(&cls_type) {

Callers 2

__subclasscheck__Method · 0.90
__subclasscheck__Method · 0.85

Calls 15

get_implFunction · 0.85
in_weak_setFunction · 0.85
get_invalidation_counterFunction · 0.85
add_to_weak_setFunction · 0.85
fast_issubclassMethod · 0.80
get_cache_versionMethod · 0.80
set_cache_versionMethod · 0.80
isMethod · 0.80
new_exception_msgMethod · 0.80
downcastMethod · 0.80
borrow_vecMethod · 0.80

Tested by

no test coverage detected