Enable some pedantic clippy lints (#7764)

This commit is contained in:
Shahar Naveh authored and GitHub committed 2026-05-04 10:25:37 +09:00
1 parent bc29e21a9d
commit 323a45ef07
100 files changed
+471 -106

No files matched your search

+17 -5
View File
@@ -297,6 +297,20 @@ elided_lifetimes_in_paths = "warn"
unreachable_pub = "warn"
[workspace.lints.clippy]
correctness = { level = "warn", priority = -2 }
suspicious = { level = "warn", priority = -2 }
perf = { level = "warn", priority = -2 }
style = { level = "warn", priority = -2 }
complexity = { level = "warn", priority = -2 }
# pedantic = { level = "warn", priority = -2 } # TODO: Enable this
missing_errors_doc = "allow" # Too many errors. No auto-fix available
missing_panics_doc = "allow" # Too many errors. No auto-fix available
match_same_arms = "allow" # Not always more readable
if_not_else = "allow" # Not always more readable
single_match_else = "allow"
similar_names = "allow"
alloc_instead_of_core = "warn"
std_instead_of_alloc = "warn"
std_instead_of_core = "warn"
@@ -310,8 +324,6 @@ manual_is_variant_and = "warn"
or_fun_call = "warn"
unnested_or_patterns = "warn"
perf = "warn"
style = "warn"
complexity = "warn"
suspicious = "warn"
correctness = "warn"
# pedantic lints to enforce gradually
cloned_instead_of_copied = "warn"
must_use_candidate = "warn"
+8 -9
View File
@@ -417,6 +417,7 @@ impl Default for PatternContext {
}
impl PatternContext {
#[must_use]
pub const fn new() -> Self {
Self {
stores: Vec::new(),
@@ -426,6 +427,7 @@ impl PatternContext {
}
}
#[must_use]
pub fn fail_pop_size(&self) -> usize {
self.fail_pop.len()
}
@@ -6266,12 +6268,11 @@ impl Compiler {
return Err(self.error(CodegenErrorType::UnreachablePattern(
PatternUnreachableReason::NameCapture,
)));
} else {
// A wildcard makes remaining patterns unreachable.
return Err(self.error(CodegenErrorType::UnreachablePattern(
PatternUnreachableReason::Wildcard,
)));
}
// A wildcard makes remaining patterns unreachable.
return Err(self.error(CodegenErrorType::UnreachablePattern(
PatternUnreachableReason::Wildcard,
)));
}
// If irrefutable matches are allowed, store the name (if any).
return self.pattern_helper_store_name(p.name.as_ref(), pc);
@@ -10327,9 +10328,8 @@ impl Compiler {
if !found_loop {
if is_break {
return Err(self.error_ranged(CodegenErrorType::InvalidBreak, range));
} else {
return Err(self.error_ranged(CodegenErrorType::InvalidContinue, range));
}
return Err(self.error_ranged(CodegenErrorType::InvalidContinue, range));
}
return Ok(());
}
@@ -10368,9 +10368,8 @@ impl Compiler {
let Some(loop_idx) = loop_idx else {
if is_break {
return Err(self.error_ranged(CodegenErrorType::InvalidBreak, range));
} else {
return Err(self.error_ranged(CodegenErrorType::InvalidContinue, range));
}
return Err(self.error_ranged(CodegenErrorType::InvalidContinue, range));
};
let loop_block = code.fblock[loop_idx].fb_block;
+5
View File
@@ -125,6 +125,7 @@ impl SymbolTable {
builder.finish()
}
#[must_use]
pub fn lookup(&self, name: &str) -> Option<&Symbol> {
self.symbols.get(name)
}
@@ -226,6 +227,7 @@ impl Symbol {
}
}
#[must_use]
pub const fn is_global(&self) -> bool {
matches!(
self.scope,
@@ -233,10 +235,12 @@ impl Symbol {
)
}
#[must_use]
pub const fn is_local(&self) -> bool {
matches!(self.scope, SymbolScope::Local | SymbolScope::Cell)
}
#[must_use]
pub const fn is_bound(&self) -> bool {
self.flags.intersects(SymbolFlags::BOUND)
}
@@ -249,6 +253,7 @@ pub struct SymbolTableError {
}
impl SymbolTableError {
#[must_use]
pub fn into_codegen_error(self, source_path: String) -> CodegenError {
CodegenError {
location: self.location,
+1
View File
@@ -64,6 +64,7 @@ impl<T> Default for OncePtr<T> {
impl<T> OncePtr<T> {
#[inline]
#[must_use]
pub fn new() -> Self {
Self {
inner: Radium::new(ptr::null_mut()),
+9
View File
@@ -38,6 +38,7 @@ macro_rules! panic_oob {
}
impl<T> BoxVec<T> {
#[must_use]
pub fn new(n: usize) -> Self {
Self {
xs: Box::new_uninit_slice(n),
@@ -46,24 +47,29 @@ impl<T> BoxVec<T> {
}
#[inline]
#[must_use]
pub const fn len(&self) -> usize {
self.len
}
#[inline]
#[must_use]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
#[must_use]
pub const fn capacity(&self) -> usize {
self.xs.len()
}
#[must_use]
pub const fn is_full(&self) -> bool {
self.len() == self.capacity()
}
#[must_use]
pub const fn remaining_capacity(&self) -> usize {
self.capacity() - self.len()
}
@@ -312,6 +318,7 @@ impl<T> BoxVec<T> {
}
/// Return a slice containing all elements of the vector.
#[must_use]
pub fn as_slice(&self) -> &[T] {
self
}
@@ -323,6 +330,7 @@ impl<T> BoxVec<T> {
/// Return a raw pointer to the vector's buffer.
#[inline]
#[must_use]
pub fn as_ptr(&self) -> *const T {
self.xs.as_ptr().cast()
}
@@ -487,6 +495,7 @@ impl<T> DoubleEndedIterator for Drain<'_, T> {
impl<T> ExactSizeIterator for Drain<'_, T> {}
impl<'a, T> Drain<'a, T> {
#[must_use]
pub fn as_slice(&self) -> &'a [T] {
self.iter.as_slice()
}
+7 -1
View File
@@ -102,6 +102,7 @@ pub enum CFormatType {
}
impl CFormatType {
#[must_use]
pub const fn to_char(self) -> char {
match self {
Self::Number(x) => x as u8 as char,
@@ -137,6 +138,7 @@ bitflags! {
impl CConversionFlags {
#[inline]
#[must_use]
pub const fn sign_string(&self) -> &'static str {
if self.contains(Self::SIGN_CHAR) {
"+"
@@ -408,6 +410,7 @@ impl CFormatSpec {
)
}
#[must_use]
pub fn format_bytes(&self, bytes: &[u8]) -> Vec<u8> {
let bytes = if let Some(CFormatPrecision::Quantity(CFormatQuantity::Amount(precision))) =
self.precision
@@ -432,6 +435,7 @@ impl CFormatSpec {
}
}
#[must_use]
pub fn format_number(&self, num: &BigInt) -> String {
use CNumberType::*;
let CFormatType::Number(format_type) = self.format_type else {
@@ -492,6 +496,7 @@ impl CFormatSpec {
}
}
#[must_use]
pub fn format_float(&self, num: f64) -> String {
let sign_string = if num.is_sign_negative() && !num.is_nan() {
"-"
@@ -740,6 +745,7 @@ pub struct CFormatStrOrBytes<S> {
}
impl<S> CFormatStrOrBytes<S> {
#[must_use]
pub fn check_specifiers(&self) -> Option<(usize, bool)> {
let mut count = 0;
let mut mapping_required = false;
@@ -828,7 +834,7 @@ pub type CFormatBytes = CFormatStrOrBytes<Vec<u8>>;
impl CFormatBytes {
pub fn parse_from_bytes(bytes: &[u8]) -> Result<Self, CFormatError> {
let mut iter = bytes.iter().cloned().enumerate().peekable();
let mut iter = bytes.iter().copied().enumerate().peekable();
Self::parse(&mut iter)
}
}
+12
View File
@@ -2,6 +2,7 @@ use core::f64;
use malachite_bigint::{BigInt, ToBigInt};
use num_traits::{Signed, ToPrimitive};
#[must_use]
pub const fn decompose_float(value: f64) -> (f64, i32) {
if 0.0 == value {
(0.0, 0i32)
@@ -29,6 +30,7 @@ pub const fn decompose_float(value: f64) -> (f64, i32) {
/// assert!(!eq_int(c, &b));
/// ```
///
#[must_use]
pub fn eq_int(value: f64, other: &BigInt) -> bool {
if let (Some(self_int), Some(other_float)) = (value.to_bigint(), other.to_f64()) {
value == other_float && self_int == *other
@@ -37,6 +39,7 @@ pub fn eq_int(value: f64, other: &BigInt) -> bool {
}
}
#[must_use]
pub fn lt_int(value: f64, other_int: &BigInt) -> bool {
match (value.to_bigint(), other_int.to_f64()) {
(Some(self_int), Some(other_float)) => value < other_float || self_int < *other_int,
@@ -50,6 +53,7 @@ pub fn lt_int(value: f64, other_int: &BigInt) -> bool {
}
}
#[must_use]
pub fn gt_int(value: f64, other_int: &BigInt) -> bool {
match (value.to_bigint(), other_int.to_f64()) {
(Some(self_int), Some(other_float)) => value > other_float || self_int > *other_int,
@@ -63,14 +67,17 @@ pub fn gt_int(value: f64, other_int: &BigInt) -> bool {
}
}
#[must_use]
pub const fn div(v1: f64, v2: f64) -> Option<f64> {
if v2 != 0.0 { Some(v1 / v2) } else { None }
}
#[must_use]
pub fn mod_(v1: f64, v2: f64) -> Option<f64> {
divmod(v1, v2).map(|(_, m)| m)
}
#[must_use]
pub fn floordiv(v1: f64, v2: f64) -> Option<f64> {
divmod(v1, v2).map(|(d, _)| d)
}
@@ -78,6 +85,7 @@ pub fn floordiv(v1: f64, v2: f64) -> Option<f64> {
// Canonical (floordiv, mod) for floats matching CPython's _float_div_mod
// (Objects/floatobject.c). `mod_` and `floordiv` delegate here so that
// `divmod(a, b) == (a // b, a % b)` holds by construction.
#[must_use]
pub fn divmod(v1: f64, v2: f64) -> Option<(f64, f64)> {
if v2 == 0.0 {
return None;
@@ -108,6 +116,7 @@ pub fn divmod(v1: f64, v2: f64) -> Option<(f64, f64)> {
// nextafter algorithm based off of https://gitlab.com/bronsonbdevost/next_afterf
#[allow(clippy::float_cmp)]
#[must_use]
pub fn nextafter(x: f64, y: f64) -> f64 {
if x == y {
y
@@ -130,6 +139,7 @@ pub fn nextafter(x: f64, y: f64) -> f64 {
}
#[allow(clippy::float_cmp)]
#[must_use]
pub fn nextafter_with_steps(x: f64, y: f64, steps: u64) -> f64 {
if x == y {
y
@@ -192,6 +202,7 @@ pub fn nextafter_with_steps(x: f64, y: f64, steps: u64) -> f64 {
}
}
#[must_use]
pub fn ulp(x: f64) -> f64 {
if x.is_nan() {
return x;
@@ -207,6 +218,7 @@ pub fn ulp(x: f64) -> f64 {
}
}
#[must_use]
pub fn round_float_digits(x: f64, ndigits: i32) -> Option<f64> {
// Mirror CPython's `float.__round__` (Objects/floatobject.c), which uses
// `_Py_dg_dtoa` to round at the decimal level. Multiplying by 10**ndigits
+8 -7
View File
@@ -53,6 +53,7 @@ impl FormatParse for FormatConversion {
}
impl FormatConversion {
#[must_use]
pub fn from_char(c: CodePoint) -> Option<Self> {
match c.to_char_lossy() {
's' => Some(Self::Str),
@@ -479,6 +480,7 @@ impl FormatSpec {
}
/// Returns true if this format spec uses the locale-aware 'n' format type.
#[must_use]
pub fn has_locale_format(&self) -> bool {
matches!(self.format_type, Some(FormatType::Number(Case::Lower)))
}
@@ -487,6 +489,7 @@ impl FormatSpec {
/// subject to `sys.get_int_max_str_digits()` (no spec, 'd', or 'n').
/// Binary bases ('b', 'o', 'x', 'X') are exempt per CPython. 'N' is rejected
/// later in `format_int` as `UnknownFormatCode`, so it is not included here.
#[must_use]
pub fn is_decimal_int_format(&self) -> bool {
matches!(
self.format_type,
@@ -1354,20 +1357,18 @@ impl FormatString {
} else if c == '{' {
if nested {
return Err(FormatParseError::InvalidFormatSpecifier);
} else {
nested = true;
left.push(c);
continue;
}
nested = true;
left.push(c);
continue;
} else if c == '}' {
if nested {
nested = false;
left.push(c);
continue;
} else {
end_bracket_pos = Some(idx);
break;
}
end_bracket_pos = Some(idx);
break;
} else {
left.push(c);
}
+12
View File
@@ -40,6 +40,7 @@ impl BuildHasher for HashSecret {
}
impl HashSecret {
#[must_use]
pub fn new(seed: u32) -> Self {
let mut buf = [0u8; 16];
lcg_urandom(seed, &mut buf);
@@ -68,6 +69,7 @@ impl HashSecret {
Ok(fix_sentinel(mod_int(hasher.finish() as PyHash)))
}
#[must_use]
pub fn hash_bytes(&self, value: &[u8]) -> PyHash {
if value.is_empty() {
0
@@ -76,12 +78,14 @@ impl HashSecret {
}
}
#[must_use]
pub fn hash_str(&self, value: &str) -> PyHash {
self.hash_bytes(value.as_bytes())
}
}
#[inline]
#[must_use]
pub const fn hash_pointer(value: usize) -> PyHash {
// TODO: 32bit?
let hash = (value >> 4) | value;
@@ -89,6 +93,7 @@ pub const fn hash_pointer(value: usize) -> PyHash {
}
#[inline]
#[must_use]
pub fn hash_float(value: f64) -> Option<PyHash> {
// cpython _Py_HashDouble
if !value.is_finite() {
@@ -130,6 +135,7 @@ pub fn hash_float(value: f64) -> Option<PyHash> {
Some(fix_sentinel(x as PyHash * value.signum() as PyHash))
}
#[must_use]
pub fn hash_bigint(value: &BigInt) -> PyHash {
let ret = match value.to_i64() {
Some(i) => mod_int(i),
@@ -142,16 +148,19 @@ pub fn hash_bigint(value: &BigInt) -> PyHash {
}
#[inline]
#[must_use]
pub const fn hash_usize(data: usize) -> PyHash {
fix_sentinel(mod_int(data as i64))
}
#[inline(always)]
#[must_use]
pub const fn fix_sentinel(x: PyHash) -> PyHash {
if x == SENTINEL { -2 } else { x }
}
#[inline]
#[must_use]
pub const fn mod_int(value: i64) -> PyHash {
value % MODULUS as i64
}
@@ -165,6 +174,7 @@ pub fn lcg_urandom(mut x: u32, buf: &mut [u8]) {
}
#[inline]
#[must_use]
pub const fn hash_object_id_raw(p: usize) -> PyHash {
// TODO: Use commented logic when below issue resolved.
// Ref: https://github.com/RustPython/RustPython/pull/3951#issuecomment-1193108966
@@ -176,10 +186,12 @@ pub const fn hash_object_id_raw(p: usize) -> PyHash {
}
#[inline]
#[must_use]
pub const fn hash_object_id(p: usize) -> PyHash {
fix_sentinel(hash_object_id_raw(p))
}
#[must_use]
pub fn keyed_hash(key: u64, buf: &[u8]) -> u64 {
let mut hasher = SipHasher24::new_with_keys(key, 0);
buf.hash(&mut hasher);
+3
View File
@@ -3,6 +3,7 @@ use malachite_bigint::{BigInt, BigUint, Sign};
use malachite_q::Rational;
use num_traits::{One, ToPrimitive, Zero};
#[must_use]
pub fn true_div(numerator: &BigInt, denominator: &BigInt) -> f64 {
let rational = Rational::from_integers_ref(numerator.into(), denominator.into());
match rational.rounding_into(RoundingMode::Nearest) {
@@ -14,6 +15,7 @@ pub fn true_div(numerator: &BigInt, denominator: &BigInt) -> f64 {
}
}
#[must_use]
pub fn float_to_ratio(value: f64) -> Option<(BigInt, BigInt)> {
let sign = match core::cmp::PartialOrd::partial_cmp(&value, &0.0)? {
core::cmp::Ordering::Less => Sign::Minus,
@@ -146,6 +148,7 @@ pub fn bytes_to_int(
// num-bigint now returns Some(inf) for to_f64() in some cases, so just keep that the same for now
#[inline(always)]
#[must_use]
pub fn bigint_to_finite_float(int: &BigInt) -> Option<f64> {
int.to_f64().filter(|f| f.is_finite())
}
+3
View File
@@ -140,6 +140,7 @@ unsafe impl<T: Sync> Sync for Pointers<T> {}
impl<L, T> LinkedList<L, T> {
/// Creates an empty linked list.
#[must_use]
pub const fn new() -> Self {
Self {
head: None,
@@ -216,6 +217,7 @@ impl<L: Link> LinkedList<L, L::Target> {
}
/// Returns whether the linked list does not contain any node
#[must_use]
pub const fn is_empty(&self) -> bool {
self.head.is_none()
// if self.head.is_some() {
@@ -354,6 +356,7 @@ where
impl<T> Pointers<T> {
/// Create a new set of empty pointers
#[must_use]
pub const fn new() -> Self {
Self {
inner: UnsafeCell::new(PointersInner {
+4 -5
View File
@@ -35,12 +35,11 @@ impl<R: RawMutex, G: GetThreadId> RawThreadMutex<R, G> {
let id = self.get_thread_id.nonzero_thread_id().get();
if self.owner.load(Ordering::Relaxed) == id {
return None;
} else {
if !try_lock() {
return Some(false);
}
self.owner.store(id, Ordering::Relaxed);
}
if !try_lock() {
return Some(false);
}
self.owner.store(id, Ordering::Relaxed);
Some(true)
}
+1
View File
@@ -6,6 +6,7 @@
/// # Panics
///
/// Panics if the OS entropy source returns an error.
#[must_use]
pub fn os_random<const N: usize>() -> [u8; N] {
let mut buf = [0u8; N];
getrandom::fill(&mut buf).unwrap();
+1
View File
@@ -86,6 +86,7 @@ impl Default for RefCount {
impl RefCount {
/// Create a new RefCount with strong count = 1
#[must_use]
pub fn new() -> Self {
// Initial state: strong=1, weak=1 (implicit weak for strong refs)
Self {
+2
View File
@@ -67,10 +67,12 @@ mod non_threading {
impl<T> StaticCell<T> {
#[doc(hidden)]
#[must_use]
pub const fn _from_local_key(inner: &'static LocalKey<OnceCell<&'static T>>) -> Self {
Self { inner }
}
#[must_use]
pub fn get(&'static self) -> Option<&'static T> {
self.inner.with(|x| x.get().copied())
}
+12
View File
@@ -36,15 +36,18 @@ impl core::ops::BitOr for StrKind {
}
impl StrKind {
#[must_use]
pub const fn is_ascii(&self) -> bool {
matches!(self, Self::Ascii)
}
#[must_use]
pub const fn is_utf8(&self) -> bool {
matches!(self, Self::Ascii | Self::Utf8)
}
#[inline(always)]
#[must_use]
pub fn can_encode(&self, code: CodePoint) -> bool {
match self {
Self::Ascii => code.is_ascii(),
@@ -234,6 +237,7 @@ impl StrData {
/// # Safety
///
/// Given `bytes` must be valid data for given `kind`
#[must_use]
pub unsafe fn new_str_unchecked(data: Box<Wtf8>, kind: StrKind) -> Self {
let len = match kind {
StrKind::Ascii => data.len().into(),
@@ -245,6 +249,7 @@ impl StrData {
/// # Safety
///
/// `char_len` must be accurate.
#[must_use]
pub unsafe fn new_with_char_len(data: Box<Wtf8>, kind: StrKind, char_len: usize) -> Self {
Self {
data,
@@ -364,6 +369,7 @@ pub fn get_chars(s: &str, range: impl RangeBounds<usize>) -> &str {
}
#[inline]
#[must_use]
pub fn char_range_end(s: &str, n_chars: usize) -> Option<usize> {
let i = match n_chars.checked_sub(1) {
Some(last_char_index) => {
@@ -399,6 +405,7 @@ pub fn get_codepoints(w: &Wtf8, range: impl RangeBounds<usize>) -> &Wtf8 {
}
#[inline]
#[must_use]
pub fn codepoint_range_end(s: &Wtf8, n_chars: usize) -> Option<usize> {
let i = match n_chars.checked_sub(1) {
Some(last_char_index) => {
@@ -410,6 +417,7 @@ pub fn codepoint_range_end(s: &Wtf8, n_chars: usize) -> Option<usize> {
Some(i)
}
#[must_use]
pub fn zfill(bytes: &[u8], width: usize) -> Vec<u8> {
if width <= bytes.len() {
bytes.to_vec()
@@ -428,6 +436,7 @@ pub fn zfill(bytes: &[u8], width: usize) -> Vec<u8> {
/// Convert a string to ascii compatible, escaping unicode-s into escape
/// sequences.
#[must_use]
pub fn to_ascii(value: &Wtf8) -> AsciiString {
let mut ascii = Vec::new();
for cp in value.code_points() {
@@ -485,6 +494,7 @@ pub mod levenshtein {
if a == b { CASE_COST } else { MOVE_COST }
}
#[must_use]
pub fn levenshtein_distance(a: &[u8], b: &[u8], max_cost: usize) -> usize {
if a == b {
return 0;
@@ -555,6 +565,7 @@ pub mod levenshtein {
}
/// Replace all tabs in a string with spaces, using the given tab size.
#[must_use]
pub fn expandtabs(input: &str, tab_size: usize) -> String {
let tab_stop = tab_size;
let mut expanded_str = String::with_capacity(input.len());
@@ -641,6 +652,7 @@ const UNICODE_DECIMAL_VALUES: &[char] = &[
'𞥗', '𞥘', '𞥙',
];
#[must_use]
pub fn char_to_decimal(ch: char) -> Option<u8> {
UNICODE_DECIMAL_VALUES
.binary_search(&ch)
+15
View File
@@ -52,6 +52,7 @@ pub struct ExceptionTableEntry {
}
impl ExceptionTableEntry {
#[must_use]
pub const fn new(start: u32, end: u32, target: u32, depth: u16, push_lasti: bool) -> Self {
Self {
start,
@@ -65,6 +66,7 @@ impl ExceptionTableEntry {
/// Encode exception table entries.
/// Uses 6-bit varint encoding with start marker (MSB) and continuation bit.
#[must_use]
pub fn encode_exception_table(entries: &[ExceptionTableEntry]) -> alloc::boxed::Box<[u8]> {
let mut data = Vec::new();
for entry in entries {
@@ -80,6 +82,7 @@ pub fn encode_exception_table(entries: &[ExceptionTableEntry]) -> alloc::boxed::
}
/// Find exception handler for given instruction offset.
#[must_use]
pub fn find_exception_handler(table: &[u8], offset: u32) -> Option<ExceptionTableEntry> {
let mut pos = 0;
while pos < table.len() {
@@ -106,6 +109,7 @@ pub fn find_exception_handler(table: &[u8], offset: u32) -> Option<ExceptionTabl
}
/// Decode all exception table entries.
#[must_use]
pub fn decode_exception_table(table: &[u8]) -> Vec<ExceptionTableEntry> {
let mut entries = Vec::new();
let mut pos = 0;
@@ -138,6 +142,7 @@ pub fn decode_exception_table(table: &[u8]) -> Vec<ExceptionTableEntry> {
/// Parse linetable to build a boolean mask indicating which code units
/// have NO_LOCATION (line == -1). Returns a Vec<bool> of length `num_units`.
#[must_use]
pub fn build_no_location_mask(linetable: &[u8], num_units: usize) -> Vec<bool> {
let mut mask = Vec::new();
mask.resize(num_units, false);
@@ -227,6 +232,7 @@ pub enum PyCodeLocationInfoKind {
}
impl PyCodeLocationInfoKind {
#[must_use]
pub fn from_code(code: u8) -> Option<Self> {
match code {
0 => Some(Self::Short0),
@@ -249,10 +255,12 @@ impl PyCodeLocationInfoKind {
}
}
#[must_use]
pub fn is_short(&self) -> bool {
(*self as u8) <= 9
}
#[must_use]
pub fn short_column_group(&self) -> Option<u8> {
if self.is_short() {
Some(*self as u8)
@@ -261,6 +269,7 @@ impl PyCodeLocationInfoKind {
}
}
#[must_use]
pub fn one_line_delta(&self) -> Option<i32> {
match self {
Self::OneLine0 => Some(0),
@@ -483,24 +492,28 @@ const MAX_BACKOFF: u16 = 12;
const UNREACHABLE_BACKOFF: u16 = 15;
/// Encode an adaptive counter as `(value << 4) | backoff`.
#[must_use]
pub const fn adaptive_counter_bits(value: u16, backoff: u16) -> u16 {
(value << BACKOFF_BITS) | backoff
}
/// True when the adaptive counter should trigger specialization.
#[inline]
#[must_use]
pub const fn adaptive_counter_triggers(counter: u16) -> bool {
counter < UNREACHABLE_BACKOFF
}
/// Decrement adaptive counter by one countdown step.
#[inline]
#[must_use]
pub const fn advance_adaptive_counter(counter: u16) -> u16 {
counter.wrapping_sub(1 << BACKOFF_BITS)
}
/// Reset adaptive counter with exponential backoff.
#[inline]
#[must_use]
pub const fn adaptive_counter_backoff(counter: u16) -> u16 {
let backoff = counter & ((1 << BACKOFF_BITS) - 1);
if backoff < MAX_BACKOFF {
@@ -511,6 +524,7 @@ pub const fn adaptive_counter_backoff(counter: u16) -> u16 {
}
impl CodeUnit {
#[must_use]
pub const fn new(op: Instruction, arg: OpArgByte) -> Self {
Self { op, arg }
}
@@ -1016,6 +1030,7 @@ impl<C: Constant> BorrowedConstant<'_, C> {
}
}
#[must_use]
pub fn to_owned(self) -> ConstantData {
use ConstantData::*;
@@ -517,6 +517,7 @@ define_opcodes!(
impl Instruction {
/// Returns `true` if this is any instrumented opcode
/// (regular INSTRUMENTED_*, INSTRUMENTED_LINE, or INSTRUMENTED_INSTRUCTION).
#[must_use]
pub const fn is_instrumented(self) -> bool {
self.to_base().is_some()
|| matches!(self, Self::InstrumentedLine | Self::InstrumentedInstruction)
@@ -527,6 +528,7 @@ impl Instruction {
///
/// # Panics (debug)
/// Panics if called on an already-instrumented opcode.
#[must_use]
pub fn to_instrumented(self) -> Option<Self> {
debug_assert!(
!self.is_instrumented(),
@@ -564,6 +566,7 @@ impl Instruction {
///
/// The returned base opcode uses `Arg::marker()` for typed fields —
/// only the opcode byte matters since `replace_op` preserves the arg byte.
#[must_use]
pub const fn to_base(self) -> Option<Self> {
Some(match self {
Self::InstrumentedResume => Self::Resume {
@@ -613,6 +616,7 @@ impl Instruction {
/// Map a specialized opcode back to its adaptive (base) variant.
/// `_PyOpcode_Deopt`
#[must_use]
pub const fn deopt(self) -> Option<Self> {
let opcode = match self {
Self::ResumeCheck => Opcode::Resume,
@@ -696,6 +700,7 @@ impl Instruction {
}
/// Map a specialized or instrumented opcode back to its adaptive (base) variant.
#[must_use]
pub const fn deoptimize(self) -> Self {
match self.deopt() {
Some(v) => v,
@@ -714,6 +719,7 @@ impl Instruction {
/// Instrumented and specialized opcodes have the same cache entries as their base.
///
/// _PyOpcode_Caches
#[must_use]
pub const fn cache_entries(self) -> usize {
match self.deoptimize().opcode() {
Opcode::LoadAttr => 9,
@@ -1348,6 +1354,7 @@ impl PseudoInstruction {
/// - [`PseudoInstruction::SetupCleanup`]
/// - [`PseudoInstruction::SetupFinally`]
/// - [`PseudoInstruction::SetupWith`]
#[must_use]
pub const fn is_block_push(&self) -> bool {
matches!(
self.opcode(),
@@ -1530,6 +1537,7 @@ impl InstructionMetadata for AnyInstruction {
impl AnyInstruction {
/// Inner value of [`Self::Real`].
#[must_use]
pub const fn real(self) -> Option<Instruction> {
match self {
Self::Real(ins) => Some(ins),
@@ -1538,6 +1546,7 @@ impl AnyInstruction {
}
/// Inner value of [`Self::Pseudo`].
#[must_use]
pub const fn pseudo(self) -> Option<PseudoInstruction> {
match self {
Self::Pseudo(ins) => Some(ins),
@@ -1546,6 +1555,7 @@ impl AnyInstruction {
}
/// Get [`Self::Real`] as [`Opcode`].
#[must_use]
pub const fn real_opcode(self) -> Option<Opcode> {
match self.real() {
Some(ins) => Some(ins.opcode()),
@@ -1554,6 +1564,7 @@ impl AnyInstruction {
}
/// Get [`Self::Pseudo`] as [`PseudoOpcode`].
#[must_use]
pub const fn pseudo_opcode(self) -> Option<PseudoOpcode> {
match self.pseudo() {
Some(ins) => Some(ins.opcode()),
@@ -1566,6 +1577,7 @@ impl AnyInstruction {
/// # Panics
///
/// If was called on something else other than [`Self::Real`].
#[must_use]
pub const fn expect_real(self) -> Instruction {
self.real()
.expect("Expected AnyInstruction::Real, found AnyInstruction::Pseudo")
@@ -1576,17 +1588,20 @@ impl AnyInstruction {
/// # Panics
///
/// If was called on something else other than [`Self::Pseudo`].
#[must_use]
pub const fn expect_pseudo(self) -> PseudoInstruction {
self.pseudo()
.expect("Expected AnyInstruction::Pseudo, found AnyInstruction::Real")
}
/// Returns true if this is a [`PseudoInstruction::PopBlock`].
#[must_use]
pub const fn is_pop_block(self) -> bool {
matches!(self, Self::Pseudo(PseudoInstruction::PopBlock))
}
/// See [`PseudoInstruction::is_block_push`].
#[must_use]
pub const fn is_block_push(self) -> bool {
matches!(self, Self::Pseudo(p) if p.is_block_push())
}
@@ -1640,6 +1655,7 @@ impl From<AnyInstruction> for AnyOpcode {
impl AnyOpcode {
/// Gets the inner value of [`Self::Real`].
#[must_use]
pub const fn real(self) -> Option<Opcode> {
match self {
Self::Real(op) => Some(op),
@@ -1648,6 +1664,7 @@ impl AnyOpcode {
}
/// Gets the inner value of [`Self::Pseudo`].
#[must_use]
pub const fn pseudo(self) -> Option<PseudoOpcode> {
match self {
Self::Pseudo(op) => Some(op),
@@ -1660,6 +1677,7 @@ impl AnyOpcode {
/// # Panics
///
/// If was called on something else other than [`Self::Real`].
#[must_use]
pub const fn expect_real(self) -> Opcode {
self.real()
.expect("Expected AnyOpcode::Real, found AnyOpcode::Pseudo")
@@ -1670,6 +1688,7 @@ impl AnyOpcode {
/// # Panics
///
/// If was called on something else other than [`Self::Pseudo`].
#[must_use]
pub const fn expect_pseudo(self) -> PseudoOpcode {
self.pseudo()
.expect("Expected AnyOpcode::Pseudo, found AnyOpcode::Real")
@@ -1687,21 +1706,25 @@ pub struct StackEffect {
impl StackEffect {
/// Creates a new [`Self`].
#[must_use]
pub const fn new(pushed: u32, popped: u32) -> Self {
Self { pushed, popped }
}
/// Get the calculated stack effect as [`i32`].
#[must_use]
pub fn effect(self) -> i32 {
self.into()
}
/// Get the pushed count.
#[must_use]
pub const fn pushed(self) -> u32 {
self.pushed
}
/// Get the popped count.
#[must_use]
pub const fn popped(self) -> u32 {
self.popped
}
@@ -1761,6 +1784,7 @@ pub struct Arg<T: OpArgType>(PhantomData<T>);
impl<T: OpArgType> Arg<T> {
#[inline]
#[must_use]
pub const fn marker() -> Self {
Self(PhantomData)
}
@@ -1779,6 +1803,7 @@ impl<T: OpArgType> Arg<T> {
}
#[inline(always)]
#[must_use]
pub fn get(self, arg: OpArg) -> T {
self.try_get(arg).unwrap()
}
@@ -1791,6 +1816,7 @@ impl<T: OpArgType> Arg<T> {
/// # Safety
/// T::from_op_arg(self) must succeed
#[inline(always)]
#[must_use]
pub unsafe fn get_unchecked(self, arg: OpArg) -> T {
// SAFETY: requirements forwarded from caller
unsafe { T::try_from(u32::from(arg)).unwrap_unchecked() }
@@ -66,6 +66,7 @@ impl OpArg {
/// Returns how many CodeUnits a instruction with this op_arg will be encoded as
#[inline]
#[must_use]
pub const fn instr_size(self) -> usize {
(self.0 > 0xff) as usize + (self.0 > 0xff_ff) as usize + (self.0 > 0xff_ff_ff) as usize + 1
}
+1
View File
@@ -1138,6 +1138,7 @@ pub fn split_localplus<S: Clone>(
})
}
#[must_use]
pub fn linetable_to_locations(
linetable: &[u8],
first_line: i32,
+5
View File
@@ -46,6 +46,7 @@ pub enum CompileError {
}
impl CompileError {
#[must_use]
pub fn from_ruff_parse_error(error: parser::ParseError, source_file: &SourceFile) -> Self {
let source_code = source_file.to_source_code();
let source_text = source_file.source_text();
@@ -116,6 +117,7 @@ impl CompileError {
})
}
#[must_use]
pub const fn location(&self) -> Option<SourceLocation> {
match self {
Self::Codegen(codegen_error) => codegen_error.location,
@@ -123,6 +125,7 @@ impl CompileError {
}
}
#[must_use]
pub const fn python_location(&self) -> (usize, usize) {
if let Some(location) = self.location() {
(location.line.get(), location.character_offset.get())
@@ -131,6 +134,7 @@ impl CompileError {
}
}
#[must_use]
pub fn python_end_location(&self) -> Option<(usize, usize)> {
match self {
CompileError::Codegen(_) => None,
@@ -141,6 +145,7 @@ impl CompileError {
}
}
#[must_use]
pub fn source_path(&self) -> &str {
match self {
Self::Codegen(codegen_error) => &codegen_error.source_path,
+1 -2
View File
@@ -192,9 +192,8 @@ impl CompilationSource {
let joined = path.parent().unwrap().join(real_path.trim());
if joined.exists() {
return compile_path(&joined);
} else {
return Err(e);
}
return Err(e);
}
Err(e)
});
+8
View File
@@ -36,10 +36,12 @@ fn result_to_tokens(result: Result<TokenStream, impl Into<Diagnostic>>) -> Token
.unwrap_or_else(ToTokens::into_token_stream)
}
#[must_use]
pub fn derive_from_args(input: DeriveInput) -> TokenStream {
result_to_tokens(from_args::impl_from_args(input))
}
#[must_use]
pub fn pyclass(attr: PunctuatedNestedMeta, item: Item) -> TokenStream {
if matches!(item, syn::Item::Impl(_) | syn::Item::Trait(_)) {
result_to_tokens(pyclass::impl_pyclass_impl(attr, item))
@@ -48,6 +50,7 @@ pub fn pyclass(attr: PunctuatedNestedMeta, item: Item) -> TokenStream {
}
}
#[must_use]
pub fn pyexception(attr: PunctuatedNestedMeta, item: Item) -> TokenStream {
if matches!(item, syn::Item::Impl(_)) {
result_to_tokens(pyclass::impl_pyexception_impl(attr, item))
@@ -56,14 +59,17 @@ pub fn pyexception(attr: PunctuatedNestedMeta, item: Item) -> TokenStream {
}
}
#[must_use]
pub fn pymodule(attr: PyModuleArgs, item: Item) -> TokenStream {
result_to_tokens(pymodule::impl_pymodule(attr, item))
}
#[must_use]
pub fn pystruct_sequence(attr: PunctuatedNestedMeta, item: Item) -> TokenStream {
result_to_tokens(pystructseq::impl_pystruct_sequence(attr, item))
}
#[must_use]
pub fn pystruct_sequence_data(attr: PunctuatedNestedMeta, item: Item) -> TokenStream {
result_to_tokens(pystructseq::impl_pystruct_sequence_data(attr, item))
}
@@ -76,10 +82,12 @@ pub fn py_freeze(input: TokenStream, compiler: &dyn Compiler) -> TokenStream {
result_to_tokens(compile_bytecode::impl_py_freeze(input, compiler))
}
#[must_use]
pub fn pypayload(input: DeriveInput) -> TokenStream {
result_to_tokens(pypayload::impl_pypayload(input))
}
#[must_use]
pub fn pytraverse(item: DeriveInput) -> TokenStream {
result_to_tokens(pytraverse::impl_pytraverse(item))
}
+1 -2
View File
@@ -2014,9 +2014,8 @@ where
Err(wrong_name) => {
if ALL_ALLOWED_NAMES.contains(&attr_name.as_str()) {
bail_span!(attr, "#[pyclass] doesn't accept #[{}]", wrong_name)
} else {
continue;
}
continue;
}
};
+1 -2
View File
@@ -469,9 +469,8 @@ where
continue;
} else if closed {
bail_span!(attr, "Only one #[pyattr] annotated #[py*] item can exist")
} else {
bail_span!(attr, "#[pymodule] doesn't accept #[{}]", wrong_name)
}
bail_span!(attr, "#[pymodule] doesn't accept #[{}]", wrong_name)
}
};
+6 -9
View File
@@ -451,9 +451,8 @@ impl PyStructSequenceMeta {
inner.meta_ident,
"#[pystruct_sequence({KEY}=value)] expects a string value"
)
} else {
Ok(None)
}
Ok(None)
}
pub(crate) fn module(&self) -> Result<Option<String>> {
@@ -475,9 +474,8 @@ impl PyStructSequenceMeta {
inner.meta_ident,
"#[pystruct_sequence({KEY}=value)] expects a string value"
)
} else {
Ok(None)
}
Ok(None)
}
fn data_type(&self) -> Result<Ident> {
@@ -499,12 +497,11 @@ impl PyStructSequenceMeta {
inner.meta_ident,
"#[pystruct_sequence({KEY}=value)] expects a string value"
)
} else {
bail_span!(
inner.meta_ident,
"#[pystruct_sequence] requires data parameter (e.g., data = \"DataStructName\")"
)
}
bail_span!(
inner.meta_ident,
"#[pystruct_sequence] requires data parameter (e.g., data = \"DataStructName\")"
)
}
pub(crate) fn no_attr(&self) -> Result<bool> {
+7
View File
@@ -162,6 +162,7 @@ impl Owned {
///
/// `fd` must be a valid file descriptor.
#[inline]
#[must_use]
pub unsafe fn from_raw(fd: Raw) -> Self {
let inner = unsafe { OwnedInner::from_raw_fd(fd) };
Self { inner }
@@ -184,20 +185,24 @@ impl Owned {
}
#[inline]
#[must_use]
pub fn borrow(&self) -> Borrowed<'_> {
unsafe { Borrowed::borrow_raw(self.as_raw()) }
}
#[inline]
#[must_use]
pub fn as_raw(&self) -> Raw {
self.inner.as_raw_fd()
}
#[inline]
#[must_use]
pub fn into_raw(self) -> Raw {
self.inner.into_raw_fd()
}
#[must_use]
pub fn leak<'fd>(self) -> Borrowed<'fd> {
unsafe { Borrowed::borrow_raw(self.into_raw()) }
}
@@ -252,6 +257,7 @@ impl<'fd> Borrowed<'fd> {
///
/// `fd` must be a valid file descriptor.
#[inline]
#[must_use]
pub const unsafe fn borrow_raw(fd: Raw) -> Self {
let inner = unsafe { BorrowedInner::borrow_raw(fd) };
Self { inner }
@@ -274,6 +280,7 @@ impl<'fd> Borrowed<'fd> {
}
#[inline]
#[must_use]
pub fn as_raw(self) -> Raw {
self.inner.as_raw_fd()
}
+1
View File
@@ -352,6 +352,7 @@ pub mod windows {
}
}
#[must_use]
pub fn stat_basic_info_to_stat(info: &FILE_STAT_BASIC_INFORMATION) -> StatStruct {
use windows_sys::Win32::Storage::FileSystem;
use windows_sys::Win32::System::Ioctl;
+5
View File
@@ -29,10 +29,12 @@ pub fn setmode_binary(fd: crt_fd::Borrowed<'_>) {
unsafe { suppress_iph!(_setmode(fd, libc::O_BINARY)) };
}
#[must_use]
pub fn getch() -> Vec<u8> {
vec![unsafe { _getch() } as u8]
}
#[must_use]
pub fn getwch() -> String {
let value = unsafe { _getwch() };
char::from_u32(value)
@@ -40,10 +42,12 @@ pub fn getwch() -> String {
.to_string()
}
#[must_use]
pub fn getche() -> Vec<u8> {
vec![unsafe { _getche() } as u8]
}
#[must_use]
pub fn getwche() -> String {
let value = unsafe { _getwche() };
char::from_u32(value)
@@ -77,6 +81,7 @@ pub fn ungetwch(c: char) -> io::Result<()> {
}
}
#[must_use]
pub fn kbhit() -> i32 {
unsafe { _kbhit() }
}
+10
View File
@@ -14,6 +14,7 @@ use std::{
///
/// On Windows, this supports the full u32 range including STATUS_CONTROL_C_EXIT (0xC000013A).
/// On other platforms, only the lower 8 bits are used.
#[must_use]
pub fn exit_code(code: u32) -> ExitCode {
#[cfg(windows)]
{
@@ -32,6 +33,7 @@ pub fn current_dir() -> io::Result<PathBuf> {
env::current_dir()
}
#[must_use]
pub fn temp_dir() -> PathBuf {
env::temp_dir()
}
@@ -44,10 +46,12 @@ pub fn var_os(key: impl AsRef<OsStr>) -> Option<OsString> {
env::var_os(key)
}
#[must_use]
pub fn vars_os() -> env::VarsOs {
env::vars_os()
}
#[must_use]
pub fn vars() -> env::Vars {
env::vars()
}
@@ -70,6 +74,7 @@ pub fn set_current_dir(path: impl AsRef<std::path::Path>) -> io::Result<()> {
env::set_current_dir(path)
}
#[must_use]
pub fn process_id() -> u32 {
std::process::id()
}
@@ -97,6 +102,7 @@ impl ErrorExt for io::Error {
/// Get the last error from C runtime library functions (like _dup, _dup2, _fstat, etc.)
/// CRT functions set errno, not GetLastError(), so we need to read errno directly.
#[cfg(windows)]
#[must_use]
pub fn errno_io_error() -> io::Error {
let errno: i32 = get_errno();
let winerror = errno_to_winerror(errno);
@@ -104,6 +110,7 @@ pub fn errno_io_error() -> io::Error {
}
#[cfg(not(windows))]
#[must_use]
pub fn errno_io_error() -> io::Error {
std::io::Error::last_os_error()
}
@@ -119,6 +126,7 @@ pub fn get_errno() -> i32 {
}
#[cfg(not(windows))]
#[must_use]
pub fn get_errno() -> i32 {
std::io::Error::last_os_error().posix_errno()
}
@@ -206,6 +214,7 @@ pub mod ffi {
}
#[cfg(windows)]
#[must_use]
pub fn errno_to_winerror(errno: i32) -> i32 {
use libc::*;
use windows_sys::Win32::Foundation::*;
@@ -235,6 +244,7 @@ pub fn errno_to_winerror(errno: i32) -> i32 {
// winerror: https://learn.microsoft.com/windows/win32/debug/system-error-codes--0-499-
// errno: https://learn.microsoft.com/cpp/c-runtime-library/errno-constants?view=msvc-170
#[cfg(windows)]
#[must_use]
pub fn winerror_to_errno(winerror: i32) -> i32 {
use libc::*;
use windows_sys::Win32::{
+3
View File
@@ -13,6 +13,7 @@ pub fn set_inheritable(fd: BorrowedFd<'_>, inheritable: bool) -> nix::Result<()>
}
#[cfg(target_os = "macos")]
#[must_use]
pub fn get_number_of_os_threads() -> isize {
type MachPortT = libc::c_uint;
type KernReturnT = libc::c_int;
@@ -60,6 +61,7 @@ pub fn get_number_of_os_threads() -> isize {
}
#[cfg(target_os = "linux")]
#[must_use]
pub fn get_number_of_os_threads() -> isize {
use std::io::Read as _;
@@ -83,6 +85,7 @@ pub fn get_number_of_os_threads() -> isize {
}
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
#[must_use]
pub fn get_number_of_os_threads() -> isize {
0
}
+2
View File
@@ -119,6 +119,7 @@ pub use platform::{RawFd, timeval};
pub struct FdSet(MaybeUninit<platform::fd_set>);
impl FdSet {
#[must_use]
pub fn new() -> Self {
let mut fdset = MaybeUninit::zeroed();
unsafe { platform::FD_ZERO(fdset.as_mut_ptr()) };
@@ -177,6 +178,7 @@ pub fn select(
}
}
#[must_use]
pub fn sec_to_timeval(sec: f64) -> timeval {
timeval {
tv_sec: sec.trunc() as _,
+3
View File
@@ -1,7 +1,9 @@
#[must_use]
pub fn timeval_to_double(tv: &libc::timeval) -> f64 {
tv.tv_sec as f64 + (tv.tv_usec as f64 / 1_000_000.0)
}
#[must_use]
pub fn double_to_timeval(val: f64) -> libc::timeval {
libc::timeval {
tv_sec: val.trunc() as _,
@@ -9,6 +11,7 @@ pub fn double_to_timeval(val: f64) -> libc::timeval {
}
}
#[must_use]
pub fn itimerval_to_tuple(it: &libc::itimerval) -> (f64, f64) {
(
timeval_to_double(&it.it_value),
+4
View File
@@ -25,6 +25,7 @@ fn global_ident() -> &'static RwLock<Option<GlobalIdent>> {
IDENT.get_or_init(|| RwLock::new(None))
}
#[must_use]
pub fn is_open() -> bool {
global_ident()
.read()
@@ -55,14 +56,17 @@ pub fn closelog() {
}
}
#[must_use]
pub fn setlogmask(maskpri: i32) -> i32 {
unsafe { libc::setlogmask(maskpri) }
}
#[must_use]
pub const fn log_mask(pri: i32) -> i32 {
pri << 1
}
#[must_use]
pub const fn log_upto(pri: i32) -> i32 {
(1 << (pri + 1)) - 1
}
+2
View File
@@ -16,6 +16,7 @@ pub fn duration_since_system_now() -> Result<Duration, SystemTimeError> {
#[cfg(target_env = "msvc")]
#[cfg(not(target_arch = "wasm32"))]
#[must_use]
pub fn get_tz_info() -> windows_sys::Win32::System::Time::TIME_ZONE_INFORMATION {
let mut info = unsafe { core::mem::zeroed() };
unsafe { windows_sys::Win32::System::Time::GetTimeZoneInformation(&mut info) };
@@ -23,6 +24,7 @@ pub fn get_tz_info() -> windows_sys::Win32::System::Time::TIME_ZONE_INFORMATION
}
#[cfg(any(unix, windows))]
#[must_use]
pub fn asctime_from_tm(tm: &libc::tm) -> String {
const WDAY_NAME: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const MON_NAME: [&str; 12] = [
+4
View File
@@ -1,17 +1,21 @@
use windows_sys::Win32::Foundation::HANDLE;
#[must_use]
pub fn get_acp() -> u32 {
unsafe { windows_sys::Win32::Globalization::GetACP() }
}
#[must_use]
pub fn get_current_process() -> HANDLE {
unsafe { windows_sys::Win32::System::Threading::GetCurrentProcess() }
}
#[must_use]
pub fn get_last_error() -> u32 {
unsafe { windows_sys::Win32::Foundation::GetLastError() }
}
#[must_use]
pub fn get_version() -> u32 {
unsafe { windows_sys::Win32::System::SystemInformation::GetVersion() }
}
+6 -2
View File
@@ -335,8 +335,9 @@ pub struct ArgsBuilder<'a> {
}
impl<'a> ArgsBuilder<'a> {
fn new(code: &'a CompiledCode) -> ArgsBuilder<'a> {
ArgsBuilder {
#[must_use]
fn new(code: &'a CompiledCode) -> Self {
Self {
values: vec![None; code.sig.args.len()],
code,
}
@@ -348,10 +349,12 @@ impl<'a> ArgsBuilder<'a> {
})
}
#[must_use]
pub fn is_set(&self, idx: usize) -> bool {
self.values[idx].is_some()
}
#[must_use]
pub fn into_args(self) -> Option<Args<'a>> {
// Ensure all values are set
if self.values.iter().any(|v| v.is_none()) {
@@ -370,6 +373,7 @@ pub struct Args<'a> {
}
impl Args<'_> {
#[must_use]
pub fn invoke(&self) -> Option<AbiValue> {
let cif_args: Vec<_> = self.values.iter().map(AbiValue::to_libffi_arg).collect();
unsafe { self.code.invoke_raw(&cif_args) }
+8 -8
View File
@@ -60,6 +60,7 @@ impl Default for Marks {
}
impl Marks {
#[must_use]
pub fn get(&self, group_index: usize) -> (Optioned<usize>, Optioned<usize>) {
let marks_index = 2 * group_index;
if marks_index + 1 < self.marks.len() {
@@ -69,10 +70,12 @@ impl Marks {
}
}
#[must_use]
pub const fn last_index(&self) -> isize {
self.last_index
}
#[must_use]
pub fn raw(&self) -> &[Optioned<usize>] {
self.marks.as_slice()
}
@@ -191,9 +194,8 @@ impl State {
if flags.contains(SreInfo::PREFIX) {
if flags.contains(SreInfo::LITERAL) {
return search_info_literal::<true, S>(&mut req, self, ctx);
} else {
return search_info_literal::<false, S>(&mut req, self, ctx);
}
return search_info_literal::<false, S>(&mut req, self, ctx);
} else if flags.contains(SreInfo::CHARSET) {
return search_info_charset(&mut req, self, ctx);
}
@@ -432,10 +434,9 @@ fn _match<S: StrDrive>(req: &Request<'_, S>, state: &mut State, mut ctx: MatchCo
if max_count == MAXREPEAT || ctx.count as usize <= max_count {
state.cursor = ctx.cursor;
break 'context ctx.next_peek_from(1, req, Jump::MinRepeatOne2);
} else {
state.marks.pop_discard();
break 'result false;
}
state.marks.pop_discard();
break 'result false;
}
Jump::MinRepeatOne2 => {
if popped_result {
@@ -485,10 +486,9 @@ fn _match<S: StrDrive>(req: &Request<'_, S>, state: &mut State, mut ctx: MatchCo
ctx.count += 1;
ctx.jump = Jump::PossessiveRepeat1;
continue 'context;
} else {
state.cursor = ctx.cursor;
break 'result false;
}
state.cursor = ctx.cursor;
break 'result false;
}
Jump::PossessiveRepeat3 => {
let max_count = ctx.peek_code(req, 3) as usize;
+3
View File
@@ -372,6 +372,7 @@ pub(crate) const fn is_linebreak(ch: u32) -> bool {
ch == '\n' as u32
}
#[inline]
#[must_use]
pub fn lower_ascii(ch: u32) -> u32 {
u8::try_from(ch)
.map(|x| x.to_ascii_lowercase() as u32)
@@ -456,6 +457,7 @@ pub(crate) fn is_uni_word(ch: u32) -> bool {
ch == '_' as u32 || is_uni_alnum(ch)
}
#[inline]
#[must_use]
pub fn lower_unicode(ch: u32) -> u32 {
// TODO: check with cpython
char::try_from(ch)
@@ -463,6 +465,7 @@ pub fn lower_unicode(ch: u32) -> u32 {
.unwrap_or(ch)
}
#[inline]
#[must_use]
pub fn upper_unicode(ch: u32) -> u32 {
// TODO: check with cpython
char::try_from(ch)
+5 -3
View File
@@ -457,7 +457,7 @@ mod _sqlite3 {
let db = context.db_handle();
let args = args
.iter()
.cloned()
.copied()
.map(|val| value_to_object(val, db, vm))
.collect::<PyResult<Vec<PyObjectRef>>>()?;
@@ -654,7 +654,7 @@ mod _sqlite3 {
let db = context.db_handle();
let args = args
.iter()
.cloned()
.copied()
.map(|val| value_to_object(val, db, vm))
.collect::<PyResult<Vec<PyObjectRef>>>()?;
vm.call_method(instance, name, args).map(drop)
@@ -680,7 +680,9 @@ mod _sqlite3 {
impl Drop for CallbackData {
fn drop(&mut self) {
unsafe { PyObjectRef::from_raw(self.obj) };
unsafe {
let _ = PyObjectRef::from_raw(self.obj);
};
}
}
+2 -3
View File
@@ -162,10 +162,9 @@ pub(crate) fn _decompress_chunks<D: Decompressor>(
} else if !chunk.is_empty() && consumed == 0 {
// we're gonna need a bigger buffer
continue;
} else {
// next chunk
continue 'outer;
}
// next chunk
continue 'outer;
}
Err(e) => {
d.maybe_set_dict(e)?;
+1 -1
View File
@@ -1012,7 +1012,7 @@ mod decl {
pub(super) fn get_user_signal(signum: usize) -> Option<UserSignal> {
let guard = USER_SIGNALS.lock();
guard.as_ref().and_then(|v| v.get(signum).cloned())
guard.as_ref().and_then(|v| v.get(signum).copied())
}
pub(super) fn set_user_signal(signum: usize, signal: UserSignal) {
+1 -1
View File
@@ -47,7 +47,7 @@ mod decl {
#[cfg(unix)]
{
use crate::vm::class::PyClassImpl;
poll::PyPoll::make_static_type();
let _ = poll::PyPoll::make_static_type();
}
__module_exec(vm, module);
+2 -3
View File
@@ -818,10 +818,9 @@ impl<'a> CertLoader<'a> {
return Err(cert_error::der::not_enough_data(
"cadata does not contain a certificate",
));
} else {
// Loaded some certificates but failed on subsequent data (garbage)
return Err(cert_error::der::parse_failed(e));
}
// Loaded some certificates but failed on subsequent data (garbage)
return Err(cert_error::der::parse_failed(e));
}
}
}
+20 -22
View File
@@ -2018,30 +2018,28 @@ fn ssl_read_tls_records(
if is_bio {
// In BIO mode, no data means WANT_READ
return Err(SslError::WantRead);
} else {
// In socket mode, empty recv() means TCP EOF (FIN received)
// Need to distinguish:
// 1. Clean shutdown: received TLS close_notify → return ZeroReturn (0 bytes)
// 2. Unexpected EOF: no close_notify → return Eof (SSLEOFError)
//
// SSL_ERROR_ZERO_RETURN vs SSL_ERROR_EOF logic
// CPython checks SSL_get_shutdown() & SSL_RECEIVED_SHUTDOWN
//
// Process any buffered TLS records (may contain close_notify)
match conn.process_new_packets() {
Ok(io_state) => {
if io_state.peer_has_closed() {
// Received close_notify - normal SSL closure (SSL_ERROR_ZERO_RETURN)
return Err(SslError::ZeroReturn);
} else {
// No close_notify - ragged EOF (SSL_ERROR_EOF → SSLEOFError)
// CPython raises SSLEOFError here, which SSLSocket.read() handles
// based on suppress_ragged_eofs setting
return Err(SslError::Eof);
}
}
// In socket mode, empty recv() means TCP EOF (FIN received)
// Need to distinguish:
// 1. Clean shutdown: received TLS close_notify → return ZeroReturn (0 bytes)
// 2. Unexpected EOF: no close_notify → return Eof (SSLEOFError)
//
// SSL_ERROR_ZERO_RETURN vs SSL_ERROR_EOF logic
// CPython checks SSL_get_shutdown() & SSL_RECEIVED_SHUTDOWN
//
// Process any buffered TLS records (may contain close_notify)
match conn.process_new_packets() {
Ok(io_state) => {
if io_state.peer_has_closed() {
// Received close_notify - normal SSL closure (SSL_ERROR_ZERO_RETURN)
return Err(SslError::ZeroReturn);
}
Err(e) => return Err(SslError::from_rustls(e)),
// No close_notify - ragged EOF (SSL_ERROR_EOF → SSLEOFError)
// CPython raises SSLEOFError here, which SSLSocket.read() handles
// based on suppress_ragged_eofs setting
return Err(SslError::Eof);
}
Err(e) => return Err(SslError::from_rustls(e)),
}
}
+1
View File
@@ -523,6 +523,7 @@ impl FormatSpec {
}
#[inline]
#[must_use]
pub const fn size(&self) -> usize {
self.size
}
+1
View File
@@ -49,6 +49,7 @@ impl PyAsyncGen {
&self.inner
}
#[must_use]
pub fn new(frame: FrameRef, name: PyStrRef, qualname: PyStrRef) -> Self {
Self {
inner: Coro::new(frame, name, qualname),
+3
View File
@@ -205,16 +205,19 @@ impl PyRef<PyBytes> {
)]
impl PyBytes {
#[inline]
#[must_use]
pub const fn __len__(&self) -> usize {
self.inner.len()
}
#[inline]
#[must_use]
pub const fn is_empty(&self) -> bool {
self.inner.is_empty()
}
#[inline]
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
self.inner.as_bytes()
}
+2
View File
@@ -272,10 +272,12 @@ impl PyComplex {
Self::from(value).into_ref(ctx)
}
#[must_use]
pub const fn to_complex64(self) -> Complex64 {
self.value
}
#[must_use]
pub const fn to_complex(&self) -> Complex64 {
self.value
}
+1
View File
@@ -40,6 +40,7 @@ impl PyCoroutine {
&self.inner
}
#[must_use]
pub fn new(frame: FrameRef, name: PyStrRef, qualname: PyStrRef) -> Self {
Self {
inner: Coro::new(frame, name, qualname),
+1
View File
@@ -29,6 +29,7 @@ pub struct PyFloat {
}
impl PyFloat {
#[must_use]
pub const fn to_f64(&self) -> f64 {
self.value
}
+1
View File
@@ -1261,6 +1261,7 @@ impl Constructor for PyBoundMethod {
}
impl PyBoundMethod {
#[must_use]
pub const fn new(object: PyObjectRef, function: PyObjectRef) -> Self {
Self { object, function }
}
+1
View File
@@ -42,6 +42,7 @@ impl PyGenerator {
&self.inner
}
#[must_use]
pub fn new(frame: FrameRef, name: PyStrRef, qualname: PyStrRef) -> Self {
Self {
inner: Coro::new(frame, name, qualname),
+3
View File
@@ -303,12 +303,14 @@ impl PyInt {
}
}
#[must_use]
pub const fn as_bigint(&self) -> &BigInt {
&self.value
}
/// Fast decimal string conversion, using i64 path when possible.
#[inline]
#[must_use]
pub fn to_str_radix_10(&self) -> String {
match self.value.to_i64() {
Some(i) => i.to_string(),
@@ -317,6 +319,7 @@ impl PyInt {
}
// _PyLong_AsUnsignedLongMask
#[must_use]
pub fn as_u32_mask(&self) -> u32 {
let v = self.as_bigint();
v.to_u32()
+1
View File
@@ -239,6 +239,7 @@ impl PyPayload for PyCallableIterator {
#[pyclass(with(IterNext, Iterable))]
impl PyCallableIterator {
#[must_use]
pub const fn new(callable: ArgCallable, sentinel: PyObjectRef) -> Self {
Self {
sentinel,
+2
View File
@@ -113,6 +113,7 @@ pub struct ModuleInitArgs {
impl PyModule {
#[allow(clippy::new_without_default)]
#[must_use]
pub const fn new() -> Self {
Self {
def: None,
@@ -120,6 +121,7 @@ impl PyModule {
}
}
#[must_use]
pub const fn from_def(def: &'static PyModuleDef) -> Self {
Self {
def: Some(def),
+4
View File
@@ -128,6 +128,7 @@ impl PyRange {
}
#[inline]
#[must_use]
pub fn index_of(&self, value: &BigInt) -> Option<BigInt> {
let step = self.step.as_bigint();
match self.offset(value) {
@@ -137,16 +138,19 @@ impl PyRange {
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.compute_length().is_zero()
}
#[inline]
#[must_use]
pub fn forward(&self) -> bool {
self.start.as_bigint() < self.stop.as_bigint()
}
#[inline]
#[must_use]
pub fn get(&self, index: &BigInt) -> Option<BigInt> {
let start = self.start.as_bigint();
let step = self.step.as_bigint();
+1
View File
@@ -46,6 +46,7 @@ impl PySet {
Self::default().into_ref(ctx)
}
#[must_use]
pub fn elements(&self) -> Vec<PyObjectRef> {
self.inner.elements()
}
+1
View File
@@ -62,6 +62,7 @@ impl Constructor for PyStaticMethod {
}
impl PyStaticMethod {
#[must_use]
pub fn new(callable: PyObjectRef) -> Self {
Self {
callable: PyMutex::new(callable),
+3
View File
@@ -456,6 +456,7 @@ impl PyStr {
/// # Safety
/// Given `bytes` must be ascii
#[must_use]
pub unsafe fn new_ascii_unchecked(bytes: Vec<u8>) -> Self {
unsafe { AsciiString::from_ascii_unchecked(bytes) }.into()
}
@@ -1533,6 +1534,7 @@ impl PyStr {
}
impl PyRef<PyStr> {
#[must_use]
pub fn is_empty(&self) -> bool {
(**self).is_empty()
}
@@ -2221,6 +2223,7 @@ impl Py<PyUtf8Str> {
impl PyRef<PyUtf8Str> {
/// Convert to PyStrRef. Safe because PyUtf8Str is a subtype of PyStr.
#[must_use]
pub fn into_wtf8(self) -> PyStrRef {
unsafe { mem::transmute::<Self, PyStrRef>(self) }
}
+1
View File
@@ -34,6 +34,7 @@ impl PyPayload for PyTemplate {
}
impl PyTemplate {
#[must_use]
pub fn new(strings: PyTupleRef, interpolations: PyTupleRef) -> Self {
Self {
strings,
+1
View File
@@ -28,6 +28,7 @@ impl PyPayload for PyTraceback {
#[pyclass(with(Constructor))]
impl PyTraceback {
#[must_use]
pub const fn new(
next: Option<PyRef<Self>>,
frame: FrameRef,
+6
View File
@@ -291,16 +291,19 @@ impl<'a, R> core::iter::IntoIterator for &'a Py<PyTuple<R>> {
}
impl<R> PyTuple<R> {
#[must_use]
pub const fn as_slice(&self) -> &[R] {
&self.elements
}
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.elements.len()
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
@@ -325,6 +328,7 @@ impl PyTuple<PyObjectRef> {
/// Creating a new tuple with given boxed slice.
/// NOTE: for usual case, you probably want to use PyTuple::new_ref.
/// Calling this function implies trying micro optimization for non-zero-sized tuple.
#[must_use]
pub const fn new_unchecked(elements: Box<[PyObjectRef]>) -> Self {
Self { elements }
}
@@ -402,6 +406,7 @@ impl PyTuple {
}
#[inline]
#[must_use]
pub const fn __len__(&self) -> usize {
self.elements.len()
}
@@ -608,6 +613,7 @@ impl PyRef<PyTuple<PyObjectRef>> {
}
impl<T: PyPayload> PyRef<PyTuple<PyRef<T>>> {
#[must_use]
pub fn into_untyped(self) -> PyRef<PyTuple> {
// SAFETY: PyTuple<PyRef<T>> has the same layout as PyTuple
unsafe { core::mem::transmute::<Self, PyRef<PyTuple>>(self) }
+1
View File
@@ -53,6 +53,7 @@ impl PyUnion {
/// Direct access to args field (_Py_union_args)
#[inline]
#[must_use]
pub fn args(&self) -> &Py<PyTuple> {
&self.args
}
+7
View File
@@ -67,14 +67,17 @@ pub trait StaticType {
// Ideally, saving PyType is better than PyTypeRef
fn static_cell() -> &'static static_cell::StaticCell<PyTypeRef>;
#[inline]
#[must_use]
fn static_metaclass() -> &'static Py<PyType> {
PyType::static_type()
}
#[inline]
#[must_use]
fn static_baseclass() -> &'static Py<PyType> {
PyBaseObject::static_type()
}
#[inline]
#[must_use]
fn static_type() -> &'static Py<PyType> {
#[cold]
fn fail() -> ! {
@@ -84,12 +87,14 @@ pub trait StaticType {
}
Self::static_cell().get().unwrap_or_else(|| fail())
}
#[must_use]
fn init_manually(typ: PyTypeRef) -> &'static Py<PyType> {
let cell = Self::static_cell();
cell.set(typ)
.unwrap_or_else(|_| panic!("double initialization from init_manually"));
cell.get().unwrap()
}
#[must_use]
fn init_builtin_type() -> &'static Py<PyType>
where
Self: PyClassImpl,
@@ -100,6 +105,7 @@ pub trait StaticType {
.unwrap_or_else(|_| panic!("double initialization of {}", Self::NAME));
cell.get().unwrap()
}
#[must_use]
fn create_static_type() -> PyTypeRef
where
Self: PyClassImpl,
@@ -206,6 +212,7 @@ pub trait PyClassImpl: PyClassDef {
class.extend_methods(class.slots.methods, ctx);
}
#[must_use]
fn make_static_type() -> PyTypeRef
where
Self: StaticType + Sized,
+2
View File
@@ -59,6 +59,7 @@ pub struct DataStack {
impl DataStack {
/// Create a new data stack with an initial root chunk.
#[must_use]
pub fn new() -> Self {
let chunk = Self::alloc_chunk(MIN_CHUNK_SIZE, ptr::null_mut());
let top = unsafe { (*chunk).data_start() };
@@ -71,6 +72,7 @@ impl DataStack {
/// Check if the current chunk has at least `size` bytes available.
#[inline(always)]
#[must_use]
pub fn has_space(&self, size: usize) -> bool {
let aligned_size = (size + ALIGN - 1) & !(ALIGN - 1);
(self.limit as usize).saturating_sub(self.top as usize) >= aligned_size
+1
View File
@@ -34,6 +34,7 @@ fn create_exception_group(ctx: &Context) -> PyRef<PyType> {
.expect("Failed to create ExceptionGroup type with multiple inheritance")
}
#[must_use]
pub fn exception_group() -> &'static Py<PyType> {
::rustpython_vm::common::static_cell! {
static CELL: ::rustpython_vm::builtins::PyTypeRef;
+10
View File
@@ -139,6 +139,7 @@ impl FuncArgs {
/// `args[..nargs]` are positional, and if `kwnames` is provided,
/// the last `kwnames.len()` entries in `args[nargs..]` are keyword values.
/// Convert borrowed vectorcall args to FuncArgs (clones all values).
#[must_use]
pub fn from_vectorcall(
args: &[PyObjectRef],
nargs: usize,
@@ -170,6 +171,7 @@ impl FuncArgs {
}
/// Convert owned vectorcall args to FuncArgs (moves values, no clone).
#[must_use]
pub fn from_vectorcall_owned(
mut args: Vec<PyObjectRef>,
nargs: usize,
@@ -198,6 +200,7 @@ impl FuncArgs {
Self { args, kwargs }
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.args.is_empty() && self.kwargs.is_empty()
}
@@ -211,6 +214,7 @@ impl FuncArgs {
self.args.remove(0)
}
#[must_use]
pub fn get_kwarg(&self, key: &str, default: PyObjectRef) -> PyObjectRef {
self.kwargs
.get(key)
@@ -218,6 +222,7 @@ impl FuncArgs {
.unwrap_or_else(|| default.clone())
}
#[must_use]
pub fn get_optional_kwarg(&self, key: &str) -> Option<PyObjectRef> {
self.kwargs.get(key).cloned()
}
@@ -357,6 +362,7 @@ pub trait FromArgs: Sized {
/// The range of positional arguments permitted by the function signature.
///
/// Returns an empty range if not applicable.
#[must_use]
fn arity() -> RangeInclusive<usize> {
0..=0
}
@@ -411,6 +417,7 @@ where
}
impl<T> KwArgs<T> {
#[must_use]
pub const fn new(map: IndexMap<String, T>) -> Self {
Self(map)
}
@@ -419,6 +426,7 @@ impl<T> KwArgs<T> {
self.0.swap_remove(name)
}
#[must_use]
pub fn is_empty(self) -> bool {
self.0.is_empty()
}
@@ -479,10 +487,12 @@ where
}
impl<T> PosArgs<T> {
#[must_use]
pub const fn new(args: Vec<T>) -> Self {
Self(args)
}
#[must_use]
pub fn into_vec(self) -> Vec<T> {
self.0
}
+11
View File
@@ -39,6 +39,7 @@ impl PyObject {
}
impl ArgBytesLike {
#[must_use]
pub fn borrow_buf(&self) -> BorrowedValue<'_, [u8]> {
unsafe { self.0.contiguous_unchecked() }
}
@@ -50,14 +51,17 @@ impl ArgBytesLike {
f(&self.borrow_buf())
}
#[must_use]
pub const fn len(&self) -> usize {
self.0.desc.len
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
#[must_use]
pub fn as_object(&self) -> &PyObject {
&self.0.obj
}
@@ -91,6 +95,7 @@ impl<'a> TryFromBorrowedObject<'a> for ArgBytesLike {
pub struct ArgMemoryBuffer(PyBuffer);
impl ArgMemoryBuffer {
#[must_use]
pub fn borrow_buf_mut(&self) -> BorrowedValueMut<'_, [u8]> {
unsafe { self.0.contiguous_mut_unchecked() }
}
@@ -102,10 +107,12 @@ impl ArgMemoryBuffer {
f(&mut self.borrow_buf_mut())
}
#[must_use]
pub const fn len(&self) -> usize {
self.0.desc.len
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
@@ -137,6 +144,7 @@ pub enum ArgStrOrBytesLike {
}
impl ArgStrOrBytesLike {
#[must_use]
pub fn as_object(&self) -> &PyObject {
match self {
Self::Buf(b) => b.as_object(),
@@ -154,6 +162,7 @@ impl TryFromObject for ArgStrOrBytesLike {
}
impl ArgStrOrBytesLike {
#[must_use]
pub fn borrow_bytes(&self) -> BorrowedValue<'_, [u8]> {
match self {
Self::Buf(b) => b.borrow_buf(),
@@ -184,6 +193,7 @@ impl TryFromObject for ArgAsciiBuffer {
}
impl ArgAsciiBuffer {
#[must_use]
pub fn len(&self) -> usize {
match self {
Self::String(s) => s.as_wtf8().len(),
@@ -191,6 +201,7 @@ impl ArgAsciiBuffer {
}
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
+2
View File
@@ -89,6 +89,7 @@ impl FsPath {
}
}
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
// TODO: FS encodings
match self {
@@ -97,6 +98,7 @@ impl FsPath {
}
}
#[must_use]
pub fn to_string_lossy(&self) -> Cow<'_, str> {
match self {
Self::Str(s) => s.to_string_lossy(),
+3
View File
@@ -118,6 +118,7 @@ impl PyMethodDef {
}
}
#[must_use]
pub const fn to_function(&'static self) -> PyNativeFunction {
PyNativeFunction {
zelf: None,
@@ -226,6 +227,7 @@ impl PyMethodDef {
}
#[doc(hidden)]
#[must_use]
pub const fn __const_concat_arrays<const SUM_LEN: usize>(
method_groups: &[&[Self]],
) -> [Self; SUM_LEN] {
@@ -286,6 +288,7 @@ pub struct HeapMethodDef {
}
impl HeapMethodDef {
#[must_use]
pub const fn new(method: PyMethodDef) -> Self {
Self { method }
}
+5
View File
@@ -22,6 +22,7 @@ pub struct ArgIntoComplex {
impl ArgIntoComplex {
#[inline]
#[must_use]
pub fn into_complex(self) -> Complex64 {
self.value
}
@@ -60,10 +61,12 @@ pub struct ArgIntoFloat {
impl ArgIntoFloat {
#[inline]
#[must_use]
pub fn into_float(self) -> f64 {
self.value
}
#[must_use]
pub fn vec_into_f64(v: Vec<Self>) -> Vec<f64> {
// TODO: Vec::into_raw_parts once stabilized
let mut v = core::mem::ManuallyDrop::new(v);
@@ -105,6 +108,7 @@ impl ArgIntoBool {
pub const FALSE: Self = Self { value: false };
#[inline]
#[must_use]
pub fn into_bool(self) -> bool {
self.value
}
@@ -133,6 +137,7 @@ pub struct ArgIndex {
impl ArgIndex {
#[inline]
#[must_use]
pub fn into_int_ref(self) -> PyIntRef {
self.value
}
+6
View File
@@ -124,21 +124,25 @@ pub struct ArgMapping {
impl ArgMapping {
#[inline]
#[must_use]
pub const fn new(obj: PyObjectRef) -> Self {
Self { obj }
}
#[inline(always)]
#[must_use]
pub fn from_dict_exact(dict: PyDictRef) -> Self {
Self { obj: dict.into() }
}
#[inline(always)]
#[must_use]
pub fn obj(&self) -> &PyObject {
&self.obj
}
#[inline(always)]
#[must_use]
pub fn mapping(&self) -> PyMapping<'_> {
self.obj.mapping_unchecked()
}
@@ -191,10 +195,12 @@ unsafe impl<T: Traverse> Traverse for ArgSequence<T> {
impl<T> ArgSequence<T> {
#[inline(always)]
#[must_use]
pub fn into_vec(self) -> Vec<T> {
self.0
}
#[inline(always)]
#[must_use]
pub fn as_slice(&self) -> &[T] {
&self.0
}
+2
View File
@@ -10,11 +10,13 @@ pub struct TimeoutSeconds {
}
impl TimeoutSeconds {
#[must_use]
pub const fn new(secs: f64) -> Self {
Self { value: secs }
}
#[inline]
#[must_use]
pub fn to_secs_f64(self) -> f64 {
self.value
}
+2
View File
@@ -67,6 +67,7 @@ pub struct GcGeneration {
}
impl GcGeneration {
#[must_use]
pub const fn new(threshold: u32) -> Self {
Self {
count: AtomicUsize::new(0),
@@ -174,6 +175,7 @@ impl Default for GcState {
}
impl GcState {
#[must_use]
pub fn new() -> Self {
Self {
generations: [
+4 -6
View File
@@ -63,13 +63,12 @@ macro_rules! py_namespace {
///
/// # Examples
///
/// ```
/// ```rust
/// use malachite_bigint::ToBigInt;
/// use num_traits::Zero;
///
/// use rustpython_vm::match_class;
/// use rustpython_vm::{PyPayload, match_class};
/// use rustpython_vm::builtins::{PyFloat, PyInt};
/// use rustpython_vm::{PyPayload};
///
/// # rustpython_vm::Interpreter::without_stdlib(Default::default()).enter(|vm| {
/// let obj = PyInt::from(0).into_pyobject(vm);
@@ -87,13 +86,12 @@ macro_rules! py_namespace {
///
/// With a binding to the downcasted type:
///
/// ```
/// ```rust
/// use malachite_bigint::ToBigInt;
/// use num_traits::Zero;
///
/// use rustpython_vm::match_class;
/// use rustpython_vm::{PyPayload, match_class};
/// use rustpython_vm::builtins::{PyFloat, PyInt};
/// use rustpython_vm::{ PyPayload};
///
/// # rustpython_vm::Interpreter::without_stdlib(Default::default()).enter(|vm| {
/// let obj = PyInt::from(0).into_pyobject(vm);
+11
View File
@@ -1291,6 +1291,7 @@ impl PyObject {
impl PyObjectRef {
#[inline(always)]
#[must_use]
pub const fn into_raw(self) -> NonNull<PyObject> {
let ptr = self.ptr;
core::mem::forget(self);
@@ -1303,6 +1304,7 @@ impl PyObjectRef {
/// dropped more than once due to mishandling the reference count by calling this function
/// too many times.
#[inline(always)]
#[must_use]
pub const unsafe fn from_raw(ptr: NonNull<PyObject>) -> Self {
Self { ptr }
}
@@ -1330,6 +1332,7 @@ impl PyObjectRef {
/// # Safety
/// T must be the exact payload type
#[inline(always)]
#[must_use]
pub unsafe fn downcast_unchecked<T>(self) -> PyRef<T> {
// PyRef::from_obj_unchecked(self)
// manual impl to avoid assertion
@@ -1926,6 +1929,7 @@ impl PyStackRef {
/// Create an owned stack reference, consuming the `PyObjectRef`.
/// Refcount is NOT incremented — ownership is transferred.
#[inline(always)]
#[must_use]
pub fn new_owned(obj: PyObjectRef) -> Self {
let ptr = obj.into_raw();
let bits = ptr.as_ptr() as usize;
@@ -1957,12 +1961,14 @@ impl PyStackRef {
/// Whether this is a borrowed (non-owning) reference.
#[inline(always)]
#[must_use]
pub fn is_borrowed(&self) -> bool {
self.bits.get() & STACKREF_BORROW_TAG != 0
}
/// Get a `&PyObject` reference. Works for both owned and borrowed.
#[inline(always)]
#[must_use]
pub fn as_object(&self) -> &PyObject {
unsafe { &*((self.bits.get() & !STACKREF_BORROW_TAG) as *const PyObject) }
}
@@ -1972,6 +1978,7 @@ impl PyStackRef {
/// * If **borrowed** → increments refcount, forgets self.
/// * If **owned** → reconstructs `PyObjectRef` from the raw pointer, forgets self.
#[inline(always)]
#[must_use]
pub fn to_pyobj(self) -> PyObjectRef {
let obj = if self.is_borrowed() {
self.as_object().to_owned() // inc refcount
@@ -2213,6 +2220,7 @@ impl<T: PyPayload> PyRef<T> {
}
}
#[must_use]
pub const fn leak(pyref: Self) -> &'static Py<T> {
let ptr = pyref.ptr;
core::mem::forget(pyref);
@@ -2281,6 +2289,7 @@ where
/// # Safety
/// T and T::Base must have compatible layouts in size_of::<T::Base>() bytes.
#[inline]
#[must_use]
pub fn into_base(self) -> PyRef<T::Base> {
let obj: PyObjectRef = self.into();
match obj.downcast() {
@@ -2289,6 +2298,7 @@ where
}
}
#[inline]
#[must_use]
pub fn upcast<U: PyPayload + StaticType>(self) -> PyRef<U>
where
T: StaticType,
@@ -2404,6 +2414,7 @@ pub struct PyWeakRef<T: PyPayload> {
}
impl<T: PyPayload> PyWeakRef<T> {
#[must_use]
pub fn upgrade(&self) -> Option<PyRef<T>> {
self.weak
.upgrade()
+4
View File
@@ -142,10 +142,12 @@ pub struct PyRefExact<T: PyPayload> {
impl<T: PyPayload> PyRefExact<T> {
/// # Safety
/// obj must have exact type for the payload
#[must_use]
pub const unsafe fn new_unchecked(obj: PyRef<T>) -> Self {
Self { inner: obj }
}
#[must_use]
pub fn into_pyref(self) -> PyRef<T> {
self.inner
}
@@ -500,6 +502,7 @@ unsafe impl Send for PyAtomicBorrow {}
unsafe impl Sync for PyAtomicBorrow {}
impl PyAtomicBorrow {
#[must_use]
pub fn new() -> Self {
Self {
inner: Radium::new(null_mut()),
@@ -610,6 +613,7 @@ pub struct PyLease<'a, T: PyPayload> {
impl<T: PyPayload> PyLease<'_, T> {
#[inline(always)]
#[must_use]
pub fn into_owned(self) -> PyRef<T> {
self.inner.clone()
}
+8
View File
@@ -21,6 +21,7 @@ pub struct PathConverter {
}
impl PathConverter {
#[must_use]
pub const fn new() -> Self {
Self {
function_name: None,
@@ -29,16 +30,19 @@ impl PathConverter {
}
}
#[must_use]
pub const fn function(mut self, name: &'static str) -> Self {
self.function_name = Some(name);
self
}
#[must_use]
pub const fn argument(mut self, name: &'static str) -> Self {
self.argument_name = Some(name);
self
}
#[must_use]
pub const fn non_strict(mut self) -> Self {
self.non_strict = true;
self
@@ -235,14 +239,17 @@ impl OsPath {
Self::from_fspath(fspath, vm)
}
#[must_use]
pub fn as_path(&self) -> &Path {
Path::new(&self.path)
}
#[must_use]
pub fn into_bytes(self) -> Vec<u8> {
self.path.into_encoded_bytes()
}
#[must_use]
pub fn to_string_lossy(&self) -> alloc::borrow::Cow<'_, str> {
self.path.to_string_lossy()
}
@@ -266,6 +273,7 @@ impl OsPath {
}
/// Get the output mode based on origin type (bytes -> Bytes, otherwise -> String)
#[must_use]
pub fn mode(&self) -> OutputMode {
match &self.origin {
Some(obj) if obj.downcast_ref::<PyBytes>().is_some() => OutputMode::Bytes,
+23 -6
View File
@@ -42,6 +42,7 @@ pub struct PyBuffer {
}
impl PyBuffer {
#[must_use]
pub fn new(obj: PyObjectRef, desc: BufferDescriptor, methods: &'static BufferMethods) -> Self {
let zelf = Self {
obj,
@@ -52,12 +53,14 @@ impl PyBuffer {
zelf
}
#[must_use]
pub fn as_contiguous(&self) -> Option<BorrowedValue<'_, [u8]>> {
self.desc
.is_contiguous()
.then(|| unsafe { self.contiguous_unchecked() })
}
#[must_use]
pub fn as_contiguous_mut(&self) -> Option<BorrowedValueMut<'_, [u8]>> {
(!self.desc.readonly && self.desc.is_contiguous())
.then(|| unsafe { self.contiguous_mut_unchecked() })
@@ -74,12 +77,14 @@ impl PyBuffer {
/// # Safety
/// assume the buffer is contiguous
#[must_use]
pub unsafe fn contiguous_unchecked(&self) -> BorrowedValue<'_, [u8]> {
self.obj_bytes()
}
/// # Safety
/// assume the buffer is contiguous and writable
#[must_use]
pub unsafe fn contiguous_mut_unchecked(&self) -> BorrowedValueMut<'_, [u8]> {
self.obj_bytes_mut()
}
@@ -109,14 +114,17 @@ impl PyBuffer {
f(v)
}
#[must_use]
pub fn obj_as<T: PyObjectPayload>(&self) -> &Py<T> {
unsafe { self.obj.downcast_unchecked_ref() }
}
#[must_use]
pub fn obj_bytes(&self) -> BorrowedValue<'_, [u8]> {
(self.methods.obj_bytes)(self)
}
#[must_use]
pub fn obj_bytes_mut(&self) -> BorrowedValueMut<'_, [u8]> {
(self.methods.obj_bytes_mut)(self)
}
@@ -174,6 +182,7 @@ pub struct BufferDescriptor {
}
impl BufferDescriptor {
#[must_use]
pub fn simple(bytes_len: usize, readonly: bool) -> Self {
Self {
len: bytes_len,
@@ -184,6 +193,7 @@ impl BufferDescriptor {
}
}
#[must_use]
pub fn format(
bytes_len: usize,
readonly: bool,
@@ -200,6 +210,7 @@ impl BufferDescriptor {
}
#[cfg(debug_assertions)]
#[must_use]
pub fn validate(self) -> Self {
// ndim=0 is valid for scalar types (e.g., ctypes Structure)
if self.ndim() == 0 {
@@ -211,7 +222,7 @@ impl BufferDescriptor {
} else {
let mut shape_product = 1;
let has_zero_dim = self.dim_desc.iter().any(|(s, _, _)| *s == 0);
for (shape, stride, suboffset) in self.dim_desc.iter().cloned() {
for (shape, stride, suboffset) in self.dim_desc.iter().copied() {
shape_product *= shape;
assert!(suboffset >= 0);
// For empty arrays (any dimension is 0), strides can be 0
@@ -229,16 +240,18 @@ impl BufferDescriptor {
self
}
#[must_use]
pub fn ndim(&self) -> usize {
self.dim_desc.len()
}
#[must_use]
pub fn is_contiguous(&self) -> bool {
if self.len == 0 {
return true;
}
let mut sd = self.itemsize;
for (shape, stride, _) in self.dim_desc.iter().cloned().rev() {
for (shape, stride, _) in self.dim_desc.iter().copied().rev() {
if shape > 1 && stride != sd as isize {
return false;
}
@@ -249,12 +262,13 @@ impl BufferDescriptor {
/// this function do not check the bound
/// panic if indices.len() != ndim
#[must_use]
pub fn fast_position(&self, indices: &[usize]) -> isize {
let mut pos = 0;
for (i, (_, stride, suboffset)) in indices
.iter()
.cloned()
.zip_eq(self.dim_desc.iter().cloned())
.copied()
.zip_eq(self.dim_desc.iter().copied())
{
pos += i as isize * stride + suboffset;
}
@@ -266,8 +280,8 @@ impl BufferDescriptor {
let mut pos = 0;
for (i, (shape, stride, suboffset)) in indices
.iter()
.cloned()
.zip_eq(self.dim_desc.iter().cloned())
.copied()
.zip_eq(self.dim_desc.iter().copied())
{
let i = i.wrapped_at(shape).ok_or_else(|| {
vm.new_index_error(format!("index out of bounds on dimension {i}"))
@@ -387,6 +401,7 @@ impl BufferDescriptor {
suboffset == 0 && stride == self.itemsize as isize
}
#[must_use]
pub fn is_zero_in_shape(&self) -> bool {
self.dim_desc.iter().any(|(shape, _, _)| *shape == 0)
}
@@ -428,6 +443,7 @@ impl From<Vec<u8>> for VecBuffer {
}
impl PyRef<VecBuffer> {
#[must_use]
pub fn into_pybuffer(self, readonly: bool) -> PyBuffer {
let len = self.data.lock().len();
PyBuffer::new(
@@ -437,6 +453,7 @@ impl PyRef<VecBuffer> {
)
}
#[must_use]
pub fn into_pybuffer_with_descriptor(self, desc: BufferDescriptor) -> PyBuffer {
PyBuffer::new(self.into(), desc, &VEC_BUFFER_METHODS)
}
+2
View File
@@ -105,11 +105,13 @@ impl AsRef<PyObject> for PyMapping<'_> {
impl PyMapping<'_> {
#[inline]
#[must_use]
pub fn slots(&self) -> &PyMappingSlots {
&self.obj.class().slots.as_mapping
}
#[inline]
#[must_use]
pub fn check(&self) -> bool {
self.slots().has_subscript()
}
+2
View File
@@ -180,6 +180,7 @@ impl PyNumberMethods {
inplace_matrix_multiply: None,
};
#[must_use]
pub fn not_implemented() -> &'static Self {
static GLOBAL_NOT_IMPLEMENTED: PyNumberMethods = PyNumberMethods::NOT_IMPLEMENTED;
&GLOBAL_NOT_IMPLEMENTED
@@ -612,6 +613,7 @@ impl<'a> PyNumber<'a> {
impl PyNumber<'_> {
// PyIndex_Check
#[must_use]
pub fn is_index(self) -> bool {
self.class().slots.as_number.index.load().is_some()
}
+2
View File
@@ -131,10 +131,12 @@ unsafe impl Traverse for PySequence<'_> {
impl PySequence<'_> {
#[inline]
#[must_use]
pub fn slots(&self) -> &PySequenceSlots {
&self.obj.class().slots.as_sequence
}
#[must_use]
pub fn check(&self) -> bool {
self.slots().has_item()
}
+1
View File
@@ -16,6 +16,7 @@ impl fmt::Debug for Scope {
impl Scope {
#[inline]
#[must_use]
pub fn new(locals: Option<ArgMapping>, globals: PyDictRef) -> Self {
Self { locals, globals }
}
+1
View File
@@ -171,6 +171,7 @@ impl fmt::Display for UserSignalSendError {
}
}
#[must_use]
pub fn user_signal_channel() -> (UserSignalSender, UserSignalReceiver) {
let (tx, rx) = mpsc::channel();
(UserSignalSender { tx }, UserSignalReceiver { rx })
+5
View File
@@ -369,6 +369,7 @@ impl SaturatedSlice {
// Equivalent to PySlice_AdjustIndices
/// Convert for usage in indexing the underlying rust collections. Called *after*
/// __index__ has been called on the Slice which might mutate the collection.
#[must_use]
pub fn adjust_indices(&self, len: usize) -> (Range<usize>, isize, usize) {
if len == 0 {
return (0..0, self.step, 0);
@@ -398,6 +399,7 @@ impl SaturatedSlice {
(range, self.step, slice_len)
}
#[must_use]
pub fn iter(&self, len: usize) -> SaturatedSliceIter {
SaturatedSliceIter::new(self, len)
}
@@ -410,11 +412,13 @@ pub struct SaturatedSliceIter {
}
impl SaturatedSliceIter {
#[must_use]
pub fn new(slice: &SaturatedSlice, seq_len: usize) -> Self {
let (range, step, len) = slice.adjust_indices(seq_len);
Self::from_adjust_indices(range, step, len)
}
#[must_use]
pub const fn from_adjust_indices(range: Range<usize>, step: isize, len: usize) -> Self {
let index = if step.is_negative() {
range.end as isize - 1
@@ -424,6 +428,7 @@ impl SaturatedSliceIter {
Self { index, step, len }
}
#[must_use]
pub const fn positive_order(mut self) -> Self {
if self.step.is_negative() {
self.index += self.step * self.len.saturating_sub(1) as isize;
+7 -7
View File
@@ -1304,13 +1304,13 @@ pub(crate) mod _ctypes {
__module_exec(vm, module);
let ctx = &vm.ctx;
PyCSimpleType::make_static_type();
array::PyCArrayType::make_static_type();
pointer::PyCPointerType::make_static_type();
structure::PyCStructType::make_static_type();
union::PyCUnionType::make_static_type();
function::PyCFuncPtrType::make_static_type();
function::RawMemoryBuffer::make_static_type();
let _ = PyCSimpleType::make_static_type();
let _ = array::PyCArrayType::make_static_type();
let _ = pointer::PyCPointerType::make_static_type();
let _ = structure::PyCStructType::make_static_type();
let _ = union::PyCUnionType::make_static_type();
let _ = function::PyCFuncPtrType::make_static_type();
let _ = function::RawMemoryBuffer::make_static_type();
extend_module!(vm, module, {
"_CData" => PyCData::make_static_type(),
+1 -1
View File
@@ -66,7 +66,7 @@ mod _sre {
impl SreStr for &[u8] {
fn slice(&self, start: usize, end: usize, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx
.new_bytes(self.iter().take(end).skip(start).cloned().collect())
.new_bytes(self.iter().take(end).skip(start).copied().collect())
.into()
}
}
+1
View File
@@ -315,6 +315,7 @@ pub(crate) mod _thread {
/// Get thread identity - uses pthread_self() on Unix for fork compatibility
#[pyfunction]
#[must_use]
pub fn get_ident() -> u64 {
current_thread_id()
}
+1 -1
View File
@@ -1346,7 +1346,7 @@ mod builtins {
pub fn init_module(vm: &VirtualMachine, module: &Py<PyModule>) {
let ctx = &vm.ctx;
crate::protocol::VecBuffer::make_static_type();
let _ = crate::protocol::VecBuffer::make_static_type();
module.__init_methods(vm).unwrap();
builtins::module_exec(vm, module).unwrap();
+14
View File
@@ -37,6 +37,7 @@ impl TypeDataSlot {
}
/// Get a reference to the data if the type matches.
#[must_use]
pub fn get<T: Any + 'static>(&self) -> Option<&T> {
if self.type_id == TypeId::of::<T>() {
self.data.downcast_ref()
@@ -63,6 +64,7 @@ pub struct TypeDataRef<'a, T: 'static> {
impl<'a, T: Any + 'static> TypeDataRef<'a, T> {
/// Try to create a TypeDataRef from a read guard.
/// Returns None if the slot is empty or contains a different type.
#[must_use]
pub fn try_new(guard: PyRwLockReadGuard<'a, Option<TypeDataSlot>>) -> Option<Self> {
PyRwLockReadGuard::try_map(guard, |opt| opt.as_ref().and_then(|slot| slot.get::<T>()))
.ok()
@@ -86,6 +88,7 @@ pub struct TypeDataRefMut<'a, T: 'static> {
impl<'a, T: Any + 'static> TypeDataRefMut<'a, T> {
/// Try to create a TypeDataRefMut from a write guard.
/// Returns None if the slot is empty or contains a different type.
#[must_use]
pub fn try_new(guard: PyRwLockWriteGuard<'a, Option<TypeDataSlot>>) -> Option<Self> {
PyRwLockWriteGuard::try_map(guard, |opt| {
opt.as_mut().and_then(|slot| slot.get_mut::<T>())
@@ -188,6 +191,7 @@ pub struct PyTypeSlots {
}
impl PyTypeSlots {
#[must_use]
pub fn new(name: &'static str, flags: PyTypeFlags) -> Self {
Self {
name,
@@ -196,6 +200,7 @@ impl PyTypeSlots {
}
}
#[must_use]
pub fn heap_default() -> Self {
Self {
// init: AtomicCell::new(Some(init_wrapper)),
@@ -243,6 +248,7 @@ impl PyTypeFlags {
// CPython: See initialization of flags in type_new.
/// Used for types created in Python. Subclassable and are a
/// heaptype.
#[must_use]
pub const fn heap_type_flags() -> Self {
match Self::from_bits(Self::DEFAULT.bits() | Self::HEAPTYPE.bits() | Self::BASETYPE.bits())
{
@@ -251,11 +257,13 @@ impl PyTypeFlags {
}
}
#[must_use]
pub const fn has_feature(self, flag: Self) -> bool {
self.contains(flag)
}
#[cfg(debug_assertions)]
#[must_use]
pub const fn is_created_with_flags(self) -> bool {
self.contains(Self::_CREATED_WITH_FLAGS)
}
@@ -1862,6 +1870,7 @@ impl PyComparisonOp {
}
}
#[must_use]
pub fn eval_ord(self, ord: Ordering) -> bool {
match self {
Self::Lt => ord == Ordering::Less,
@@ -1873,6 +1882,7 @@ impl PyComparisonOp {
}
}
#[must_use]
pub const fn swapped(self) -> Self {
match self {
Self::Lt => Self::Gt,
@@ -1895,6 +1905,7 @@ impl PyComparisonOp {
}
}
#[must_use]
pub const fn operator_token(self) -> &'static str {
match self {
Self::Lt => "<",
@@ -1987,6 +1998,7 @@ pub trait AsMapping: PyPayload {
fn as_mapping() -> &'static PyMappingMethods;
#[inline]
#[must_use]
fn mapping_downcast(mapping: PyMapping<'_>) -> &Py<Self> {
unsafe { mapping.obj.downcast_unchecked_ref() }
}
@@ -2001,6 +2013,7 @@ pub trait AsSequence: PyPayload {
fn as_sequence() -> &'static PySequenceMethods;
#[inline]
#[must_use]
fn sequence_downcast(seq: PySequence<'_>) -> &Py<Self> {
unsafe { seq.obj.downcast_unchecked_ref() }
}
@@ -2025,6 +2038,7 @@ pub trait AsNumber: PyPayload {
}
#[inline]
#[must_use]
fn number_downcast(num: PyNumber<'_>) -> &Py<Self> {
unsafe { num.obj.downcast_unchecked_ref() }
}
+7
View File
@@ -28,6 +28,7 @@ pub enum SlotOp {
impl SlotOp {
/// Convert to PyComparisonOp if this is a comparison operation
#[must_use]
pub fn as_compare_op(&self) -> Option<PyComparisonOp> {
match self {
Self::Lt => Some(PyComparisonOp::Lt),
@@ -41,6 +42,7 @@ impl SlotOp {
}
/// Check if this is a right operation (__radd__, __rsub__, etc.)
#[must_use]
pub fn is_right(&self) -> bool {
matches!(self, Self::Right)
}
@@ -167,6 +169,7 @@ pub enum SlotAccessor {
impl SlotAccessor {
/// Check if this accessor is for a reserved/unused slot
#[must_use]
pub fn is_reserved(&self) -> bool {
matches!(
self,
@@ -195,6 +198,7 @@ impl SlotAccessor {
}
/// Check if this is a number binary operation slot
#[must_use]
pub fn is_number_binary(&self) -> bool {
matches!(
self,
@@ -223,6 +227,7 @@ impl SlotAccessor {
/// - TpDescrSet: __set__ and __delete__
/// - SqAssItem/MpAssSubscript: __setitem__ and __delitem__
/// - Number binaries: __add__ and __radd__, etc.
#[must_use]
pub fn is_shared_slot(&self) -> bool {
matches!(
self,
@@ -235,6 +240,7 @@ impl SlotAccessor {
}
/// Get underlying slot field name for debugging
#[must_use]
pub fn slot_name(&self) -> &'static str {
match self {
Self::BfGetBuffer => "bf_getbuffer",
@@ -322,6 +328,7 @@ impl SlotAccessor {
}
/// Extract the raw function pointer from a SlotFunc if it matches this accessor's type
#[must_use]
pub fn extract_from_slot_func(&self, slot_func: &SlotFunc) -> bool {
match self {
// Type slots
+11
View File
@@ -15,6 +15,7 @@ pub const SERIAL: usize = 0;
pub const VERSION_HEX: usize =
(MAJOR << 24) | (MINOR << 16) | (MICRO << 8) | (RELEASELEVEL_N << 4) | SERIAL;
#[must_use]
pub fn get_version() -> String {
// Windows: include MSC v. for compatibility with ctypes.util.find_library
// MSC v.1929 = VS 2019, version 14+ makes find_msvcrt() return None
@@ -42,16 +43,19 @@ pub fn get_version() -> String {
)
}
#[must_use]
pub fn get_version_number() -> String {
format!("{MAJOR}.{MINOR}.{MICRO}{RELEASELEVEL}")
}
#[must_use]
pub fn get_winver_number() -> String {
format!("{MAJOR}.{MINOR}")
}
const COMPILER: &str = env!("RUSTC_VERSION");
#[must_use]
pub fn get_build_info() -> String {
// See: https://reproducible-builds.org/docs/timestamps/
let git_revision = get_git_revision();
@@ -73,20 +77,24 @@ pub fn get_build_info() -> String {
)
}
#[must_use]
pub fn get_git_revision() -> String {
option_env!("RUSTPYTHON_GIT_HASH").unwrap_or("").to_owned()
}
#[must_use]
pub fn get_git_tag() -> String {
option_env!("RUSTPYTHON_GIT_TAG").unwrap_or("").to_owned()
}
#[must_use]
pub fn get_git_branch() -> String {
option_env!("RUSTPYTHON_GIT_BRANCH")
.unwrap_or("")
.to_owned()
}
#[must_use]
pub fn get_git_identifier() -> String {
let git_tag = get_git_tag();
let git_branch = get_git_branch();
@@ -109,18 +117,21 @@ fn get_git_timestamp_datetime() -> DateTime<Local> {
datetime.into()
}
#[must_use]
pub fn get_git_date() -> String {
let datetime = get_git_timestamp_datetime();
datetime.format("%b %e %Y").to_string()
}
#[must_use]
pub fn get_git_time() -> String {
let datetime = get_git_timestamp_datetime();
datetime.format("%H:%M:%S").to_string()
}
#[must_use]
pub fn get_git_datetime() -> String {
let date = get_git_date();
let time = get_git_time();
+1
View File
@@ -288,6 +288,7 @@ impl Context {
pub const INT_CACHE_POOL_RANGE: core::ops::RangeInclusive<i32> = (-5)..=256;
const INT_CACHE_POOL_MIN: i32 = *Self::INT_CACHE_POOL_RANGE.start();
#[must_use]
pub fn genesis() -> &'static PyRc<Self> {
rustpython_common::static_cell! {
static CONTEXT: PyRc<Context>;
+8
View File
@@ -155,6 +155,7 @@ where
impl InterpreterBuilder {
/// Create a new interpreter configuration with default settings.
#[must_use]
pub fn new() -> Self {
Self {
settings: Settings::default(),
@@ -168,6 +169,7 @@ impl InterpreterBuilder {
/// Set custom settings for the interpreter.
///
/// If called multiple times, only the last settings will be used.
#[must_use]
pub fn settings(mut self, settings: Settings) -> Self {
self.settings = settings;
self
@@ -185,6 +187,7 @@ impl InterpreterBuilder {
/// // let interp = builder.add_native_module(def).build();
/// let interp = builder.build();
/// ```
#[must_use]
pub fn add_native_module(self, def: &'static builtins::PyModuleDef) -> Self {
self.add_native_modules(&[def])
}
@@ -201,6 +204,7 @@ impl InterpreterBuilder {
/// // let interp = builder.add_native_modules(&defs).build();
/// let interp = builder.build();
/// ```
#[must_use]
pub fn add_native_modules(mut self, defs: &[&'static builtins::PyModuleDef]) -> Self {
self.module_defs.extend_from_slice(defs);
self
@@ -254,6 +258,7 @@ impl InterpreterBuilder {
/// Build the interpreter.
///
/// This consumes the configuration and returns a fully initialized Interpreter.
#[must_use]
pub fn build(self) -> Interpreter {
let (vm, global_state) = initialize_main_vm(
self.settings,
@@ -267,6 +272,7 @@ impl InterpreterBuilder {
}
/// Alias for `build()` for compatibility with the `interpreter()` pattern.
#[must_use]
pub fn interpreter(self) -> Interpreter {
self.build()
}
@@ -312,6 +318,7 @@ impl Interpreter {
/// // In practice, add stdlib: builder.add_native_modules(&stdlib_module_defs(&builder.ctx))
/// let interp = builder.build();
/// ```
#[must_use]
pub fn builder(settings: Settings) -> InterpreterBuilder {
InterpreterBuilder::new().settings(settings)
}
@@ -320,6 +327,7 @@ impl Interpreter {
/// To create an interpreter with the standard library with the `rustpython` crate, use `rustpython::InterpreterBuilder`.
/// To create an interpreter without the `rustpython` crate, but only with `rustpython-vm`,
/// try to build one from the source code of `InterpreterBuilder`. It will not be a one-liner but it also will not be too hard.
#[must_use]
pub fn without_stdlib(settings: Settings) -> Self {
Self::with_init(settings, |_| {})
}
+3
View File
@@ -115,6 +115,7 @@ pub struct FramePtr(NonNull<Py<Frame>>);
impl FramePtr {
/// # Safety
/// The pointed-to frame must still be alive.
#[must_use]
pub unsafe fn as_ref(&self) -> &Py<Frame> {
unsafe { self.0.as_ref() }
}
@@ -201,6 +202,7 @@ impl Default for StopTheWorldState {
#[cfg(all(unix, feature = "threading"))]
impl StopTheWorldState {
#[must_use]
pub const fn new() -> Self {
Self {
requested: AtomicBool::new(false),
@@ -2273,6 +2275,7 @@ impl AsRef<Context> for VirtualMachine {
/// Resolve frozen module alias to its original name.
/// Returns the original module name if an alias exists, otherwise returns the input name.
#[must_use]
pub fn resolve_frozen_alias(name: &str) -> &str {
match name {
"_frozen_importlib" => "importlib._bootstrap",
+2
View File
@@ -31,6 +31,7 @@ pub struct PyConfig {
}
impl PyConfig {
#[must_use]
pub fn new(settings: Settings, paths: Paths) -> Self {
Self { settings, paths }
}
@@ -171,6 +172,7 @@ pub enum CheckHashPycsMode {
}
impl Settings {
#[must_use]
pub fn with_path(mut self, path: String) -> Self {
self.path_list.push(path);
self
+2
View File
@@ -345,6 +345,7 @@ fn do_suspend(stw: &super::StopTheWorldState) {
#[cfg(all(unix, feature = "threading"))]
#[inline]
#[must_use]
pub fn stop_requested_for_current_thread() -> bool {
CURRENT_THREAD_SLOT.with(|slot| {
slot.borrow()
@@ -393,6 +394,7 @@ pub fn set_current_frame(frame: *const Frame) -> *const Frame {
/// Get the current thread's top frame pointer.
/// Used by faulthandler's signal handler to start traceback walking.
#[must_use]
pub fn get_current_frame() -> *const Frame {
CURRENT_FRAME.with(|c| c.load(Ordering::Relaxed) as *const Frame)
}
+1
View File
@@ -254,6 +254,7 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
}
}
#[must_use]
pub fn syntax_err(err: CompileError) -> SyntaxError {
let js_err = SyntaxError::new(&format!("Error parsing Python code: {err}"));
let _ = Reflect::set(
+4
View File
@@ -108,6 +108,7 @@ pub struct VMStore;
#[wasm_bindgen(js_class = vmStore)]
impl VMStore {
#[must_use]
pub fn init(id: String, inject_browser_module: Option<bool>) -> WASMVirtualMachine {
STORED_VMS.with_borrow_mut(|vms| {
if !vms.contains_key(&id) {
@@ -123,6 +124,7 @@ impl VMStore {
STORED_VMS.with_borrow(|vms| vms.contains_key(&id).then_some(WASMVirtualMachine { id }))
}
#[must_use]
pub fn get(id: String) -> JsValue {
match Self::_get(id) {
Some(wasm_vm) => wasm_vm.into(),
@@ -142,6 +144,7 @@ impl VMStore {
});
}
#[must_use]
pub fn ids() -> Vec<JsValue> {
STORED_VMS.with_borrow(|vms| vms.keys().map(|k| k.into()).collect())
}
@@ -178,6 +181,7 @@ impl WASMVirtualMachine {
self.with(|stored| stored.interp.enter(|vm| f(vm, stored)))
}
#[must_use]
pub fn valid(&self) -> bool {
STORED_VMS.with_borrow(|vms| vms.contains_key(&self.id))
}