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

Method slot_new

crates/vm/src/builtins/type.rs:1802–2256  ·  view source on GitHub ↗
(metatype: PyTypeRef, args: FuncArgs, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

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

Callers

nothing calls this directly

Calls 15

calculate_meta_classFunction · 0.85
best_baseFunction · 0.85
downcast_qualnameFunction · 0.85
newFunction · 0.85
isMethod · 0.80
try_into_utf8Method · 0.80
get_attribute_optMethod · 0.80
get_item_optMethod · 0.80
into_wtf8Method · 0.80
to_attributesMethod · 0.80
ensure_valid_utf8Method · 0.80
get_mutMethod · 0.80

Tested by

no test coverage detected