(metatype: PyTypeRef, args: FuncArgs, vm: &VirtualMachine)
| 1800 | type Args = FuncArgs; |
| 1801 | |
| 1802 | fn slot_new(metatype: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult { |
| 1803 | vm_trace!("type.__new__ {:?}", args); |
| 1804 | |
| 1805 | let is_type_type = metatype.is(vm.ctx.types.type_type); |
| 1806 | if is_type_type && args.args.len() == 1 && args.kwargs.is_empty() { |
| 1807 | return Ok(args.args[0].class().to_owned().into()); |
| 1808 | } |
| 1809 | |
| 1810 | if args.args.len() != 3 { |
| 1811 | return Err(vm.new_type_error(if is_type_type { |
| 1812 | "type() takes 1 or 3 arguments".to_owned() |
| 1813 | } else { |
| 1814 | format!( |
| 1815 | "type.__new__() takes exactly 3 arguments ({} given)", |
| 1816 | args.args.len() |
| 1817 | ) |
| 1818 | })); |
| 1819 | } |
| 1820 | |
| 1821 | let (name, bases, dict, kwargs): (PyStrRef, PyTupleRef, PyDictRef, KwArgs) = |
| 1822 | args.clone().bind(vm)?; |
| 1823 | |
| 1824 | if name.as_bytes().contains(&0) { |
| 1825 | return Err(vm.new_value_error("type name must not contain null characters")); |
| 1826 | } |
| 1827 | let name = name.try_into_utf8(vm)?; |
| 1828 | |
| 1829 | let (metatype, base, bases, base_is_type) = if bases.is_empty() { |
| 1830 | let base = vm.ctx.types.object_type.to_owned(); |
| 1831 | (metatype, base.clone(), vec![base], false) |
| 1832 | } else { |
| 1833 | let bases = bases |
| 1834 | .iter() |
| 1835 | .map(|obj| { |
| 1836 | obj.clone().downcast::<Self>().or_else(|obj| { |
| 1837 | if vm |
| 1838 | .get_attribute_opt(obj, identifier!(vm, __mro_entries__))? |
| 1839 | .is_some() |
| 1840 | { |
| 1841 | Err(vm.new_type_error( |
| 1842 | "type() doesn't support MRO entry resolution; \ |
| 1843 | use types.new_class()", |
| 1844 | )) |
| 1845 | } else { |
| 1846 | Err(vm.new_type_error("bases must be types")) |
| 1847 | } |
| 1848 | }) |
| 1849 | }) |
| 1850 | .collect::<PyResult<Vec<_>>>()?; |
| 1851 | |
| 1852 | // Search the bases for the proper metatype to deal with this: |
| 1853 | let winner = calculate_meta_class(metatype.clone(), &bases, vm)?; |
| 1854 | let metatype = if !winner.is(&metatype) { |
| 1855 | if let Some(ref slot_new) = winner.slots.new.load() { |
| 1856 | // Pass it to the winner |
| 1857 | return slot_new(winner, args, vm); |
| 1858 | } |
| 1859 | winner |
nothing calls this directly
no test coverage detected