mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 11:14:38 +08:00
General code nits (#8041)
This commit is contained in:
1 parent
4143af54f7
commit
fb9a5ca65b
11 files changed
+141
-134
No files matched your search
@@ -2,6 +2,8 @@
|
||||
|
||||
pub(super) use decl::crc32;
|
||||
pub(crate) use decl::module_def;
|
||||
|
||||
use rustpython_common::wtf8::Wtf8Buf;
|
||||
use rustpython_vm::{VirtualMachine, builtins::PyBaseExceptionRef, convert::ToPyException};
|
||||
|
||||
const PAD: u8 = 61u8;
|
||||
@@ -16,6 +18,7 @@ mod decl {
|
||||
convert::ToPyException,
|
||||
function::{ArgAsciiBuffer, ArgBytesLike, OptionalArg},
|
||||
};
|
||||
|
||||
use base64::Engine;
|
||||
use itertools::Itertools;
|
||||
|
||||
@@ -33,7 +36,7 @@ mod decl {
|
||||
vm.ctx.new_exception_type("binascii", "Incomplete", None)
|
||||
}
|
||||
|
||||
fn hex_nibble(n: u8) -> u8 {
|
||||
const fn hex_nibble(n: u8) -> u8 {
|
||||
match n {
|
||||
0..=9 => b'0' + n,
|
||||
10..=15 => b'a' + (n - 10),
|
||||
@@ -174,10 +177,7 @@ mod decl {
|
||||
fn unhexlify(data: ArgAsciiBuffer, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
|
||||
data.with_ref(|hex_bytes| {
|
||||
if hex_bytes.len() % 2 != 0 {
|
||||
return Err(super::new_binascii_error(
|
||||
"Odd-length string".to_owned(),
|
||||
vm,
|
||||
));
|
||||
return Err(super::new_binascii_error("Odd-length string", vm));
|
||||
}
|
||||
|
||||
let mut unhex = Vec::<u8>::with_capacity(hex_bytes.len() / 2);
|
||||
@@ -185,10 +185,7 @@ mod decl {
|
||||
if let (Some(n1), Some(n2)) = (unhex_nibble(*n1), unhex_nibble(*n2)) {
|
||||
unhex.push((n1 << 4) | n2);
|
||||
} else {
|
||||
return Err(super::new_binascii_error(
|
||||
"Non-hexadecimal digit found".to_owned(),
|
||||
vm,
|
||||
));
|
||||
return Err(super::new_binascii_error("Non-hexadecimal digit found", vm));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,10 +261,10 @@ mod decl {
|
||||
|
||||
#[pyfunction]
|
||||
fn a2b_base64(args: A2bBase64Args, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
|
||||
#[rustfmt::skip]
|
||||
// Converts between ASCII and base-64 characters. The index of a given number yields the
|
||||
// number in ASCII while the value of said index yields the number in base-64. For example
|
||||
// "=" is 61 in ASCII but 0 (since it's the pad character) in base-64, so BASE64_TABLE[61] == 0
|
||||
#[rustfmt::skip]
|
||||
const BASE64_TABLE: [i8; 256] = [
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||
@@ -398,7 +395,7 @@ mod decl {
|
||||
if [b'\r', b'\n'].contains(c) {
|
||||
return Ok(0);
|
||||
}
|
||||
return Err(super::new_binascii_error("Illegal char".to_owned(), vm));
|
||||
return Err(super::new_binascii_error("Illegal char", vm));
|
||||
}
|
||||
Ok((*c - b' ') & 0x3f)
|
||||
}
|
||||
@@ -757,8 +754,7 @@ mod decl {
|
||||
|
||||
// Allocate the buffer
|
||||
let mut res = Vec::<u8>::with_capacity(length);
|
||||
let trailing_garbage_error =
|
||||
|| Err(super::new_binascii_error("Trailing garbage".to_owned(), vm));
|
||||
let trailing_garbage_error = || Err(super::new_binascii_error("Trailing garbage", vm));
|
||||
|
||||
for chunk in b.get(1..).unwrap_or_default().chunks(4) {
|
||||
let (char_a, char_b, char_c, char_d) = {
|
||||
@@ -823,10 +819,7 @@ mod decl {
|
||||
data.with_ref(|b| {
|
||||
let length = b.len();
|
||||
if length > 45 {
|
||||
return Err(super::new_binascii_error(
|
||||
"At most 45 bytes at once".to_owned(),
|
||||
vm,
|
||||
));
|
||||
return Err(super::new_binascii_error("At most 45 bytes at once", vm));
|
||||
}
|
||||
let mut res = Vec::<u8>::with_capacity(2 + length.div_ceil(3) * 4);
|
||||
res.push(uu_b2a(length as u8, backtick));
|
||||
@@ -850,7 +843,7 @@ mod decl {
|
||||
|
||||
struct Base64DecodeError(base64::DecodeError);
|
||||
|
||||
fn new_binascii_error(msg: String, vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
fn new_binascii_error<T: Into<Wtf8Buf>>(msg: T, vm: &VirtualMachine) -> PyBaseExceptionRef {
|
||||
vm.new_exception_msg(decl::error_type(vm), msg.into())
|
||||
}
|
||||
|
||||
|
||||
@@ -274,11 +274,10 @@ mod unicodedata {
|
||||
|
||||
#[pymethod]
|
||||
fn decomposition(&self, character: PyStrRef, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let ch = match self.extract_char(character, vm)?.and_then(|c| c.to_char()) {
|
||||
Some(ch) => ch,
|
||||
None => return Ok(String::new()),
|
||||
let Some(ch) = self.extract_char(character, vm)?.and_then(|c| c.to_char()) else {
|
||||
return Ok(String::new());
|
||||
};
|
||||
let chars: Vec<char> = ch.decomposition_map().collect();
|
||||
let chars = ch.decomposition_map().collect::<Vec<char>>();
|
||||
// If decomposition maps to just the character itself, there's no decomposition
|
||||
if chars.len() == 1 && chars[0] == ch {
|
||||
return Ok(String::new());
|
||||
@@ -356,7 +355,7 @@ mod unicodedata {
|
||||
}
|
||||
}
|
||||
|
||||
fn decomposition_type_tag(dt: DecompositionType) -> &'static str {
|
||||
const fn decomposition_type_tag(dt: DecompositionType) -> &'static str {
|
||||
match dt {
|
||||
DecompositionType::Canonical => "canonical",
|
||||
DecompositionType::Compat => "compat",
|
||||
|
||||
@@ -855,6 +855,7 @@ impl Iterator for DictIntoIter {
|
||||
(l, Some(l))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for DictIntoIter {
|
||||
fn len(&self) -> usize {
|
||||
self.dict.entries.len_from_entry_index(self.position)
|
||||
@@ -886,6 +887,7 @@ impl Iterator for DictIter<'_> {
|
||||
(l, Some(l))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for DictIter<'_> {
|
||||
fn len(&self) -> usize {
|
||||
self.dict.entries.len_from_entry_index(self.position)
|
||||
@@ -1266,6 +1268,7 @@ trait ViewSetOps: DictView {
|
||||
}
|
||||
|
||||
impl ViewSetOps for PyDictKeys {}
|
||||
|
||||
#[pyclass(
|
||||
flags(DISALLOW_INSTANTIATION),
|
||||
with(
|
||||
|
||||
@@ -533,7 +533,7 @@ impl AsSequence for PyList {
|
||||
}
|
||||
.map_err(|e| {
|
||||
if e.class().is(vm.ctx.exceptions.index_error) {
|
||||
vm.new_index_error("list assignment index out of range".to_owned())
|
||||
vm.new_index_error("list assignment index out of range")
|
||||
} else {
|
||||
e
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ mod _collections {
|
||||
})
|
||||
} else {
|
||||
Err(vm.new_type_error(format!(
|
||||
"can only concatenate deque (not \"{}\") to deque",
|
||||
r#"can only concatenate deque (not "{}") to deque"#,
|
||||
other.class().name()
|
||||
)))
|
||||
}
|
||||
@@ -503,11 +503,13 @@ mod _collections {
|
||||
.concat(other, vm)
|
||||
.map(|x| x.into_ref(&vm.ctx).into())
|
||||
}),
|
||||
|
||||
repeat: atomic_func!(|seq, n, vm| {
|
||||
PyDeque::sequence_downcast(seq)
|
||||
.__mul__(n, vm)
|
||||
.map(|x| x.into_ref(&vm.ctx).into())
|
||||
}),
|
||||
|
||||
item: atomic_func!(|seq, i, vm| PyDeque::sequence_downcast(seq).__getitem__(i, vm)),
|
||||
ass_item: atomic_func!(|seq, i, value, vm| {
|
||||
let zelf = PyDeque::sequence_downcast(seq);
|
||||
@@ -517,14 +519,17 @@ mod _collections {
|
||||
zelf.__delitem__(i, vm)
|
||||
}
|
||||
}),
|
||||
|
||||
contains: atomic_func!(
|
||||
|seq, needle, vm| PyDeque::sequence_downcast(seq)._contains(needle, vm)
|
||||
),
|
||||
|
||||
inplace_concat: atomic_func!(|seq, other, vm| {
|
||||
let zelf = PyDeque::sequence_downcast(seq);
|
||||
zelf._extend(other, vm)?;
|
||||
Ok(zelf.to_owned().into())
|
||||
}),
|
||||
|
||||
inplace_repeat: atomic_func!(|seq, n, vm| {
|
||||
let zelf = PyDeque::sequence_downcast(seq);
|
||||
PyDeque::__imul__(zelf.to_owned(), n, vm).map(|x| x.into())
|
||||
@@ -545,6 +550,7 @@ mod _collections {
|
||||
if let Some(res) = op.identical_optimization(zelf, other) {
|
||||
return Ok(res.into());
|
||||
}
|
||||
|
||||
let other = class_or_notimplemented!(Self, other);
|
||||
let lhs = zelf.borrow_deque();
|
||||
let rhs = other.borrow_deque();
|
||||
@@ -573,6 +579,7 @@ mod _collections {
|
||||
if zelf.__len__() == 0 {
|
||||
return Ok(vm.ctx.new_str(format!("{class_name}([{closing_part})")));
|
||||
}
|
||||
|
||||
if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
Ok(vm.ctx.new_str(collection_repr(
|
||||
Some(&class_name),
|
||||
|
||||
+23
-24
@@ -188,18 +188,18 @@ mod _io {
|
||||
result.map(Some)
|
||||
}
|
||||
|
||||
pub(super) fn new_unsupported_operation(
|
||||
pub(super) fn new_unsupported_operation<T: Into<String>>(
|
||||
msg: T,
|
||||
vm: &VirtualMachine,
|
||||
msg: String,
|
||||
) -> PyBaseExceptionRef {
|
||||
vm.new_os_subtype_error(unsupported_operation().to_owned(), None, msg)
|
||||
vm.new_os_subtype_error(unsupported_operation().to_owned(), None, msg.into())
|
||||
.upcast()
|
||||
}
|
||||
|
||||
fn _unsupported<T>(vm: &VirtualMachine, zelf: &PyObject, operation: &str) -> PyResult<T> {
|
||||
Err(new_unsupported_operation(
|
||||
vm,
|
||||
format!("{}.{}() not supported", zelf.class().name(), operation),
|
||||
vm,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -363,8 +363,8 @@ mod _io {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(new_unsupported_operation(
|
||||
"File or stream is not readable",
|
||||
vm,
|
||||
"File or stream is not readable".to_owned(),
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -374,8 +374,8 @@ mod _io {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(new_unsupported_operation(
|
||||
"File or stream is not writable.",
|
||||
vm,
|
||||
"File or stream is not writable.".to_owned(),
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -385,8 +385,8 @@ mod _io {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(new_unsupported_operation(
|
||||
"File or stream is not seekable",
|
||||
vm,
|
||||
"File or stream is not seekable".to_owned(),
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -1680,7 +1680,7 @@ mod _io {
|
||||
let mut data = zelf.lock(vm)?;
|
||||
data.check_init(vm)?;
|
||||
if !data.writable() {
|
||||
return Err(new_unsupported_operation(vm, "truncate".to_owned()));
|
||||
return Err(new_unsupported_operation("truncate", vm));
|
||||
}
|
||||
data.flush_rewind(vm)?;
|
||||
let res = vm.call_method(data.raw.as_ref().unwrap(), "truncate", (pos,))?;
|
||||
@@ -3063,9 +3063,8 @@ mod _io {
|
||||
|| data.decoded_chars_used.chars != 0)
|
||||
{
|
||||
return Err(new_unsupported_operation(
|
||||
"cannot reconfigure encoding or newline after reading from the stream",
|
||||
vm,
|
||||
"cannot reconfigure encoding or newline after reading from the stream"
|
||||
.to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -3203,8 +3202,8 @@ mod _io {
|
||||
|
||||
if !textio.seekable {
|
||||
return Err(new_unsupported_operation(
|
||||
"underlying stream is not seekable",
|
||||
vm,
|
||||
"underlying stream is not seekable".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -3217,8 +3216,8 @@ mod _io {
|
||||
vm.call_method(&textio.buffer, "tell", ())?
|
||||
} else {
|
||||
return Err(new_unsupported_operation(
|
||||
"can't do nonzero cur-relative seeks",
|
||||
vm,
|
||||
"can't do nonzero cur-relative seeks".to_owned(),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -3241,8 +3240,8 @@ mod _io {
|
||||
return Ok(res);
|
||||
}
|
||||
return Err(new_unsupported_operation(
|
||||
"can't do nonzero end-relative seeks",
|
||||
vm,
|
||||
"can't do nonzero end-relative seeks".to_owned(),
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
@@ -3312,8 +3311,8 @@ mod _io {
|
||||
let mut textio = zelf.lock(vm)?;
|
||||
if !textio.seekable {
|
||||
return Err(new_unsupported_operation(
|
||||
"underlying stream is not seekable",
|
||||
vm,
|
||||
"underlying stream is not seekable".to_owned(),
|
||||
));
|
||||
}
|
||||
if !textio.telling {
|
||||
@@ -3444,7 +3443,7 @@ mod _io {
|
||||
let decoder = textio
|
||||
.decoder
|
||||
.clone()
|
||||
.ok_or_else(|| new_unsupported_operation(vm, "not readable".to_owned()))?;
|
||||
.ok_or_else(|| new_unsupported_operation("not readable", vm))?;
|
||||
|
||||
textio.write_pending(vm)?;
|
||||
|
||||
@@ -3495,7 +3494,7 @@ mod _io {
|
||||
let (encoder, encode_func) = textio
|
||||
.encoder
|
||||
.as_ref()
|
||||
.ok_or_else(|| new_unsupported_operation(vm, "not writable".to_owned()))?;
|
||||
.ok_or_else(|| new_unsupported_operation("not writable", vm))?;
|
||||
|
||||
let char_len = obj.char_len();
|
||||
|
||||
@@ -3861,7 +3860,7 @@ mod _io {
|
||||
let decoder = self
|
||||
.decoder
|
||||
.as_ref()
|
||||
.ok_or_else(|| new_unsupported_operation(vm, "not readable".to_owned()))?;
|
||||
.ok_or_else(|| new_unsupported_operation("not readable", vm))?;
|
||||
|
||||
let dec_state = if self.telling {
|
||||
let state = vm.call_method(decoder, "getstate", ())?;
|
||||
@@ -5101,8 +5100,8 @@ mod _io {
|
||||
}
|
||||
.ok_or_else(|| {
|
||||
new_unsupported_operation(
|
||||
"Couldn't get FileIO, io.open likely isn't supported on your platform",
|
||||
vm,
|
||||
"Couldn't get FileIO, io.open likely isn't supported on your platform".to_owned(),
|
||||
)
|
||||
})?;
|
||||
let raw = PyType::call(
|
||||
@@ -5586,8 +5585,8 @@ mod fileio {
|
||||
) -> PyResult<Option<Vec<u8>>> {
|
||||
if !zelf.mode.load().contains(host_io::FileMode::READABLE) {
|
||||
return Err(new_unsupported_operation(
|
||||
"File or stream is not readable",
|
||||
vm,
|
||||
"File or stream is not readable".to_owned(),
|
||||
));
|
||||
}
|
||||
let handle = zelf.get_fd(vm)?;
|
||||
@@ -5644,8 +5643,8 @@ mod fileio {
|
||||
) -> PyResult<Option<usize>> {
|
||||
if !zelf.mode.load().contains(host_io::FileMode::READABLE) {
|
||||
return Err(new_unsupported_operation(
|
||||
"File or stream is not readable",
|
||||
vm,
|
||||
"File or stream is not readable".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -5679,8 +5678,8 @@ mod fileio {
|
||||
) -> PyResult<Option<usize>> {
|
||||
if !zelf.mode.load().contains(host_io::FileMode::WRITABLE) {
|
||||
return Err(new_unsupported_operation(
|
||||
"File or stream is not writable",
|
||||
vm,
|
||||
"File or stream is not writable".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -6219,8 +6218,8 @@ mod winconsoleio {
|
||||
let fd = self.get_fd(vm)?;
|
||||
if !self.readable.load() {
|
||||
return Err(new_unsupported_operation(
|
||||
"Console buffer does not support reading",
|
||||
vm,
|
||||
"Console buffer does not support reading".to_owned(),
|
||||
));
|
||||
}
|
||||
let mut buf_ref = buffer.borrow_buf_mut();
|
||||
@@ -6267,8 +6266,8 @@ mod winconsoleio {
|
||||
}
|
||||
if !self.readable.load() {
|
||||
return Err(new_unsupported_operation(
|
||||
"Console buffer does not support reading",
|
||||
vm,
|
||||
"Console buffer does not support reading".to_owned(),
|
||||
));
|
||||
}
|
||||
let size = size.unwrap_or(-1);
|
||||
@@ -6310,8 +6309,8 @@ mod winconsoleio {
|
||||
}
|
||||
if !self.writable.load() {
|
||||
return Err(new_unsupported_operation(
|
||||
"Console buffer does not support writing",
|
||||
vm,
|
||||
"Console buffer does not support writing".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -152,6 +152,7 @@ pub(crate) mod _thread {
|
||||
fn acquire(&self, args: AcquireArgs, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
acquire_lock_impl!(&self.mu, args, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
#[pymethod(name = "release_lock")]
|
||||
fn release(&self, vm: &VirtualMachine) -> PyResult<()> {
|
||||
@@ -240,6 +241,7 @@ pub(crate) mod _thread {
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
#[pymethod(name = "release_lock")]
|
||||
fn release(&self, vm: &VirtualMachine) -> PyResult<()> {
|
||||
@@ -413,34 +415,36 @@ pub(crate) mod _thread {
|
||||
|
||||
/// Get OS-level thread ID (pthread_self on Unix)
|
||||
/// This is important for fork compatibility - the ID must remain stable after fork
|
||||
#[cfg(unix)]
|
||||
fn current_thread_id() -> u64 {
|
||||
host_thread::current_thread_id()
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn current_thread_id() -> u64 {
|
||||
thread_to_rust_id(&thread::current())
|
||||
cfg_select! {
|
||||
unix => host_thread::current_thread_id(),
|
||||
_ => thread_to_rust_id(&thread::current()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert Rust thread to ID (used for non-unix platforms)
|
||||
#[cfg(not(unix))]
|
||||
fn thread_to_rust_id(t: &thread::Thread) -> u64 {
|
||||
use core::hash::{Hash, Hasher};
|
||||
|
||||
struct U64Hash {
|
||||
v: Option<u64>,
|
||||
}
|
||||
|
||||
impl Hasher for U64Hash {
|
||||
fn write(&mut self, _: &[u8]) {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn write_u64(&mut self, i: u64) {
|
||||
self.v = Some(i);
|
||||
}
|
||||
|
||||
fn finish(&self) -> u64 {
|
||||
self.v.expect("should have written a u64")
|
||||
}
|
||||
}
|
||||
|
||||
let mut h = U64Hash { v: None };
|
||||
t.id().hash(&mut h);
|
||||
h.finish()
|
||||
@@ -472,12 +476,14 @@ pub(crate) mod _thread {
|
||||
if !f_args.kwargs.is_empty() {
|
||||
return Err(vm.new_type_error("start_new_thread() takes no keyword arguments"));
|
||||
}
|
||||
|
||||
let given = f_args.args.len();
|
||||
if given < 2 {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"start_new_thread expected at least 2 arguments, got {given}"
|
||||
)));
|
||||
}
|
||||
|
||||
if given > 3 {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"start_new_thread expected at most 3 arguments, got {given}"
|
||||
@@ -491,9 +497,11 @@ pub(crate) mod _thread {
|
||||
if func_obj.to_callable().is_none() {
|
||||
return Err(vm.new_type_error("first arg must be callable"));
|
||||
}
|
||||
|
||||
if !args_obj.fast_isinstance(vm.ctx.types.tuple_type) {
|
||||
return Err(vm.new_type_error("2nd arg must be a tuple"));
|
||||
}
|
||||
|
||||
if kwargs_obj
|
||||
.as_ref()
|
||||
.is_some_and(|obj| !obj.fast_isinstance(vm.ctx.types.dict_type))
|
||||
@@ -1537,13 +1545,12 @@ pub(crate) mod _thread {
|
||||
})
|
||||
.min_by_key(|(distance, _)| *distance)
|
||||
.map(|(_, candidate)| candidate);
|
||||
let msg = if let Some(suggestion) = suggestion {
|
||||
format!(
|
||||
"start_joinable_thread() got an unexpected keyword argument '{unexpected}'. Did you mean '{suggestion}'?"
|
||||
)
|
||||
} else {
|
||||
format!("start_joinable_thread() got an unexpected keyword argument '{unexpected}'")
|
||||
};
|
||||
|
||||
let msg_suffix =
|
||||
suggestion.map_or_else(String::new, |s| format!(". Did you mean '{s}'?"));
|
||||
let msg = format!(
|
||||
"start_joinable_thread() got an unexpected keyword argument '{unexpected}'{msg_suffix}"
|
||||
);
|
||||
return Err(vm.new_type_error(msg));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,18 +17,22 @@ mod _weakref {
|
||||
fn ref_(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.weakref_type.to_owned()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn proxy(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.weakproxy_type.to_owned()
|
||||
}
|
||||
|
||||
#[pyattr(name = "ReferenceType")]
|
||||
fn reference_type(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.weakref_type.to_owned()
|
||||
}
|
||||
|
||||
#[pyattr(name = "ProxyType")]
|
||||
fn proxy_type(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.weakproxy_type.to_owned()
|
||||
}
|
||||
|
||||
#[pyattr(name = "CallableProxyType")]
|
||||
fn callable_proxy_type(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.weakproxy_type.to_owned()
|
||||
@@ -41,10 +45,8 @@ mod _weakref {
|
||||
|
||||
#[pyfunction]
|
||||
fn getweakrefs(obj: PyObjectRef) -> Vec<PyObjectRef> {
|
||||
match obj.get_weak_references() {
|
||||
Some(v) => v.into_iter().map(Into::into).collect(),
|
||||
None => vec![],
|
||||
}
|
||||
obj.get_weak_references()
|
||||
.map_or_else(Vec::new, |v| v.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
@@ -128,7 +128,7 @@ mod builtins {
|
||||
let hash_pos = line.iter().position(|&b| b == b'#')?;
|
||||
if !line[..hash_pos]
|
||||
.iter()
|
||||
.all(|&b| b == b' ' || b == b'\t' || b == b'\x0c' || b == b'\r')
|
||||
.all(|&b| matches!(b, b' ' | b'\t' | b'\x0c' | b'\r'))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
@@ -139,8 +139,7 @@ mod builtins {
|
||||
let after_coding = &after_hash[coding_pos + 6..];
|
||||
|
||||
// Next char must be ':' or '='
|
||||
let rest = if after_coding.first() == Some(&b':') || after_coding.first() == Some(&b'=')
|
||||
{
|
||||
let rest = if matches!(after_coding.first(), Some(b':' | b'=')) {
|
||||
&after_coding[1..]
|
||||
} else {
|
||||
return None;
|
||||
@@ -150,15 +149,15 @@ mod builtins {
|
||||
let rest = rest
|
||||
.iter()
|
||||
.copied()
|
||||
.skip_while(|&b| b == b' ' || b == b'\t')
|
||||
.skip_while(|&b| matches!(b, b' ' | b'\t'))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Read encoding name: [-\w.]+
|
||||
let name: String = rest
|
||||
let name = rest
|
||||
.iter()
|
||||
.take_while(|&&b| b.is_ascii_alphanumeric() || b == b'-' || b == b'_' || b == b'.')
|
||||
.take_while(|&&b| b.is_ascii_alphanumeric() || matches!(b, b'-' | b'_' | b'.'))
|
||||
.map(|&b| b as char)
|
||||
.collect();
|
||||
.collect::<String>();
|
||||
|
||||
if name.is_empty() {
|
||||
None
|
||||
@@ -179,10 +178,10 @@ mod builtins {
|
||||
// Only check second line if first line is blank or a comment
|
||||
let trimmed = first
|
||||
.iter()
|
||||
.skip_while(|&&b| b == b' ' || b == b'\t' || b == b'\x0c' || b == b'\r')
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
if !trimmed.is_empty() && trimmed[0] != b'#' {
|
||||
.find(|&&b| !matches!(b, b' ' | b'\t' | b'\x0c' | b'\r'))
|
||||
.copied();
|
||||
|
||||
if trimmed.is_some_and(|b| b != b'#') {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@@ -350,7 +349,7 @@ mod builtins {
|
||||
|
||||
#[cfg(not(feature = "rustpython-codegen"))]
|
||||
{
|
||||
return Err(vm.new_type_error(CODEGEN_NOT_SUPPORTED.to_owned()));
|
||||
return Err(vm.new_type_error(CODEGEN_NOT_SUPPORTED));
|
||||
}
|
||||
#[cfg(feature = "rustpython-codegen")]
|
||||
{
|
||||
@@ -368,10 +367,10 @@ mod builtins {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "parser"))]
|
||||
{
|
||||
const PARSER_NOT_SUPPORTED: &str = "can't compile() source code when the `parser` feature of rustpython is disabled";
|
||||
Err(vm.new_type_error(PARSER_NOT_SUPPORTED.to_owned()))
|
||||
}
|
||||
return Err(vm.new_type_error(
|
||||
"can't compile() source code when the `parser` feature of rustpython is disabled",
|
||||
));
|
||||
|
||||
#[cfg(feature = "parser")]
|
||||
{
|
||||
use crate::convert::ToPyException;
|
||||
@@ -398,7 +397,7 @@ mod builtins {
|
||||
if (flags & _ast::PY_CF_ONLY_AST).is_zero() {
|
||||
#[cfg(not(feature = "compiler"))]
|
||||
{
|
||||
Err(vm.new_value_error(CODEGEN_NOT_SUPPORTED.to_owned()))
|
||||
Err(vm.new_value_error(CODEGEN_NOT_SUPPORTED))
|
||||
}
|
||||
#[cfg(feature = "compiler")]
|
||||
{
|
||||
@@ -470,23 +469,22 @@ mod builtins {
|
||||
feature_version: OptionalArg<i32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<Option<ruff_python_ast::PythonVersion>> {
|
||||
let minor = match feature_version.into_option() {
|
||||
Some(minor) => minor,
|
||||
None => return Ok(None),
|
||||
let Some(minor) = feature_version.into_option() else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
if minor < 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let minor = u8::try_from(minor)
|
||||
.map_err(|_| vm.new_value_error("compile() _feature_version out of range"))?;
|
||||
Ok(Some(ruff_python_ast::PythonVersion { major: 3, minor }))
|
||||
u8::try_from(minor)
|
||||
.map(|v| Some(ruff_python_ast::PythonVersion { major: 3, minor: v }))
|
||||
.map_err(|_| vm.new_value_error("compile() _feature_version out of range"))
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn delattr(obj: PyObjectRef, attr: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let attr = attr.try_to_ref::<PyStr>(vm).map_err(|_e| {
|
||||
let attr = attr.try_to_ref::<PyStr>(vm).map_err(|_| {
|
||||
vm.new_type_error(format!(
|
||||
"attribute name must be string, not '{}'",
|
||||
attr.class().name()
|
||||
@@ -514,40 +512,42 @@ mod builtins {
|
||||
}
|
||||
|
||||
impl ScopeArgs {
|
||||
fn validate_globals_dict(
|
||||
globals: &PyObject,
|
||||
vm: &VirtualMachine,
|
||||
func_name: &'static str,
|
||||
) -> PyResult<()> {
|
||||
if globals.fast_isinstance(vm.ctx.types.dict_type) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let msg = match func_name {
|
||||
"eval" => {
|
||||
let is_mapping = globals.mapping_unchecked().check();
|
||||
if is_mapping {
|
||||
"globals must be a real dict; try eval(expr, {}, mapping)".into()
|
||||
} else {
|
||||
"globals must be a dict".into()
|
||||
}
|
||||
}
|
||||
"exec" => format!(
|
||||
"exec() globals must be a dict, not {}",
|
||||
globals.class().name()
|
||||
),
|
||||
_ => "globals must be a dict".into(),
|
||||
};
|
||||
|
||||
Err(vm.new_type_error(msg))
|
||||
}
|
||||
|
||||
fn make_scope(
|
||||
self,
|
||||
vm: &VirtualMachine,
|
||||
func_name: &'static str,
|
||||
) -> PyResult<crate::scope::Scope> {
|
||||
fn validate_globals_dict(
|
||||
globals: &PyObject,
|
||||
vm: &VirtualMachine,
|
||||
func_name: &'static str,
|
||||
) -> PyResult<()> {
|
||||
if !globals.fast_isinstance(vm.ctx.types.dict_type) {
|
||||
return Err(match func_name {
|
||||
"eval" => {
|
||||
let is_mapping = globals.mapping_unchecked().check();
|
||||
vm.new_type_error(if is_mapping {
|
||||
"globals must be a real dict; try eval(expr, {}, mapping)"
|
||||
.to_owned()
|
||||
} else {
|
||||
"globals must be a dict".to_owned()
|
||||
})
|
||||
}
|
||||
"exec" => vm.new_type_error(format!(
|
||||
"exec() globals must be a dict, not {}",
|
||||
globals.class().name()
|
||||
)),
|
||||
_ => vm.new_type_error("globals must be a dict"),
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let (globals, locals) = match self.globals {
|
||||
Some(globals) => {
|
||||
validate_globals_dict(&globals, vm, func_name)?;
|
||||
Self::validate_globals_dict(&globals, vm, func_name)?;
|
||||
|
||||
let globals = PyDictRef::try_from_object(vm, globals)?;
|
||||
if !globals.contains_key(identifier!(vm, __builtins__), vm) {
|
||||
@@ -636,7 +636,7 @@ mod builtins {
|
||||
.map_err(|err| vm.new_syntax_error(&err, Some(source)))?
|
||||
}
|
||||
#[cfg(not(feature = "rustpython-compiler"))]
|
||||
Either::A(_) => return Err(vm.new_type_error(CODEGEN_NOT_SUPPORTED.to_owned())),
|
||||
Either::A(_) => return Err(vm.new_type_error(CODEGEN_NOT_SUPPORTED)),
|
||||
Either::B(code_obj) => code_obj,
|
||||
};
|
||||
|
||||
|
||||
@@ -109,12 +109,11 @@ mod decl {
|
||||
}
|
||||
}
|
||||
};
|
||||
match next {
|
||||
Err(_) | Ok(PyIterReturn::StopIteration(_)) => {
|
||||
*zelf.source.write() = None;
|
||||
}
|
||||
_ => {}
|
||||
|
||||
if matches!(next, Err(_) | Ok(PyIterReturn::StopIteration(_))) {
|
||||
*zelf.source.write() = None;
|
||||
};
|
||||
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,6 @@ pub(crate) mod typevar {
|
||||
#[pyattr]
|
||||
#[pyclass(name = "TypeVar", module = "typing")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
#[allow(dead_code)]
|
||||
pub struct TypeVar {
|
||||
name: PyObjectRef, // TODO PyStrRef?
|
||||
bound: PyMutex<PyObjectRef>,
|
||||
@@ -94,6 +93,7 @@ pub(crate) mod typevar {
|
||||
contravariant: bool,
|
||||
infer_variance: bool,
|
||||
}
|
||||
|
||||
#[pyclass(
|
||||
flags(HAS_DICT, HAS_WEAKREF),
|
||||
with(AsNumber, Constructor, Representable)
|
||||
@@ -267,7 +267,7 @@ pub(crate) mod typevar {
|
||||
// Check if we have enough arguments
|
||||
if args_tuple.len() <= index && zelf.has_default(vm) {
|
||||
// Need to add default value
|
||||
let mut new_args: Vec<PyObjectRef> = args_tuple.iter().cloned().collect();
|
||||
let mut new_args = args_tuple.iter().cloned().collect::<Vec<PyObjectRef>>();
|
||||
|
||||
// Add default value at the correct position
|
||||
while new_args.len() <= index {
|
||||
@@ -367,7 +367,7 @@ pub(crate) mod typevar {
|
||||
|
||||
// Check for unexpected keyword arguments
|
||||
if !kwargs.is_empty() {
|
||||
let unexpected_keys: Vec<String> = kwargs.keys().map(|s| s.to_string()).collect();
|
||||
let unexpected_keys = kwargs.keys().map(|s| s.to_string()).collect::<Vec<_>>();
|
||||
return Err(vm.new_type_error(format!(
|
||||
"TypeVar() got unexpected keyword argument(s): {}",
|
||||
unexpected_keys.join(", ")
|
||||
@@ -459,7 +459,6 @@ pub(crate) mod typevar {
|
||||
#[pyattr]
|
||||
#[pyclass(name = "ParamSpec", module = "typing")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
#[allow(dead_code)]
|
||||
pub struct ParamSpec {
|
||||
name: PyObjectRef,
|
||||
bound: Option<PyObjectRef>,
|
||||
@@ -651,7 +650,7 @@ pub(crate) mod typevar {
|
||||
|
||||
// Check for unexpected keyword arguments
|
||||
if !kwargs.is_empty() {
|
||||
let unexpected_keys: Vec<String> = kwargs.keys().map(|s| s.to_string()).collect();
|
||||
let unexpected_keys = kwargs.keys().map(|s| s.to_string()).collect::<Vec<_>>();
|
||||
return Err(vm.new_type_error(format!(
|
||||
"ParamSpec() got unexpected keyword argument(s): {}",
|
||||
unexpected_keys.join(", ")
|
||||
@@ -721,12 +720,12 @@ pub(crate) mod typevar {
|
||||
#[pyattr]
|
||||
#[pyclass(name = "TypeVarTuple", module = "typing")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
#[allow(dead_code)]
|
||||
pub struct TypeVarTuple {
|
||||
name: PyObjectRef,
|
||||
default_value: PyMutex<PyObjectRef>,
|
||||
evaluate_default: PyMutex<PyObjectRef>,
|
||||
}
|
||||
|
||||
#[pyclass(
|
||||
flags(HAS_DICT, HAS_WEAKREF),
|
||||
with(Constructor, Representable, Iterable)
|
||||
@@ -845,7 +844,7 @@ pub(crate) mod typevar {
|
||||
|
||||
// Check for unexpected keyword arguments
|
||||
if !kwargs.is_empty() {
|
||||
let unexpected_keys: Vec<String> = kwargs.keys().map(|s| s.to_string()).collect();
|
||||
let unexpected_keys = kwargs.keys().map(|s| s.to_string()).collect::<Vec<_>>();
|
||||
return Err(vm.new_type_error(format!(
|
||||
"TypeVarTuple() got unexpected keyword argument(s): {}",
|
||||
unexpected_keys.join(", ")
|
||||
@@ -898,10 +897,10 @@ pub(crate) mod typevar {
|
||||
#[pyattr]
|
||||
#[pyclass(name = "ParamSpecArgs", module = "typing")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
#[allow(dead_code)]
|
||||
pub struct ParamSpecArgs {
|
||||
__origin__: PyObjectRef,
|
||||
}
|
||||
|
||||
#[pyclass(with(Constructor, Representable, Comparable), flags(HAS_WEAKREF))]
|
||||
impl ParamSpecArgs {
|
||||
#[pymethod]
|
||||
@@ -961,10 +960,10 @@ pub(crate) mod typevar {
|
||||
#[pyattr]
|
||||
#[pyclass(name = "ParamSpecKwargs", module = "typing")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
#[allow(dead_code)]
|
||||
pub struct ParamSpecKwargs {
|
||||
__origin__: PyObjectRef,
|
||||
}
|
||||
|
||||
#[pyclass(with(Constructor, Representable, Comparable), flags(HAS_WEAKREF))]
|
||||
impl ParamSpecKwargs {
|
||||
#[pymethod]
|
||||
@@ -1048,7 +1047,6 @@ pub(crate) mod typevar {
|
||||
#[pyattr]
|
||||
#[pyclass(name = "Generic", module = "typing")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Generic;
|
||||
|
||||
#[pyclass(flags(BASETYPE, HEAPTYPE))]
|
||||
|
||||
Reference in new issue
Block a user