General code nits (#8041)

This commit is contained in:
Shahar Naveh authored and GitHub committed 2026-06-10 11:00:58 +09:00
1 parent 4143af54f7
commit fb9a5ca65b
11 files changed
+141 -134

No files matched your search

+11 -18
View File
@@ -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())
}
+4 -5
View File
@@ -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",
+3
View File
@@ -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(
+1 -1
View File
@@ -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
}
+8 -1
View File
@@ -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
View File
@@ -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(),
));
}
+21 -14
View File
@@ -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));
}
+6 -4
View File
@@ -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]
+52 -52
View File
@@ -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,
};
+4 -5
View File
@@ -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
}
}
+8 -10
View File
@@ -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))]