(&self, cls: &Self, vm: &VirtualMachine)
| 497 | } |
| 498 | |
| 499 | fn recursive_issubclass(&self, cls: &Self, vm: &VirtualMachine) -> PyResult<bool> { |
| 500 | // Fast path for both being types (matches CPython's PyType_Check) |
| 501 | if let Some(cls) = PyType::check(cls) |
| 502 | && let Some(derived) = PyType::check(self) |
| 503 | { |
| 504 | // PyType_IsSubtype equivalent |
| 505 | return Ok(derived.is_subtype(cls)); |
| 506 | } |
| 507 | // Check if derived is a class |
| 508 | self.check_class(vm, || { |
| 509 | format!("issubclass() arg 1 must be a class, not {}", self.class()) |
| 510 | })?; |
| 511 | |
| 512 | // Check if cls is a class, tuple, or union (matches CPython's order and message) |
| 513 | if !cls.class().is(vm.ctx.types.union_type) { |
| 514 | cls.check_class(vm, || { |
| 515 | format!( |
| 516 | "issubclass() arg 2 must be a class, a tuple of classes, or a union, not {}", |
| 517 | cls.class() |
| 518 | ) |
| 519 | })?; |
| 520 | } |
| 521 | |
| 522 | self.abstract_issubclass(cls, vm) |
| 523 | } |
| 524 | |
| 525 | /// Real issubclass check without going through __subclasscheck__ |
| 526 | /// This is equivalent to CPython's _PyObject_RealIsSubclass which just calls recursive_issubclass |
no test coverage detected