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

Method init

crates/vm/src/stdlib/_collections.rs:421–478  ·  view source on GitHub ↗
(
            zelf: PyRef<Self>,
            PyDequeOptions { iterable, maxlen }: Self::Args,
            vm: &VirtualMachine,
        )

Source from the content-addressed store, hash-verified

419 type Args = PyDequeOptions;
420
421 fn init(
422 zelf: PyRef<Self>,
423 PyDequeOptions { iterable, maxlen }: Self::Args,
424 vm: &VirtualMachine,
425 ) -> PyResult<()> {
426 // TODO: This is _basically_ pyobject_to_opt_usize in itertools.rs
427 // need to move that function elsewhere and refactor usages.
428 let maxlen = if let Some(obj) = maxlen.into_option() {
429 if !vm.is_none(&obj) {
430 let maxlen: isize = obj
431 .downcast_ref::<PyInt>()
432 .ok_or_else(|| vm.new_type_error("an integer is required."))?
433 .try_to_primitive(vm)?;
434
435 if maxlen.is_negative() {
436 return Err(vm.new_value_error("maxlen must be non-negative."));
437 }
438 Some(maxlen as usize)
439 } else {
440 None
441 }
442 } else {
443 None
444 };
445
446 // retrieve elements first to not to make too huge lock
447 let elements = iterable
448 .into_option()
449 .map(|iter| {
450 let mut elements: Vec<PyObjectRef> = iter.try_to_value(vm)?;
451 if let Some(maxlen) = maxlen {
452 elements.drain(..elements.len().saturating_sub(maxlen));
453 }
454 Ok(elements)
455 })
456 .transpose()?;
457
458 // SAFETY: This is hacky part for read-only field
459 // Because `maxlen` is only mutated from __init__. We can abuse the lock of deque to ensure this is locked enough.
460 // If we make a single lock of deque not only for extend but also for setting maxlen, it will be safe.
461 {
462 let mut deque = zelf.borrow_deque_mut();
463 // Clear any previous data present.
464 deque.clear();
465 unsafe {
466 // `maxlen` is better to be defined as UnsafeCell in common practice,
467 // but then more type works without any safety benefits
468 let unsafe_maxlen =
469 &zelf.maxlen as *const _ as *const core::cell::UnsafeCell<Option<usize>>;
470 *(*unsafe_maxlen).get() = maxlen;
471 }
472 if let Some(elements) = elements {
473 deque.extend(elements);
474 }
475 }
476
477 Ok(())
478 }

Callers

nothing calls this directly

Calls 14

into_optionMethod · 0.80
try_to_primitiveMethod · 0.80
ok_or_elseMethod · 0.80
try_to_valueMethod · 0.80
borrow_deque_mutMethod · 0.80
ErrClass · 0.50
SomeClass · 0.50
is_noneMethod · 0.45
mapMethod · 0.45
drainMethod · 0.45
lenMethod · 0.45
clearMethod · 0.45

Tested by

no test coverage detected