mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
code nits (#7908)
* Slight cleanup of super.rs * frame.rs * buffer.rs * bool.rs
This commit is contained in:
@@ -18,7 +18,7 @@ type UnpackFunc = fn(&VirtualMachine, &[u8]) -> PyObjectRef;
|
||||
|
||||
static OVERFLOW_MSG: &str = "total struct size too long"; // not a const to reduce code size
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum Endianness {
|
||||
Native,
|
||||
Little,
|
||||
@@ -40,7 +40,12 @@ impl Endianness {
|
||||
Some(b'>' | b'!') => Self::Big,
|
||||
_ => return Self::Native,
|
||||
};
|
||||
chars.next().unwrap();
|
||||
|
||||
// SAFETY:
|
||||
// We just ensured with `chars.peek()` that this is safe
|
||||
unsafe {
|
||||
let _ = chars.next().unwrap_unchecked();
|
||||
}
|
||||
e
|
||||
}
|
||||
}
|
||||
@@ -48,13 +53,17 @@ impl Endianness {
|
||||
trait ByteOrder {
|
||||
fn convert<I: PrimInt>(i: I) -> I;
|
||||
}
|
||||
|
||||
enum BigEndian {}
|
||||
|
||||
impl ByteOrder for BigEndian {
|
||||
fn convert<I: PrimInt>(i: I) -> I {
|
||||
i.to_be()
|
||||
}
|
||||
}
|
||||
|
||||
enum LittleEndian {}
|
||||
|
||||
impl ByteOrder for LittleEndian {
|
||||
fn convert<I: PrimInt>(i: I) -> I {
|
||||
i.to_le()
|
||||
@@ -66,7 +75,7 @@ type NativeEndian = cfg_select! {
|
||||
target_endian = "little" => LittleEndian,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, num_enum::TryFromPrimitive)]
|
||||
#[derive(Copy, Clone, num_enum::TryFromPrimitive, Eq, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub(crate) enum FormatType {
|
||||
Pad = b'x',
|
||||
@@ -105,6 +114,7 @@ impl FormatType {
|
||||
fn info(self, e: Endianness) -> &'static FormatInfo {
|
||||
use FormatType::*;
|
||||
use mem::{align_of, size_of};
|
||||
|
||||
macro_rules! native_info {
|
||||
($t:ty) => {{
|
||||
&FormatInfo {
|
||||
@@ -115,6 +125,7 @@ impl FormatType {
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! nonnative_info {
|
||||
($t:ty, $end:ty) => {{
|
||||
&FormatInfo {
|
||||
@@ -125,6 +136,7 @@ impl FormatType {
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! match_nonnative {
|
||||
($zelf:expr, $end:ty) => {{
|
||||
match $zelf {
|
||||
@@ -158,6 +170,7 @@ impl FormatType {
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
match e {
|
||||
Endianness::Native => match self {
|
||||
Pad | Str | Pascal => &FormatInfo {
|
||||
@@ -381,6 +394,7 @@ pub(crate) struct FormatInfo {
|
||||
pub pack: Option<PackFunc>,
|
||||
pub unpack: Option<UnpackFunc>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for FormatInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("FormatInfo")
|
||||
|
||||
@@ -37,8 +37,7 @@ impl PyObjectRef {
|
||||
pub fn try_to_bool(self, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
if self.is(&vm.ctx.true_value) {
|
||||
return Ok(true);
|
||||
}
|
||||
if self.is(&vm.ctx.false_value) {
|
||||
} else if self.is(&vm.ctx.false_value) {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
@@ -83,10 +82,9 @@ impl Constructor for PyBool {
|
||||
fn slot_new(zelf: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
let x: Self::Args = args.bind(vm)?;
|
||||
if !zelf.fast_isinstance(vm.ctx.types.type_type) {
|
||||
let actual_class = zelf.class();
|
||||
let actual_type = &actual_class.name();
|
||||
return Err(vm.new_type_error(format!(
|
||||
"requires a 'type' object but received a '{actual_type}'"
|
||||
"requires a 'type' object but received a '{}'",
|
||||
zelf.class().name()
|
||||
)));
|
||||
}
|
||||
let val = x.map_or(Ok(false), |val| val.try_to_bool(vm))?;
|
||||
|
||||
@@ -43,19 +43,19 @@ pub(crate) mod stack_analysis {
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
fn from_i64(v: i64) -> Option<Self> {
|
||||
match v {
|
||||
1 => Some(Self::Iterator),
|
||||
2 => Some(Self::Except),
|
||||
3 => Some(Self::Object),
|
||||
4 => Some(Self::Null),
|
||||
5 => Some(Self::Lasti),
|
||||
_ => None,
|
||||
}
|
||||
const fn from_i64(v: i64) -> Option<Self> {
|
||||
Some(match v {
|
||||
1 => Self::Iterator,
|
||||
2 => Self::Except,
|
||||
3 => Self::Object,
|
||||
4 => Self::Null,
|
||||
5 => Self::Lasti,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn push_value(stack: i64, kind: i64) -> i64 {
|
||||
pub(crate) const fn push_value(stack: i64, kind: i64) -> i64 {
|
||||
if (stack as u64) >= WILL_OVERFLOW {
|
||||
OVERFLOWED
|
||||
} else {
|
||||
@@ -63,20 +63,20 @@ pub(crate) mod stack_analysis {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn pop_value(stack: i64) -> i64 {
|
||||
pub(crate) const fn pop_value(stack: i64) -> i64 {
|
||||
stack >> BITS_PER_BLOCK
|
||||
}
|
||||
|
||||
pub(crate) fn top_of_stack(stack: i64) -> i64 {
|
||||
pub(crate) const fn top_of_stack(stack: i64) -> i64 {
|
||||
stack & MASK
|
||||
}
|
||||
|
||||
fn peek(stack: i64, n: u32) -> i64 {
|
||||
const fn peek(stack: i64, n: u32) -> i64 {
|
||||
debug_assert!(n >= 1);
|
||||
(stack >> (BITS_PER_BLOCK * (n - 1))) & MASK
|
||||
}
|
||||
|
||||
fn stack_swap(stack: i64, n: u32) -> i64 {
|
||||
const fn stack_swap(stack: i64, n: u32) -> i64 {
|
||||
debug_assert!(n >= 1);
|
||||
let to_swap = peek(stack, n);
|
||||
let top = top_of_stack(stack);
|
||||
@@ -85,7 +85,7 @@ pub(crate) mod stack_analysis {
|
||||
(replaced_low & !MASK) | to_swap
|
||||
}
|
||||
|
||||
fn pop_to_level(mut stack: i64, level: u32) -> i64 {
|
||||
const fn pop_to_level(mut stack: i64, level: u32) -> i64 {
|
||||
if level == 0 {
|
||||
return EMPTY_STACK;
|
||||
}
|
||||
@@ -97,20 +97,21 @@ pub(crate) mod stack_analysis {
|
||||
stack
|
||||
}
|
||||
|
||||
fn compatible_kind(from: i64, to: i64) -> bool {
|
||||
#[must_use]
|
||||
const fn compatible_kind(from: i64, to: i64) -> bool {
|
||||
if to == 0 {
|
||||
return false;
|
||||
false
|
||||
} else if to == Kind::Object as i64 {
|
||||
from != Kind::Null as i64
|
||||
} else if to == Kind::Null as i64 {
|
||||
true
|
||||
} else {
|
||||
from == to
|
||||
}
|
||||
if to == Kind::Object as i64 {
|
||||
return from != Kind::Null as i64;
|
||||
}
|
||||
if to == Kind::Null as i64 {
|
||||
return true;
|
||||
}
|
||||
from == to
|
||||
}
|
||||
|
||||
pub(crate) fn compatible_stack(from_stack: i64, to_stack: i64) -> bool {
|
||||
#[must_use]
|
||||
pub(crate) const fn compatible_stack(from_stack: i64, to_stack: i64) -> bool {
|
||||
if from_stack < 0 || to_stack < 0 {
|
||||
return false;
|
||||
}
|
||||
@@ -131,14 +132,17 @@ pub(crate) mod stack_analysis {
|
||||
to == 0
|
||||
}
|
||||
|
||||
pub(crate) fn explain_incompatible_stack(to_stack: i64) -> &'static str {
|
||||
pub(crate) const fn explain_incompatible_stack(to_stack: i64) -> &'static str {
|
||||
debug_assert!(to_stack != 0);
|
||||
|
||||
if to_stack == OVERFLOWED {
|
||||
return "stack is too deep to analyze";
|
||||
}
|
||||
|
||||
if to_stack == UNINITIALIZED {
|
||||
return "can't jump into an exception handler, or code may be unreachable";
|
||||
}
|
||||
|
||||
match Kind::from_i64(top_of_stack(to_stack)) {
|
||||
Some(Kind::Except) => "can't jump into an 'except' block as there's no exception",
|
||||
Some(Kind::Lasti) => "can't jump into a re-raising block as there's no location",
|
||||
|
||||
@@ -33,11 +33,13 @@ fn format_missing_args(
|
||||
missing: &mut Vec<impl core::fmt::Display>,
|
||||
) -> String {
|
||||
let count = missing.len();
|
||||
|
||||
let last = if missing.len() > 1 {
|
||||
missing.pop()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let (and, right): (&str, String) = if let Some(last) = last {
|
||||
(
|
||||
if missing.len() == 1 {
|
||||
@@ -45,11 +47,12 @@ fn format_missing_args(
|
||||
} else {
|
||||
"', and '"
|
||||
},
|
||||
format!("{last}"),
|
||||
last.to_string(),
|
||||
)
|
||||
} else {
|
||||
("", String::new())
|
||||
};
|
||||
|
||||
format!(
|
||||
"{qualname}() missing {count} required {kind} argument{}: '{}{}{right}'",
|
||||
if count == 1 { "" } else { "s" },
|
||||
@@ -1268,12 +1271,12 @@ impl PyBoundMethod {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn function_obj(&self) -> &PyObjectRef {
|
||||
pub(crate) const fn function_obj(&self) -> &PyObjectRef {
|
||||
&self.function
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn self_obj(&self) -> &PyObjectRef {
|
||||
pub(crate) const fn self_obj(&self) -> &PyObjectRef {
|
||||
&self.object
|
||||
}
|
||||
|
||||
@@ -1398,6 +1401,7 @@ impl Representable for PyBoundMethod {
|
||||
pub(crate) struct PyCell {
|
||||
contents: PyMutex<Option<PyObjectRef>>,
|
||||
}
|
||||
|
||||
pub(crate) type PyCellRef = PyRef<PyCell>;
|
||||
|
||||
impl PyPayload for PyCell {
|
||||
@@ -1426,6 +1430,7 @@ impl PyCell {
|
||||
pub(crate) fn get(&self) -> Option<PyObjectRef> {
|
||||
self.contents.lock().clone()
|
||||
}
|
||||
|
||||
pub(crate) fn set(&self, x: Option<PyObjectRef>) {
|
||||
*self.contents.lock() = x;
|
||||
}
|
||||
@@ -1435,6 +1440,7 @@ impl PyCell {
|
||||
self.get()
|
||||
.ok_or_else(|| vm.new_value_error("Cell is empty"))
|
||||
}
|
||||
|
||||
#[pygetset(setter)]
|
||||
fn set_cell_contents(&self, x: PySetterValue) {
|
||||
match x {
|
||||
@@ -1488,6 +1494,7 @@ pub(crate) fn vectorcall_function(
|
||||
args.truncate(nargs);
|
||||
FuncArgs::from(args)
|
||||
};
|
||||
|
||||
zelf.invoke(func_args, vm)
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ impl Initializer for PySuper {
|
||||
if frame.code.arg_count == 0 {
|
||||
return Err(vm.new_runtime_error("super(): no arguments"));
|
||||
}
|
||||
|
||||
// SAFETY: Frame is current and not concurrently mutated.
|
||||
use rustpython_compiler_core::bytecode::CO_FAST_CELL;
|
||||
let obj = unsafe { frame.fastlocals() }[0]
|
||||
@@ -165,9 +166,9 @@ impl GetAttr for PySuper {
|
||||
Some(o) => o.clone(),
|
||||
None => return skip(zelf, name),
|
||||
};
|
||||
|
||||
// We want __class__ to return the class of the super object
|
||||
// (i.e. super, or a subclass), not the class of su->obj.
|
||||
|
||||
if name.as_bytes() == b"__class__" {
|
||||
return skip(zelf, name);
|
||||
}
|
||||
@@ -280,21 +281,23 @@ pub(crate) fn init(context: &'static Context) {
|
||||
let super_type = &context.types.super_type;
|
||||
PySuper::extend_class(context, super_type);
|
||||
|
||||
let super_doc = "super() -> same as super(__class__, <first argument>)\n\
|
||||
super(type) -> unbound super object\n\
|
||||
super(type, obj) -> bound super object; requires isinstance(obj, type)\n\
|
||||
super(type, type2) -> bound super object; requires issubclass(type2, type)\n\
|
||||
Typical use to call a cooperative superclass method:\n\
|
||||
class C(B):\n \
|
||||
def meth(self, arg):\n \
|
||||
super().meth(arg)\n\
|
||||
This works for class methods too:\n\
|
||||
class C(B):\n \
|
||||
@classmethod\n \
|
||||
def cmeth(cls, arg):\n \
|
||||
super().cmeth(arg)\n";
|
||||
const SUPER_DOC: &str = "\
|
||||
super() -> same as super(__class__, <first argument>)
|
||||
super(type) -> unbound super object
|
||||
super(type, obj) -> bound super object; requires isinstance(obj, type)
|
||||
super(type, type2) -> bound super object; requires issubclass(type2, type)
|
||||
Typical use to call a cooperative superclass method:
|
||||
class C(B):
|
||||
def meth(self, arg):
|
||||
super().meth(arg)
|
||||
This works for class methods too:
|
||||
class C(B):
|
||||
@classmethod
|
||||
def cmeth(cls, arg):
|
||||
super().cmeth(arg)
|
||||
";
|
||||
|
||||
extend_class!(context, super_type, {
|
||||
"__doc__" => context.new_str(super_doc),
|
||||
"__doc__" => context.new_str(SUPER_DOC),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// cspell:ignore pyhash
|
||||
|
||||
use super::{
|
||||
PositionIterInternal, PyGenericAlias, PyStrRef, PyType, PyTypeRef, iter::builtins_iter,
|
||||
};
|
||||
@@ -296,13 +298,13 @@ impl<R> PyTuple<R> {
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn len(&self) -> usize {
|
||||
pub const fn len(&self) -> usize {
|
||||
self.elements.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
self.elements.is_empty()
|
||||
}
|
||||
|
||||
@@ -725,23 +727,29 @@ pub(crate) fn init(context: &'static Context) {
|
||||
}
|
||||
|
||||
pub(super) fn tuple_hash(elements: &[PyObjectRef], vm: &VirtualMachine) -> PyResult<PyHash> {
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const PRIME1: PyUHash = 11400714785074694791;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const PRIME2: PyUHash = 14029467366897019727;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const PRIME5: PyUHash = 2870177450012600261;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const ROTATE: u32 = 31;
|
||||
const PRIME1: PyUHash = cfg_select! {
|
||||
target_pointer_width = "64" => 11400714785074694791,
|
||||
target_pointer_width = "32" => 2654435761,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const PRIME1: PyUHash = 2654435761;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const PRIME2: PyUHash = 2246822519;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const PRIME5: PyUHash = 374761393;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const ROTATE: u32 = 13;
|
||||
const PRIME2: PyUHash = cfg_select! {
|
||||
target_pointer_width = "64" => 14029467366897019727,
|
||||
target_pointer_width = "32" => 2246822519,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
const PRIME5: PyUHash = cfg_select! {
|
||||
target_pointer_width = "64" => 2870177450012600261,
|
||||
target_pointer_width = "32" => 374761393,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
const ROTATE: u32 = cfg_select! {
|
||||
target_pointer_width = "64" => 31,
|
||||
target_pointer_width = "32" => 13,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut acc = PRIME5;
|
||||
let len = elements.len() as PyUHash;
|
||||
@@ -755,8 +763,10 @@ pub(super) fn tuple_hash(elements: &[PyObjectRef], vm: &VirtualMachine) -> PyRes
|
||||
|
||||
acc = acc.wrapping_add(len ^ (PRIME5 ^ 3527539));
|
||||
|
||||
if acc as PyHash == -1 {
|
||||
let acc_pyhash = acc as PyHash;
|
||||
if acc_pyhash == -1 {
|
||||
return Ok(1546275796);
|
||||
}
|
||||
Ok(acc as PyHash)
|
||||
|
||||
Ok(acc_pyhash)
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ impl IterNext for PyWeakProxy {
|
||||
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
|
||||
let obj = zelf.try_upgrade(vm)?;
|
||||
if obj.class().slots.iternext.load().is_none() {
|
||||
return Err(vm.new_type_error("Weakref proxy referenced a non-iterator".to_owned()));
|
||||
return Err(vm.new_type_error("Weakref proxy referenced a non-iterator"));
|
||||
}
|
||||
PyIter::new(obj).next(vm)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ impl PyPayload for PyWeak {
|
||||
|
||||
impl Callable for PyWeak {
|
||||
type Args = ();
|
||||
|
||||
#[inline]
|
||||
fn call(zelf: &Py<Self>, _: Self::Args, vm: &VirtualMachine) -> PyResult {
|
||||
Ok(vm.unwrap_or_none(zelf.upgrade()))
|
||||
@@ -50,10 +51,10 @@ impl Constructor for PyWeak {
|
||||
.ok_or_else(|| vm.new_type_error("__new__ expected at least 1 argument, got 0"))?;
|
||||
let callback = positional.next();
|
||||
if let Some(_extra) = positional.next() {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"__new__ expected at most 2 arguments, got {}",
|
||||
3 + positional.count()
|
||||
)));
|
||||
let got = positional.count() + 3;
|
||||
return Err(
|
||||
vm.new_type_error(format!("__new__ expected at most 2 arguments, got {got}"))
|
||||
);
|
||||
}
|
||||
let weak = referent.downgrade_with_typ(callback, cls, vm)?;
|
||||
Ok(weak.into())
|
||||
@@ -151,7 +152,7 @@ impl Representable for PyWeak {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
let id = zelf.get_id();
|
||||
let repr = if let Some(o) = zelf.upgrade() {
|
||||
Ok(if let Some(o) = zelf.upgrade() {
|
||||
format!(
|
||||
"<weakref at {:#x}; to '{}' at {:#x}>",
|
||||
id,
|
||||
@@ -160,8 +161,7 @@ impl Representable for PyWeak {
|
||||
)
|
||||
} else {
|
||||
format!("<weakref at {id:#x}; dead>")
|
||||
};
|
||||
Ok(repr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user